小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

用hibernate插入數(shù)據(jù)時(shí)怎么讓默認(rèn)值生效,以及HIbernate注解詳解

 宇宙之窗 2014-01-15

數(shù)據(jù)庫中一個(gè)字段的默認(rèn)值設(shè)為0,當(dāng)用hibernate插入數(shù)據(jù)時(shí),沒有對該字段進(jìn)行操作,結(jié)果該字段居然不是0,而是空。后來google了一下,發(fā)現(xiàn)應(yīng)該在.hbm.xml文件中添加一些參數(shù)定義(示例中的紅色部分),具體如下:

<hibernate-mapping>
    <class name="com.tom.hibernate.EbayItem" table="EBAY_ITEM" schema="API_USER" dynamic-insert="true" dynamic-update="true">
.......
........
</class>
</hibernate-mapping>

在我們熟悉的Hibernate映射文件中也大有乾坤,很多值得我注意的地方。
在Hibernate的映射文件的class tag使用dynamic-insert,dynamic-update,可以優(yōu)化生成的SQL語句,提高SQL執(zhí)行效率,最終可以提高系統(tǒng)性能。
如,有一個(gè)User類。

public class User {
    
    /** Creates a new instance of User */
    public User() {
    }
    private long id;
    private int age;

    private String firstname;
    private String lastname;
    private Set emailAddresses;
//省略getter 和setter方法
}

Hibernate映射文件(User.hbm.xml,省略了文件頭聲明)定義為:
<hibernate-mapping>
    <class name="model.User" table="Users"  >
        <id name="id" column="ID">
            <generator class="native"/>
        </id>
        <property name="age"/>
        <property name="firstname"/>
        <property name="lastname"/>
        
        <set name="emailAddresses" table="PERSON_EMAIL_ADDR">
            <key column="PERSON_ID"/>
            <element type="string" column="EMAIL_ADDR"/>
        </set>
    </class>
</hibernate-mapping>
我們寫一個(gè)測試類進(jìn)行測試UserTest。


public class UserTest extends TestCase {
    
    public UserTest(String testName) {
        super(testName);
    }
    
    private Session session;
    private SessionFactory sessionFactory;
    
    protected void setUp() throws Exception {
        sessionFactory=HibernateUtil.getSessionFactory();
        session=sessionFactory.openSession();
        session.getTransaction().begin();
    }
    
    protected void tearDown() throws Exception {
        session.getTransaction().commit();
        session.close();
        
    }
    
    /**
     * Test of getAge method, of class model.User.
     */
    public void testSaveUser() {
        System.out.println("================testSaveUser=================");
        
        User user = new User();
        user.setAge(29);
        session.save(user);
        assertNotNull("id is assigned !",user.getId());
    }
    public void testUpdateUser() {
        System.out.println("================testUpdateUser=================");
        
        User user = new User();
        user.setAge(29);
        session.save(user);
        assertNotNull("id is assigned !",user.getId());
        
        User _user=(User) session.get(User.class, user.getId());
        _user.setFirstname("Array");
        session.update(_user);
        
    }
    
    
}
運(yùn)行測試后,此時(shí)會生成完整的SQL語句(注意將hibernate屬性show_sql設(shè)置成true)。

================testSaveUser=================
Hibernate: insert into Users (age, firstname, lastname) values (?, ?, ?)
================testUpdateUser=================
Hibernate: insert into Users (age, firstname, lastname) values (?, ?, ?)
Hibernate: update Users set age=?, firstname=?, lastname=? where ID=?

如果我們在<class ...>中加上 dynamic-insert="true" dynamic-update="true",變成如下。

<class name="model.User" table="Users"  dynamic-insert="true" dynamic-update="true">

再次運(yùn)行測試類,就會發(fā)現(xiàn)生成的SQL中涉及的字段只包含User類中修改的屬性所對應(yīng)的表字段。

================testSaveUser=================
Hibernate: insert into Users (age) values (?)
================testUpdateUser=================
Hibernate: insert into Users (age) values (?)
Hibernate: update Users set firstname=? where ID=?

如果一個(gè)表的結(jié)構(gòu)很復(fù)雜,字段很多的情況下,使用dynamic-insert,dynamic-update能夠性能上的少許提升。

下面是有關(guān)其它配置的說明

