2015-09-11 2 views
0

Я использовал Hibernate/JPA в прошлом, теперь используя комбинацию Spring JDBC и MyBatis.JDBC Domain Design and Relationships

С JPA/Hibernate, если у вас был клиент, у которого был адрес, у вас будет доменная структура, похожая на код ниже. (минус все аннотации/конфиг/сопоставления).

Это все еще имеет смысл при использовании JDBC или MyBatis. Это составной дизайн домена из того, что я знаю, имеет-a, принадлежит и т. Д. Однако большинство примеров, которые я видел в коде JDBC, у них есть объект домена, который возвращает идентификаторы, а не сбор, или сглаживает данные. Существуют ли какие-либо преимущества в производительности от подхода, ремонтопригодности и т. Д. Сначала я работал с JPA, я не уверен, что такое JDBC.

public class Customer { 

    private Long id; 
    private String userName; 
    private String password; 
    private String firstName; 
    private String lastName; 
    private Collection<Address> addresses 
    ... 
} 

public class Address { 
    private Long id; 
    private String streetAddress1; 
    private String streetAddress2; 
    private String city; 
    private State state; 
    private String postalCode; 
} 

public class State { 
    private Long id; 
    private String code; 
    private String name; 
    private Country country; 
} 

public class Country { 
    private Long id; 
    private String code; 
    private String name; 
} 

Я столкнулся с примером и здесь был один из их классов.

public class Question { 
    private long questionId; 
    private long categoryId; 
    private long userId; 
    private long areaId; 
    private String question; 
    private String verifyKey; 
    private Date created; 
    private User user; 
    private List<Answer> answers; 
    private long answerCount; 
    private String name; 
    // getters and setters omited... 
} 

Почему вы запрашиваете идент, Areaid и CategoryId вместо фактического извлечения связанного объекта? Идентификатор, вероятно, бесполезен для конечного пользователя, я полагаю, вы могли бы использовать ID для выдачи другого запроса для получения дополнительных данных, но, похоже, неэффективны, делая еще одно путешествие в базу данных.

ответ

0

Вы можете посмотреть этот объект домена как «след» таблицы базы данных. В вашем примере userId, areaId и categoryId от Question, скорее всего, являются внешними ключами из соответствующих таблиц. Вам никогда не понадобится полные данные объекта в момент создания Вопроса и позже получить его с помощью отдельного запроса db. Если вы сразу выберете все связанные объекты, вы нажмете хотя бы одну дополнительную таблицу на объект (по команде join-s или subselect-s). Более того, это то же самое, что и Hibernate. По умолчанию он загружает объект домена лениво и снова удаляет базу данных, если требуется неинициализированный связанный объект.

В это время лучше получить те объекты, которые объект домена не может существовать без него. В вашем примере связаны вопросы и список.

Конечно, если вам нужен пользователь или категория или любой другой связанный объект в другом месте приложения (предположим, что ссылка на ранее извлеченный объект была утеряна), вы попадете в базу данных с тем же запросом. Это должно быть сделано и может показаться неэффективным, поскольку как простые JDBC, так и SpringJDBC не имеют промежуточного кэширования, в отличие от Hibernate. Но для этого не предназначен JDBC.

+0

Что вы подразумеваете под «Вы можете посмотреть этот объект домена как« след »таблицы базы данных»? Если я правильно понимаю вас, домен не будет иметь 1 к 1 с базой данных, но должен быть схожим. В качестве примера объекта Address это действительно не имеет смысла для него существовать без состояния, поэтому вместо stateId он должен ссылаться на объект State? – greyfox

+0

Извините, я не имел в виду объект объекта Domain, но класс 'Question' в первом выражении. Что касается адреса и состояния, что зависит от их типичного использования в вашем приложении. Объект State используется через объект Address в большинстве случаев? Если нет, то зачем его инициализировать? Конечно, вы можете настаивать на поле _State_ вместо _stateId_ и оставить его как «null». Но лично я бы этого не сделал. Это смущает разработчиков, которые ожидают, что объект состояния будет инициализирован, а также потребует нулевые проверки по всему коду. – Grade

+0

Что касается проблемы n + 1, скажем, мне нужно вернуть 100 адресов в пользовательский интерфейс, и ему нужно отобразить имя состояния, а не идентификатор, теперь вы запускаете один запрос для получения всех строк адреса и выдаете другой запрос за каждый строка, чтобы получить состояние в общей сложности 101 запрос, является ли это приемлемым для JDBC?Чем больше подкатегорий у вас есть, тем хуже получается – greyfox