Какую стратегию DAL Вы используете или предлагаете?

В дополнение к превосходному сообщению @TofuBeer TofuBeer рассмотрим ответ @pdox pdox:

static boolean five(final boolean a, final boolean b, final boolean c)
{
    return a == b ? a : c;
}

Рассмотрим также его разобранную версию, представленную «javap -c»:

static boolean five(boolean, boolean, boolean);
  Code:
    0:    iload_0
    1:    iload_1
    2:    if_icmpne    9
    5:    iload_0
    6:    goto    10
    9:    iload_2
   10:    ireturn

Ответ pdox компилируется в меньший байт-код, чем любой из предыдущих ответов. Как его время выполнения сравнивается с другими?

one                5242 ms
two                6318 ms
three (moonshadow) 3806 ms
four               7192 ms
five  (pdox)       3650 ms

По крайней мере, на моем компьютере ответ pdox немного быстрее, чем ответ @moonshadow moonshadow, что делает pdox самым быстрым в целом (на моем ноутбуке HP / Intel) .

7
задан 2 revs 14 July 2009 в 14:08
поделиться

7 ответов

Мой опыт работы с NHibernate показывает, что, несмотря на то, что он обладает множеством функций и обладает очень высокой производительностью, вам в конечном итоге потребуется стать экспертом по NHibernate, чтобы исправить некоторые неожиданные ошибки. Прочитав ответы про-NHibernate и увидев

Хмм, возможно, он использует длительный бег Сеансы (сеансов на бизнес Модель транзакции), и в таком подход, использование идентичности обескуражен, так как это нарушает ваш unitofwork (нужно промывать напрямую после вставки нового объекта). А решением могло бы быть отбросить идентичность и использовать идентичность HiLo generator.

illustrates exactly what I mean.

What I've done is create a base class modeled somewhat off of the ActiveRecord pattern, that I inherit from and mark up the inherited class with attributes that attach it to a stored procedure each for Select, Insert, Update and Delete. The base class uses Reflection to read the attributes and assign the class's property values to SP parameters, and in the case of Select(), assign the result SQLDataReader's column values to the properties of a list of generics.

This is what DataObjectBase looks like:

interface IDataObjectBase<T>
    {
        void Delete();
        void Insert();
        System.Collections.Generic.List<T> Select();
        void Update();
    }

This is an example of a data class deriving from it:

[StoredProcedure("usp_refund_CustRefundDetailInsert", OperationType.Insert)]
    [StoredProcedure("usp_refund_CustRefundDetailSelect", OperationType.Select)]
    [StoredProcedure("usp_refund_CustRefundDetailUpdate", OperationType.Update)]
    public class RefundDetail : DataObjectBase<RefundDetail>
    {

        [StoredProcedureParameter(null, OperationType.Update, ParameterDirection.Input)]
        [StoredProcedureParameter(null, OperationType.Insert, ParameterDirection.Output)]
        [StoredProcedureParameter(null, OperationType.Select, ParameterDirection.Input)]
        [ResultColumn(null)]
        public int? RefundDetailId
        { get; set; }

        [StoredProcedureParameter(null, OperationType.Update, ParameterDirection.Input)]
        [StoredProcedureParameter(null, OperationType.Insert, ParameterDirection.Input)]
        [StoredProcedureParameter(null, OperationType.Select, ParameterDirection.Input)]
        [ResultColumn(null)]
        public int? RefundId
        { get; set; }
        [StoredProcedureParameter(null, OperationType.Update, ParameterDirection.Input)]
        [StoredProcedureParameter(null, OperationType.Insert, ParameterDirection.Input)]
        [ResultColumn(null)]
        public int RefundTypeId
        { get; set; }

        [StoredProcedureParameter(null, OperationType.Update, ParameterDirection.Input)]
        [StoredProcedureParameter(null, OperationType.Insert, ParameterDirection.Input)]
        [ResultColumn(null)]
        public decimal? RefundAmount
        { get; set; }        
        [StoredProcedureParameter(null, OperationType.Update, ParameterDirection.Input)]
        [StoredProcedureParameter(null, OperationType.Insert, ParameterDirection.Input)]
        [ResultColumn(null)]
        public string ARTranId
        { get; set; }

    }

I know it seems like I'm reinventing the wheel, but all of the libraries I found either had too much dependence on other libraries (ActiveRecord + NHibernate, for instance, which was a close second) or were too complicated to use and administer.

The library I made is very lightweight (maybe a couple of hundred lines of C#) and doesn't do anything more than assign values to parameters and execute the SP. It also lends itself very well to code generation, so eventually I expect to write no data access code. I also like that it uses a class instance instead of a static class, so that I can pass data to queries without some awkward criteria collection or HQL. Select() means "get more like me".

1
ответ дан 7 December 2019 в 18:45
поделиться

Для меня лучше всего подошла довольно простая концепция - использовать определения классов DAO и с отражением создать весь SQL, необходимый для их заполнения и сохранения. Таким образом, нет файла отображения, только простые классы. Моим DAO требуется базовый класс Entity, поэтому это не POCO, но меня это не беспокоит. Он поддерживает любой тип первичного ключа, будь то один столбец идентификаторов или несколько столбцов.

1
ответ дан 7 December 2019 в 18:45
поделиться

Моим первым шагом было бы взломать код монстра 15 KLOC, а затем разработать стратегию создания нового DAL.

0
ответ дан 7 December 2019 в 18:45
поделиться

Чтобы проверять наличие обновлений только ежечасно (для пример) используйте это в своем файле VCALENDAR:

X-PUBLISHED-TTL:PT1H

Я почерпнул эту информацию из одного из документов протокола Microsoft было бы намного проще переключиться на NHibernate или что-то совместимое (я бы предпочел Fluent-NHibernate, но я отвлекся). Так почему бы вместо этого не потратить время на рефакторинг DAL для использования интерфейса, а затем написать новую реализацию с использованием NH или вашего ORM по выбору?

0
ответ дан 7 December 2019 в 18:45
поделиться

Linq to SQL is nice if you are using SQL Server. There is source out there for a LinqToSQL provider to Access and MySQL. I haven't tested it though. LinqToSql follows the UnitOfWork model which is similar to the way ADO.NET functions. You make a series of changes to a local copy of the data then commit all the changes with one update call. It's pretty clean I think.

You can also extend the DataRow class yourself to provide strongly typed access to your fields. I used XSLT to generate the DataRow descendants based on the metadata of each table. I have a generic DataTable decendant. MyDataTable where T is my derived row. I know that MS's strongly-typed datasets do a similar thing but I wanted a light-weight generic version that I complete control of. Once you have this, you can write static access methods that query the db and fill the DataTable.

You would be in charge of writing the changes from the DataTable back to the DataSource. I would write a generic class or method that creates the update,inserts and deletes.

Good Luck!

0
ответ дан 7 December 2019 в 18:45
поделиться

В последних проектах мы прекратили программирование отдельного DAL.

Вместо этого мы используем объектно-реляционный сопоставитель (в нашем случае Entity Framework). Затем мы позволяем программе бизнес-уровня напрямую взаимодействовать с ORM.

В некоторых случаях это сэкономило нам более 90% усилий по разработке.

0
ответ дан 7 December 2019 в 18:45
поделиться

Я использую свою оболочку для SP для максимально быстрого извлечения данных и L2S, когда производительность не является целью. Мой DAL использует шаблон репозитория и инкапсулированную логику для TDD.

0
ответ дан 7 December 2019 в 18:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: