由於公司的項目是基本JPA作的數據處理,想總結實際項目中一些基本的用法。 java
1.由於項目基於maven,因此在resources目錄下須存放JPA基本的配置文件META-INF/persistence.xml,測試時通常使用derby,爲了更清楚的瞭解JPA執行的動做,show_sql,format_sql,hbm2ddl.auto三個屬性都須要設置。hbm2ddl.auto 不要設置成create-drop ,由於測試經過後,咱們能夠直接打開數據表,觀察 java bean 在 數據庫中對應的表結構。 sql
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> <persistence-unit name="NewPersistenceUnit"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <class>org.pan.domain.Account</class> <class>org.pan.domain.AccountHeaderImage</class> <properties> <property name="hibernate.connection.url" value="jdbc:derby:test;create=true"/> <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver"/> <property name="hibernate.connection.username" value=""/> <property name="hibernate.connection.password" value=""/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/> <property name="hibernate.hbm2ddl.auto" value="create"/> </properties> </persistence-unit> </persistence>
2. 實體類:一個帳戶(Account)會擁有一個頭像(AccountHeaderImage),他們是一對一對關係。一般咱們會創建一個雙向的一對一來表現這樣方式,即在雙邊都添加@oneToOne 註解,但有一點必定要清楚,無論是加載任何一方的數據,另外一方都會被加載出來,致使列表的查詢變爲1+n的查詢。(有一個比較牽強的理由:由於帳戶與頭像自己是一個整理,只是在數據上進行分開存儲,但在面向對象的層面他們仍是總體)。 數據庫
因此在項目中我會盡可能的減小@oneToOne的雙向關聯,而改爲單向。即帳戶包含圖片,頭像作爲帳戶的外鍵。具體的標註以下: apache
@Entity public class Account extends AbstractDomain { @Column private String username; @Column private String password; @OneToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL) private AccountHeaderImage accountHeaderImage; //getter and setter }
@Entity public class AccountHeaderImage extends AbstractDomain{ @Lob private byte[] headerImage; //getter and setter }
若是 Account 中fetchType使用Lazy 的話,則默認加載Account時不會加載AccountHeaderImage,需調用getAccountHeaderImage()纔會加載。以下以id的方式加載Account時,產生的sql語句以下: dom
select account0_.id as id1_0_0_, account0_.accountHeaderImage_id as accountH4_0_0_, account0_.password as password2_0_0_,account0_.username as username3_0_0_ from Account account0_ where account0_.id=?若是調用account.getAccountHeaderImage().getId(),則會多出一條sql,代表只有在須要用時才作加載:
select accounthea0_.id as id1_1_0_,accounthea0_.headerImage as headerIm2_1_0_ from AccountHeaderImage accounthea0_ where accounthea0_.id=?但咱們通常作加載時這樣作:
Hibernate.initialize(account.getAccountHeaderImage());若是咱們在Account 中 fetchType 使用EAGER的話,則經過id加載Account 會產生以下sql :
select account0_.id as id1_0_0_, account0_.accountHeaderImage_id as accountH4_0_0_, account0_.password as password2_0_0_, account0_.username as username3_0_0_, accounthea1_.id as id1_1_1_, accounthea1_.headerImage as headerIm2_1_1_ from Account account0_ left outer join AccountHeaderImage accounthea1_ on account0_.accountHeaderImage_id=accounthea1_.id where account0_.id=?