void |
update(Object object) Update the persistent instance with the identifier of the given detached instance. |
还是通过例子来看看
1.用之前的Teacher
package com.baosight.model;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.SequenceGenerator;
import javax.persistence.TableGenerator;
/**
* Title:
* Description:Teacher
* Company:
* @author yuan
* @date 2016-4-10 下午12:32:46*/
@Entity
@TableGenerator(name="tableGEN",table="table_gen",pkColumnName="pk_key",valueColumnName="pk_value",pkColumnValue="teacher",allocationSize=1)
@SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")
//@IdClass(value=TeacherPK.class)
public class Teacher {
private String id;
private String name;
private String title;
// private TeacherPK pk;
@Id
@GeneratedValue//auto
// @GeneratedValue(strategy=GenerationType.TABLE,generator="tableGEN")
// @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="teacherSEQ")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
// @Id
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(updatable=false)//不参与自动更新
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
// @EmbeddedId
// @Id
/*public TeacherPK getPk() {
return pk;
}
public void setPk(TeacherPK pk) {
this.pk = pk;
}*/
}
2.JUnit测试类为TeacherTest.java
package com.baosight.model;
import static org.junit.Assert.*;
import javax.persistence.Column;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Title:TecherTest
* Description:TODO
* Company:
* @author yuan
* @date 2016-4-13 下午10:32:17*/
public class TeacherTest {
private static SessionFactory sf = null;
@BeforeClass
public static void beforeClass(){
// 读取配置文件
Configuration cfg = new AnnotationConfiguration();
// 得到session工厂
sf = cfg.configure().buildSessionFactory();
}
@Test
public void testSave() {
// 教师测试类
Teacher t = new Teacher();
t.setName("t1");
t.setTitle("中级");
System.out.println("transient状态下id============="+t.getId());
// 得到session
Session session = sf.openSession();
// 开启事务
session.beginTransaction();
// session执行save
session.save(t);
System.out.println("persistent状态下id============="+t.getId());
// 事务提交
session.getTransaction().commit();
// 关闭session
session.close();
System.out.println("ditached状态下id============="+t.getId());
}
@Test
public void testDelete() {
// 教师测试类
Teacher t = new Teacher();
t.setName("t1");
t.setTitle("中级");
System.out.println("transient状态下id============="+t.getId());
// 得到session
Session session = sf.getCurrentSession();
// 开启事务
session.beginTransaction();
// session执行save
session.save(t);
System.out.println("persistent状态下id============="+t.getId());
// 事务提交
session.getTransaction().commit();
// 关闭session
System.out.println("ditached状态下id============="+t.getId());
//删除
Session session2 = sf.getCurrentSession();
// 开启事务
session2.beginTransaction();
// session执行
session2.delete(t);
System.out.println("persistent状态下id============="+t.getId());
// 事务提交
session2.getTransaction().commit();
// 关闭session
System.out.println("ditached状态下id============="+t.getId());
}
@Test
public void testDelete2() {
// 教师测试类
Teacher t = new Teacher();
t.setId("24");
System.out.println("transient状态下id============="+t.getId());
//删除
Session session2 = sf.getCurrentSession();
// 开启事务
session2.beginTransaction();
// session执行
session2.delete(t);
System.out.println("persistent状态下id============="+t.getId());
// 事务提交
session2.getTransaction().commit();
// 关闭session
System.out.println("ditached状态下id============="+t.getId());
}
@Test
public void testLoad() {
//使用代理,只有使用到查询对象时才会打印sql
Session session = sf.getCurrentSession();
// 开启事务
session.beginTransaction();
// session执行
Teacher t = (Teacher) session.load(Teacher.class, "1");
//打印代理对象名称
System.out.println(t.getClass().getName());
// System.out.println(t);
// System.out.println("id============="+t.getId());
// 事务提交
session.getTransaction().commit();
// 关闭session
// System.out.println("id============="+t.getId());
}
@Test
public void testGet() {
//直接从数据库查询,会打印sql
Session session = sf.getCurrentSession();
// 开启事务
session.beginTransaction();
// session执行
Teacher t = (Teacher) session.get(Teacher.class, "1");
System.out.println(t.getClass().getName());
// System.out.println(t);
// System.out.println("id============="+t.getId());
// 事务提交
session.getTransaction().commit();
// 关闭session
// System.out.println("id============="+t.getId());
}
@Test
public void testUpdate1() {
//直接从数据库查询,会打印sql
Session session = sf.getCurrentSession();
// 开启事务
session.beginTransaction();
// session执行
Teacher t = (Teacher) session.get(Teacher.class, "1");
// 事务提交
session.getTransaction().commit();
//将detached通过update变为persistent
//修改
t.setName("zhangsan");
Session session2 = sf.getCurrentSession();
// 开启事务
session2.beginTransaction();
// session执行
session2.update(t);
// 事务提交
session2.getTransaction().commit();
}
@Test
public void testUpdate2() {
// 教师测试类
Teacher t = new Teacher();
t.setName("zhangsan");
//transient没有Id无法进行update操作
//修改
Session session2 = sf.getCurrentSession();
// 开启事务
session2.beginTransaction();
// session执行
session2.update(t);
// 事务提交
session2.getTransaction().commit();
}
@Test
public void testUpdate3() {
// 教师测试类
Teacher t = new Teacher();
t.setId("1");
t.setName("lisi");
//transient有Id可以进行update操作
//修改
Session session2 = sf.getCurrentSession();
// 开启事务
session2.beginTransaction();
// session执行
session2.update(t);
// 事务提交
session2.getTransaction().commit();
}
@Test
public void testUpdate4() {
// 直接从数据库查询,会打印sql
Session session = sf.getCurrentSession();
// 开启事务
session.beginTransaction();
// session执行
Teacher t = (Teacher) session.get(Teacher.class, "1");
//对persistent直接set也能执行
//测试@Column(updatable=false)指定age不参与修改
t.setName("wangwu");
// 事务提交
session.getTransaction().commit();
}
@Test
public void testUpdate5() {
// 学生测试类
// 得到session
Session session = sf.openSession();
// 开启事务
session.beginTransaction();
// session执行
Student s = (Student) session.get(Student.class, "1");
//xml文件
3.测试结果如下:
update1方法用来测试detached执行update的效果,发现是可以执行的,但是,存在修改1个字段其它字段也被修改的问题,结果如下:
update2用来测试transient执行update的问题,由于未设定Id,所以执行失败,结果如下:
update3为transient设定了Id,可以正常执行,结果如下:
update4用来测试对于persistent直接使用set属性进行修改,能够执行,结果如下:
4.从以上的测试可以发现一个问题,就是对1个属性的修改可能会影响到其他的属性,为了解决这一问题有三种方案:
一是使用annotation的@Column(updatable=false),放在不想被自动修改的属性的get方法上面,比如上面使用在getTitle,对于使用xml的需要修改 二是对于xml使用在class使用dynamic-update="true"说明只修改变化的列 三是通过HQl来实现特定的修改 5.使用annotation的@Column(updatable=false) 修改Teacher的getTitle,使用注解 6.对于使用xml的需要修改 使用之前的Student Title: Description:Student Company: 7.对于xml使用在class使用dynamic-update="true"说明只修改变化的列,xml见上面 运行update5,结果如下: 8.通过HQL来实现特定的修改 直接通过执行特定的HQL来实现特定的修改 比如本例中的update8,方法如下: 9.执行update6,结果如下: 发现persistent的update只修改变化的属性,而detached则可能修改其他属性,针对这一情况,可以考虑使用merge 10.merge的使用 hibernate的API文档中对Session的merge方法的描述: 执行update7,结果如下: 以上即为hibernate的Session的update相关内容,值得一提的是,对于上面提到的防止修改其他属性的3种方法,在实际的使用中多采用第三种方法,即使用HQL实现特定的修改,当然可能还会结合HQL查询等。
重新执行update4,结果如下:
@Column(updatable=false)
public String getTitle() {
return title;
}
修改Student.hbm.xml,使用package com.baosight.model;
import javax.persistence.Column;
/**
*
运行update5,结果如下:
执行结果如下:
@Test
public void testUpdate8() {
// 直接从数据库查询,会打印sql
Session session = sf.getCurrentSession();
// 开启事务
session.beginTransaction();
//通过HQl来实现特定的修改
Query q = session.createQuery("update Student s set s.name='lisi' where s.id='1'");
q.executeUpdate();
// 事务提交
session.getTransaction().commit();
}
Object
merge(Object object)
Copy the state of the given object onto the persistent object with the same identifier.
将给定对象的状态复制到具有相同标识符的持久对象上。会先做查询再做修改,类似于persistent的update