Hibernate允許我們在映射文件里控制insert和update語句的內(nèi)容.比如在映射文件中<property 元素中的update屬性設(shè)置成為false,那么這個(gè)字段,將不被包括在基本的update語句中,修改的時(shí)候,將不包括這個(gè)字段了.insert同理.dynamic動態(tài)SQL語句的配置也是很常用的.下面介紹配置SQL語句的具體屬性:
      1)<property>元素 insert屬性:設(shè)置為false,在insert語句中不包含這個(gè)字段,表示永遠(yuǎn)不會被插入,默認(rèn)true
      2)<property>元素 update屬性:設(shè)置為false,在update語句中不包含這個(gè)字段,表示永遠(yuǎn)不會被修改,默認(rèn)true
      3)<class>元素 mutable屬性:設(shè)置為false就是把所有的<property>元素的update屬性設(shè)置為了false,說明這個(gè)對象不會被更新,默認(rèn)true
      4)<property>元素 dynamic-insert屬性:設(shè)置為true,表示insert對象的時(shí)候,生成動態(tài)的insert語句,如果這個(gè)字段的值是null就不會加入到insert語句當(dāng)中.默認(rèn)false
      5)<property>元素 dynamic-update屬性,設(shè)置為true,表示update對象的時(shí)候,生成動態(tài)的update語句,如果這個(gè)字段的值是null就不會被加入到update語句中,默認(rèn)false
      6)<class>元素 dynamic-insert屬性:設(shè)置為true,表示把所有的<property>元素的dynamic-insert屬性設(shè)置為true,默認(rèn)false
      7)<class>元素 dynamic-update屬性:設(shè)置為true,表示把所有的<property>元素的dynamic-update屬性設(shè)置為true,默認(rèn)false

      Hibernate生成動態(tài)SQL語句的消耗的系統(tǒng)資源(比如CPU,內(nèi)存等)是很小的,所以不會影響到系統(tǒng)的性能,如果表中包含N多字段,建議把dynamic-update屬性和insert屬性設(shè)置為true,這樣在插入和修改數(shù)據(jù)的時(shí)候,語句中只包括要插入或者修改的字段.可以節(jié)省SQL語句的執(zhí)行時(shí)間,提高程序的運(yùn)行效率.


hibernate 常用注解說明。

@content ejb3注解的API定義在javax.persistence.*包里面。   
   
注釋說明:   
@Entity —— 將一個(gè)類聲明為一個(gè)實(shí)體bean(即一個(gè)持久化POJO類)   
@Id —— 注解聲明了該實(shí)體bean的標(biāo)識屬性(對應(yīng)表中的主鍵)。   
@Table —— 注解聲明了該實(shí)體bean映射指定的表(table),目錄(catalog)和schema的名字   
@Column —— 注解聲明了屬性到列的映射。該注解有如下的屬性   
name 可選,列名(默認(rèn)值是屬性名)   
unique 可選,是否在該列上設(shè)置唯一約束(默認(rèn)值false)   
nullable 可選,是否設(shè)置該列的值可以為空(默認(rèn)值false)   
insertable 可選,該列是否作為生成的insert語句中的一個(gè)列(默認(rèn)值true)   
updatable 可選,該列是否作為生成的update語句中的一個(gè)列(默認(rèn)值true)   
columnDefinition 可選,為這個(gè)特定列覆蓋sql ddl片段(這可能導(dǎo)致無法在不同數(shù)據(jù)庫間移植)   
table 可選,定義對應(yīng)的表(默認(rèn)為主表)   
length 可選,列長度(默認(rèn)值255)   
precision 可選,列十進(jìn)制精度(decimal precision)(默認(rèn)值0)   
scale 可選,如果列十進(jìn)制數(shù)值范圍(decimal scale)可用,在此設(shè)置(默認(rèn)值0)   
@GeneratedValue —— 注解聲明了主鍵的生成策略。該注解有如下屬性   
strategy 指定生成的策略(JPA定義的),這是一個(gè)GenerationType。默認(rèn)是GenerationType. AUTO   
   GenerationType.AUTO 主鍵由程序控制   
