先看写代码的方法:
@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.Finaldocumentationmanualen-UShtml_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();
}