先看寫代碼的方法:
@Test
public void testUpdate3() {
Teacher t = new Teacher();
t.setId(1);//指定了主鍵也可以直接更新
t.setName("zhanglaoshi");
Session session2 = sessionFactory.getCurrentSession();
session2.beginTransaction();
session2.update(t);
session2.getTransaction().commit();
}
@Test
public void testUpdate4() {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Teacher t = (Teacher)session.get(Teacher.class, 1);
t.setName("zhangsan2");
session.getTransaction().commit();//提交的時候會自動檢查和數據庫中的數據一樣不一樣,如果有就會自動進行更新。
}
只寫代碼並不好使,因為他們更新的時候不會只更新name,會把所有字段都更新一遍,就算和原來數據一致也會更新。這導致效率降低很多。為了解決這一情況,我們可以做一些修改。有以下幾種方式:
方式1(不推薦)
修改注解,將不打算參與更新的字段的get方法上加上這么一段:@Column(updatable=false)。
關於持久化相關注解的更多內容可以參看jee api的javax.persistence相關內容。
方式2(不推薦)
修改映射關系xml,<property name="age" update="false" />
關於持久化映射關系xml配置的更多內容可以參看hibernate的doc文檔(關於本例,參考目錄hibernate-release-4.2.8.Final\documentation\manual\en-US\html_single中的5. Basic O/R Mapping---5.1. Mapping declaration---5.1.4. Property---5.1.4.2 )
方式3
在hbm配置文件上加上下面的黑體行
<hibernate-mapping>
<class name="com.test.hibernate.Student" dynamic-update="true">
如此,在同一個session中更新數據就可以只更新變更了的數據。
如果想跨session只更新修改了的字段,可以手動讓hibernate去比較,session.merge(要比較的從別的session里取出來后修改過的對象)。但是為了作比較hibernate會自動先查詢一遍數據庫。
但是用注解怎么實現呢?????用注解能實現嗎????難道為了只更新修改的字段我們就要把映射關系都在xml文件里實現而放棄注解?這個我暫時也不知道,如果你看到了就自己查去吧。。
方式4(推薦)
使用HQL(EJBQL)自己寫一條類似sql而非sql的語句
@Test
public void testUpdate7() {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Query q = session.createQuery("update Student s set s.name='z5' where s.id = 1");//這個org.hibernate.Query對象類似於jdbc的statement,這里update的不是表而是對象s,所以指明Student類用了大寫的S
q.executeUpdate();
session.getTransaction().commit();
}