GenerationType.TABLE 使用一個(gè)特定的數(shù)據(jù)庫表格來保存主鍵   
GenerationType.IDENTITY 主鍵由數(shù)據(jù)庫自動生成(主要是自動增長類型)   
GenerationType.SEQUENCE 根據(jù)底層數(shù)據(jù)庫的序列來生成主鍵,條件是數(shù)據(jù)庫支持序列。(這個(gè)值要與generator一起使用)   
generator 指定生成主鍵使用的生成器(可能是orcale中的序列)。   
@SequenceGenerator —— 注解聲明了一個(gè)數(shù)據(jù)庫序列。該注解有如下屬性   
name 表示該表主鍵生成策略名稱,它被引用在@GeneratedValue中設(shè)置的“gernerator”值中   
sequenceName 表示生成策略用到的數(shù)據(jù)庫序列名稱。   
initialValue 表示主鍵初始值,默認(rèn)為0.   
allocationSize 每次主鍵值增加的大小,例如設(shè)置成1,則表示每次創(chuàng)建新記錄后自動加1,默認(rèn)為50.   
@GenericGenerator —— 注解聲明了一個(gè)hibernate的主鍵生成策略。支持十三種策略。該注解有如下屬性  
name 指定生成器名稱   
strategy 指定具體生成器的類名(指定生成策略)。   
parameters 得到strategy指定的具體生成器所用到的參數(shù)。   
   其十三種策略(strategy屬性的值)如下:   
   1.native 對于orcale采用Sequence方式,對于MySQL和SQL Server采用identity(處境主鍵生成機(jī)制),   
    native就是將主鍵的生成工作將由數(shù)據(jù)庫完成,hibernate不管(很常用)   
    例:@GeneratedValue(generator = "paymentableGenerator")       
         @GenericGenerator(name = "paymentableGenerator", strategy = "native")   
     2.uuid 采用128位的uuid算法生成主鍵,uuid被編碼為一個(gè)32位16進(jìn)制數(shù)字的字符串。占用空間大(字符串類型)。   
      例:@GeneratedValue(generator = "paymentableGenerator")       
         @GenericGenerator(name = "paymentableGenerator", strategy = "uuid")   
     3.hilo 要在數(shù)據(jù)庫中建立一張額外的表,默認(rèn)表名為hibernate_unque_key,默認(rèn)字段為integer類型,名稱是next_hi(比較少用)   
      例:@GeneratedValue(generator = "paymentableGenerator")       
         @GenericGenerator(name = "paymentableGenerator", strategy = "hilo")   
     4.assigned 在插入數(shù)據(jù)的時(shí)候主鍵由程序處理(很常用),這是<generator>元素沒有指定時(shí)的默認(rèn)生成策略。等同于JPA中的AUTO。   
      例:@GeneratedValue(generator = "paymentableGenerator")       
         @GenericGenerator(name = "paymentableGenerator", strategy = "assigned")   
     5.identity 使用SQL Server和MySQL的自增字段,這個(gè)方法不能放到Oracle中,Oracle不支持自增字段,要設(shè)定sequence(MySQL和SQL Server中很常用)。等同于JPA中的IDENTITY   
      例:@GeneratedValue(generator = "paymentableGenerator")       
         @GenericGenerator(name = "paymentableGenerator", strategy = "identity")   
     6.select 使用觸發(fā)器生成主鍵(主要用于早期的數(shù)據(jù)庫主鍵生成機(jī)制,少用)   
      例:@GeneratedValue(generator = "paymentableGenerator")       
         @GenericGenerator(name = "paymentableGenerator", strategy = "select")   
     7.sequence 調(diào)用謹(jǐn)慎數(shù)據(jù)庫的序列來生成主鍵,要設(shè)定序列名,不然hibernate無法找到。   
      例:@GeneratedValue(generator = "paymentableGenerator")      
   @GenericGenerator(name = "paymentableGenerator", strategy = "sequence",       
   parameters = { @Parameter(name = "sequence", value = "seq_payablemoney") })   
8.seqhilo 通過hilo算法實(shí)現(xiàn),但是主鍵歷史保存在Sequence中,適用于支持Sequence的數(shù)據(jù)庫,如Orcale(比較少用)    
例:@GeneratedValue(generator = "paymentableGenerator")      
   @GenericGenerator(name = "paymentableGenerator", strategy = "seqhilo",       
   parameters = { @Parameter(name = "max_lo", value = "5") })   
9.increnment 插入數(shù)據(jù)的時(shí)候hibernate會給主鍵添加一個(gè)自增的主鍵,但是一個(gè)hibernate實(shí)例就維護(hù)一個(gè)計(jì)數(shù)器,所以在多個(gè)實(shí)例運(yùn)行的時(shí)候不能使用這個(gè)方法。   
例:@GeneratedValue(generator = "paymentableGenerator")       
         @GenericGenerator(name = "paymentableGenerator", strategy = "increnment")   
     10.foreign 使用另一個(gè)相關(guān)的對象的主鍵。通常和<one-to-one>聯(lián)合起來使用。   
     例:@Id       
   @GeneratedValue(generator = "idGenerator")      
   @GenericGenerator(name = "idGenerator", strategy = "foreign",       
        parameters = { @Parameter(name = "property", value = "info") })       
   Integer id;   
@OneToOne    
EmployeeInfo info;   
11.guid 采用數(shù)據(jù)庫底層的guid算法機(jī)制,對應(yīng)MySQL的uuid()函數(shù),SQL Server的newid()函數(shù),ORCALE的rawtohex(sys_guid())函數(shù)等   
例:@GeneratedValue(generator = "paymentableGenerator")        
   @GenericGenerator(name = "paymentableGenerator", strategy = "guid")    
12.uuid.hex 看uudi,建議用uuid替換   
   例:@GeneratedValue(generator = "paymentableGenerator")        
   @GenericGenerator(name = "paymentableGenerator", strategy = "uuid.hex")   
13.sequence-identity sequence策略的擴(kuò)展,采用立即檢索策略來獲取sequence值,需要JDBC3.0和JDK4以上(含1.4)版本   
      例:@GeneratedValue(generator = "paymentableGenerator")      
   @GenericGenerator(name = "paymentableGenerator", strategy = "sequence-identity",       
        parameters = { @Parameter(name = "sequence", value = "seq_payablemoney") })    
        
@OneToOne 設(shè)置一對一個(gè)關(guān)聯(lián)。cascade屬性有五個(gè)值(只有CascadeType.ALL好用?很奇怪),分別是CascadeType.PERSIST(級聯(lián)新建),CascadeType.REMOVE(級聯(lián)刪除),CascadeType.REFRESH(級聯(lián)刷新),CascadeType.MERGE(級聯(lián)更新),CascadeType.ALL(全部四項(xiàng))   
   方法一   
   主表: ?@OneToOne(cascade = CascadeType.ALL)   
     @PrimaryKeyJoinColumn 
     public 從表類 get從表類(){return 從表對象}   
     從表:沒有主表類。   
     注意:這種方法要求主表與從表的主鍵值想對應(yīng)。   
方法二   
     主表:?@OneToOne(cascade = CascadeType.ALL)   
         @JoinColumn(name="主表外鍵") //這里指定的是數(shù)據(jù)庫中的外鍵字段。   
         public 從表類 get從表類(){return 從表類}   
     從表:@OneToOne(mappedBy = "主表類中的從表屬性")//例主表User中有一個(gè)從表屬性是Heart類型的heart,這里就填heart   
         public 主表類 get主表類(){return 主表對象}   
     注意:@JoinColumn是可選的。默認(rèn)值是從表變量名+"_"+從表的主鍵(注意,這里加的是主鍵。而不是主鍵對應(yīng)的變量)。   
方法三   
     主表:@OneToOne(cascade=CascadeType.ALL)   
         @JoinTable( name="關(guān)聯(lián)表名",   
    joinColumns = @JoinColumn(name="主表外鍵"),   
    inverseJoinColumns = @JoinColumns(name="從表外鍵")   
         )   
     從表:@OneToOne(mappedBy = "主表類中的從表屬性")//例主表User中有一個(gè)從表屬性是Heart類型的heart,這里就填heart   
         public 主表類 get主表類(){return 主表對象}       
@ManyToOne 設(shè)置多對一關(guān)聯(lián)   
   方法一          
   @ManyToOne(cascade={CasCadeType.PERSIST,CascadeType.MERGE})   
   @JoinColumn(name="外鍵")   
   public 主表類 get主表類(){return 主表對象}   
   方法二   
   @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE})   
   @JoinTable(name="關(guān)聯(lián)表名",   
   joinColumns = @JoinColumn(name="主表外鍵"),   
   inverseJoinColumns = @JoinColumns(name="從表外鍵")   
   )   
@OneToMany 設(shè)置一對多關(guān)聯(lián)。cascade屬性指定關(guān)聯(lián)級別,參考@OneToOne中的說明。fetch指定是否延遲加載,值為FetchType.LAZY表示延遲,為FetchType.EAGER表示立即加載   
   方法一     使用這種配置,在為“一端”添加“多端”時(shí),不會修改“多端”的外鍵。在“一端”加載時(shí),不會得到“多端”。如果使用延遲加載,在讀“多端”列表時(shí)會出異常,立即加載在得到多端時(shí),是一個(gè)空集合(集合元素為0)。   
   “一端”配置   
   @OneToMany(mappedBy="“多端”的屬性")   
   public List<“多端”類> get“多端”列表(){return “多端”列表}   
   “多端”配置參考@ManyToOne.        
   方法二   
   “一端”配置   
   @OneToMany(mappedBy="“多端”的屬性")   
   @MapKey(name="“多端”做為Key的屬性")   
   public Map<“多端”做為Key的屬性的類,主表類> get“多端”列表(){return “多端”列表}   
   “多端”配置參考@ManyToOne.    
   方法三 使用這種配置,在為“一端”添加“多端”時(shí),可以修改“多端”的外鍵。   
   “一端”配置   
   @OneToMany 
   @JoinColumn(name="“多端外鍵")    
   public List<“多端類> get“多端列表(){return “多端列表}   
   “多端配置參考@ManyToOne.


    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多