Hibernate(5)session的方法

您所在的位置:网站首页 hibernate的save方法捕捉不到异常 Hibernate(5)session的方法

Hibernate(5)session的方法

2023-07-15 21:41| 来源: 网络整理| 查看: 265

1. Session缓存 Session缓存(Hibernate一级缓存),在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存。只要 Session 实例没有结束生命周期, 且没有清理缓存,则存放在它缓存中的对象也不会结束生命周期。 Session 缓存可减少 Hibernate 应用程序访问数据库的频率。 两次获取同一个对象: ①第一次获取Users对象时会去数据库中查找,找到之后把Users对象的引用赋给user引用变量,同时还会把Users对象的引用给到Session缓存中, ②若再次查找同一个Users变量,首先会去Session中找有没有,若缓存中有就不去查询数据库,直接从缓存中获取 /** * Session缓存(Hibernate一级缓存),在 Session 接口的实现中包含一系列的 Java 集合, *这些 Java 集合构成了 Session 缓存。 *只要 Session 实例没有结束生命周期, 且没有清理缓存,则存放在它缓存中的对象也不会结束生命周期 *Session 缓存可减少 Hibernate 应用程序访问数据库的频率。 * 两次获取同一个对象: * ①第一次获取Users对象时会去数据库中查找,找到之后把Users对象的引用赋给user引用变量, * 同时还会把Users对象的引用给到Session缓存中, * ②若再次查找同一个Users变量,首先会去Session中找有没有,若缓存中有就不去查询数据库,直接从缓存中获取 */ @Test public void testSessionCache(){ Users user = (Users) session.get(Users.class, 8); System.out.println(user); Users user2 = (Users) session.get(Users.class, 8); System.out.println(user2); } 2. flush方法:使数据表中的记录和Session缓存中的对象的状态保持一致,为保持一致,则可能会发送对应的SQL语句 * 提下情况会调用该方法: * 1.在Transaction的commit方法中,先调用session的Flush方法,在提交事务 * 2.显式的调用flush()方法可能会发送SQL语句,但不会提交事务 * 3.注意:在未提交事务或显式的调用session.flush()方法之前,也有可能进行flush()操作。 * ①.执行HQL或QBC查询,会先进行flush()操作,以得到数据表的最新的记录 * ②.若记录的ID是由底层数据库使用自增的方式生成的则在调用save()方法后,就会立即发送INSERT语句,因为save方法后 * 必须保证对象的ID是存在的 /** * flush方法:使数据表中的记录和Session缓存中的对象的状态保持一致,为保持一致,则可能会发送对应的SQL语句 *提下情况会调用该方法: * 1.在Transaction的commit方法中,先调用session的Flush方法,在提交事务 * 2.显式的调用flush()方法可能会发送SQL语句,但不会提交事务 * 3.注意:在未提交事务或显式的调用session.flush()方法之前,也有可能进行flush()操作。 * ①.执行HQL或QBC查询,会先进行flush()操作,以得到数据表的最新的记录 * ②.若记录的ID是由底层数据库使用自增的方式生成的则在调用save()方法后,就会立即发送INSERT语句,因为save方法后 *必须保证对象的ID是存在的 */ @Test public void testSessionFlush(){ Users users = (Users) session.get(Users.class, 8); users.setLoginName("Jack"); //session.flush(); //System.out.println("flush()"); //HQL查询 Users user2 = (Users) session.createCriteria(Users.class).uniqueResult(); System.out.println(user2); } //使用save()方法,会立即执行SQL语句,而不用等到事务提交,其他方法需要等到事务提交之后到能执行SQL语句 @Test public void testSessionFlush2(){ Users user = new Users("mengqi", "123", "孟奇", "河南省郑州市", "19843244908", "[email protected]", new Date()); session.save(user); } 3. reflush():获取数据表中最新的记录,该方法会强制执行查询, * 手动修改表中的记录,使用reflush(),再次打印user时,打印的记录就会和之前打印的不一致,此时打印的是手动修改后的记录,即最新是记录,若打印的不是最新的则是MYSQL数据库的隔离级别问题,MYSQL默认的隔离级别为REPEATABLE READ(可重复读),需要改成READ COMMITED(读已提交)。 * 在Hibernate的配置文件中,可以显示的设置隔离级别,每一个隔离级别都对应一个数字 * 1对应READ UNCOMMITED * 2对应READ COMMITED * 4对应REPEATABLE READ * 8对应SERIALIZEABLE *Hibernate通过Hibernate配置文件指定,Hibernate.connection.isolation属性设置事务的隔离级别 /** * reflush():获取数据表中最新的记录,该方法会强制执行查询, * 手动修改表中的记录,使用reflush(),再次打印user时,打印的记录就会和之前打印的不一致,此时打印 * 的是手动修改后的记录,即最新是记录,若打印的不是最新的则是MYSQL数据库的隔离级别问题, * MYSQL默认的隔离级别为REPEATABLE READ(可重复读),需要改成READ COMMITED(读已提交) * 在Hibernate的配置文件中,可以显示的设置隔离级别,每一个隔离级别都对应一个数字 * 1对应READ UNCOMMITED * 2对应READ COMMITED * 4对应REPEATABLE READ * 8对应SERIALIZEABLE *Hibernate通过Hibernate配置文件指定,Hibernate.connection.isolation属性设置事务的隔离级别 */ @Test public void testReFlush(){ Users user = (Users) session.get(Users.class, 8); System.out.println(user); //在此打印断点,打印出的user与上一个打印的user没有什么不同 System.out.println(user); //此时手动修改了表中的记录,使用reflush(),再次打印user时,打印的记录就会和之前打印的不一致,此时打印 //的是手动修改后的记录,即最新是记录,若打印的不是最新的则是MYSQL数据库的隔离级别问题, //MYSQL默认的隔离级别为REPEATABLE READ(可重复读),需要改成 session.refresh(user); System.out.println(user); } 4. claer():清理缓存,两次查询同一条记录,中间使用clear()清理之后,第二条查询也会发送一条记录 /** * claer():清理缓存,两次查询同一条记录,中间使用clear()清理之后,第二条查询也会发送一条记录 */ @Test public void testClear(){ Users users = (Users) session.get(Users.class, 8); session.clear(); Users users2 = (Users) session.get(Users.class, 8); } 5. save() * ①把对象加入到Session缓存中,使一个临时对象变为持久化对象 * ②选用映射文件指定的标识符生成器,为对象分配ID * ③在flush()缓存时会发送一条INSERT语句 * ④在save()方法之前设置ID属性值是无效的,但不抛出异常 * ⑤持久化对象的ID是不能被修改的 /** * save(): * ①把对象加入到Session缓存中,使一个临时对象变为持久化对象 * ②选用映射文件指定的标识符生成器,为对象分配ID * ③在flush()缓存时会发送一条INSERT语句 * ④在save()方法之前设置ID属性值是无效的,但不抛出异常 * ⑤持久化对象的ID是不能被修改的 */ @Test public void testSave(){ Users user = new Users("wangqiang", "123", "王强", "河南省", "18292389876", "[email protected]", new Date()); //save()方法前后的对象区别在于save()之后会给对象分配ID System.out.println("user:"+user); session.save(user); System.out.println("user:"+user); //在save()方法前修改ID是无效的 Users user2 = new Users("wangqiang", "1234", "王强", "河南省", "18292389876", "[email protected]", new Date()); user2.setId(100); session.save(user2); System.out.println("user2:"+user2);//为id赋值失败 user2.setId(100); } 6. Persist():也会执行INSERT操作,作用与save()一致 与save的主要内容区别: persist把一个瞬态的实例持久化,但是并"不保证"标识符(identifier主键对应的属性)被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时候。 save, 把一个瞬态的实例持久化标识符,及时的产生,它要返回标识符,所以它会立即执行Sql insert /** * Persist():也会执行INSERT操作,作用与save()一致,与save的主要内容区别: persist把一个瞬态的实例持久化,但是并"不保证"标识符(identifier主键对应的属性)被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时候。 save, 把一个瞬态的实例持久化标识符,及时的产生,它要返回标识符,所以它会立即执行Sql insert *: */ @Test public void testPersist(){ Users user = new Users("wangwei", "123", "王伟", "河南省", "19483928495", "[email protected]", new Date()); user.setId(100); session.persist(user); } 7. GET()和Load()的区别 * 1.get方法会立即加载该对象,立即执行查询 * load方法,若不使用该对象,则不会立即加载,而返回一个代理对象,不会立即执行查询操作 * 2.若数据表中没有对应的记录get返回null,load会抛出异常 * 3.load方法可能会抛出懒加载异常,因为load方法是在使用对象的时候再执行查询操作, * 假如在使用对象之前把session关闭,即需要初始化代理对象之前已经关闭了Session,同时又在使用加载的对象, * 就会出现懒加载异常,若不使用加载的对象,则没有问题 * get在使用对象之前关闭session则没有问题。 * GET()和Load()的区别 * 1.get方法会立即加载该对象,立即执行查询 * load方法,若不使用该对象,则不会立即加载,而返回一个代理对象,不会立即执行查询操作 * 2.若数据表中没有对应的记录get返回null,load会抛出异常 * 3.load方法可能会抛出懒加载异常,因为load方法是在使用对象的时候再执行查询操作, * 假如在使用对象之前把session关闭,即需要初始化代理对象之前已经关闭了Session,同时又在使用加载的对象, * 就会出现懒加载异常,若不使用加载的对象,则没有问题 * get在使用对象之前关闭session则没有问题。 * */ @Test public void testGet(){ Users user = (Users) session.get(Users.class, 5); session.close(); System.out.println(user); } @Test public void testLoad(){ Users user = (Users) session.load(Users.class, 5); session.close();//使用对象前关闭session,出现懒加载异常org.hibernate.LazyInitializationException,不使用则没有问题 System.out.println(user); } 8. Update() * 1.若更新一个持久化对象,不需要显示的调用update()方法,因为在调用Transaction的commit方法时,会先执行 *Session的flush()方法 * 2.更新一个游离对象时,需要显式的调用Session的update方法,可以把一个游离对象变为一个持久化对象 *注意: * ①.若显式的调用Session的update方法,则无论游离的对象中属性有没有变化,都会发送update语句 *可以使用Xxx.hbm.xml文件的class节点设置select-before-update=true(默认为false), *但通常并不设置此属性 * ②.若数据表中没有对应的记录,但还调用了update方法,会抛出异常 * ③.当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, * 会抛出异常 /** * Update() * 1.若更新一个持久化对象,不需要显示的调用update()方法,因为在调用Transaction的commit方法时,会先执行 *Session的flush()方法 * 2.更新一个游离对象时,需要显式的调用Session的update方法,可以把一个游离对象变为一个持久化对象 *注意: * ①.若显式的调用Session的update方法,则无论游离的对象中属性有没有变化,都会发送update语句 *可以使用Xxx.hbm.xml文件的class节点设置select-before-update=true(默认为false), *但通常并不设置此属性 * ②.若数据表中没有对应的记录,但还调用了update方法,会抛出异常 * ③.当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, * 会抛出异常 */ @Test public void testUpdate(){ Users user = (Users) session.get(Users.class, 8); //1. transaction.commit(); //关闭session,user对象成为游离对象 session.close(); //②更改游离对象的id,使update方法更新一个数据库中不存在的记录,结果是抛出异常 //user.setId(100); //虽然又开启了一个Session,但是这个Session与上一个Session并没有联系。 session = sessionFactory.openSession(); transaction = session.beginTransaction(); //③虽然这只是一个简单的查询,但是执行查询会在session缓存中关联ID为8的一个持久化对象, //当显式执行下面的update方法时,会把id为8的游离对象也关联到session缓存中,但是Session缓存中不能有 //两个相同ID的对象 Users users = (Users) session.get(Users.class, 8); user.setLoginName("Nick"); //2.只有显式的调用session的update方法才能让设置的LoginName属性生效 session.update(user); } 9. SaveOrUpdate():若是一个临时对象则执行save,游离对象执行update * 注意: * 1.若OID不为null,但数据表中没有与之对应的记录则会抛出异常,因为虽然OID不为空,也是一个游离对象, *但是数据表中没有对应的记录无法执行update语句。 * 2.了解:OID值等于id的unsaved-value属性值的对象,也被认为是一个游离对象,unsave-value是映射文件中id子节点的属性 /** * SaveOrUpdate():若是一个临时对象则执行save,游离对象执行update * 注意: * 1.若OID不为null,但数据表中没有与之对应的记录则会抛出异常,因为虽然OID不为空,也是一个游离对象, *但是数据表中没有对应的记录无法执行update语句。 * 2.了解:OID值等于id的unsaved-value属性值的对象,也被认为是一个游离对象,unsave-value是映射文件中id子节点的属性 */ @Test public void testSaveOrUpdate(){ //临时对象,调用saveOrUpdate()方法,执行insert语句 Users user = new Users("wangmei", "123", "王梅", "河南省", "19483928495", "[email protected]", new Date()); //设置id为8对应数据库表中存在的记录,调用saveOrUpdate()方法,执行update语句 user.setId(8); //该值等于映射文件中id子节点的unsave-value属性值,所以可以调用saveOrUpdate()方法,执行insert语句 user.setId(100); session.saveOrUpdate(user); } 10. Delete():Session的delete()方法既可以删除一个游离对象,又可以删除一个持久化对象, * ①只要OID和数据表中一条记录对应,就会准备执行Delete操作,若OID在数据表中没有对应的记录,则会抛出异常。 * ②可以通过设置Hibernate配置文件中的一个hibernate.use_identifier_rollback 属性 *来把持久化对象或游离对象的 OID 设置为 null, 使它们变为临时对象 /** * Delete():Session的delete()方法既可以删除一个游离对象,又可以删除一个持久化对象, * ①只要OID和数据表中一条记录对应,就会准备执行Delete操作,若OID在数据表中没有对应的记录,则会抛出异常。 * ②可以通过设置Hibernate配置文件中的一个hibernate.use_identifier_rollback 属性 *来把持久化对象或游离对象的 OID 设置为 null, 使它们变为临时对象 */ @Test public void testDelete(){ //因为数据表中id为8的记录已经被删除了,所以该对象是游离对象 // Users user = new Users(); // user.setId(8); //持久化对象也可以删除 Users user = (Users) session.get(Users.class, 7); session.delete(user); //执行完delete之后,该对象还是有ID值的,若之后想要对该对象执行saveOrUpdate方法,则会强制发送update语句 //但是,数据表中已经没有这条记录,就会抛异常 System.out.println(user); } 11. Evict():从Session中把指定的持久化对象移除 /** * Evict():从Session中把指定的持久化对象移除 * */ @Test public void testEvict(){ Users user = (Users) session.get(Users.class, 4); Users user2 = (Users) session.get(Users.class, 5); user.setLoginName("Lucy"); user2.setLoginName("Jack"); //虽然更新了两个对象的值,但是由于user对象从session中移除,所以只对user2执行了update session.evict(user); } 12. doWork():调用存储过程,需要获取Connection /** * doWork():调用存储过程,需要获取Connection */ @Test public void testDoWork(){ session.doWork(new Work() { @Override public void execute(Connection conn) throws SQLException { //没有配置C3P0数据源时连接是从数据库中获取的:com.mysql.jdbc.JDBC4Connection@42f92dbc //配置C3P0数据源之后从连接池中获取连接:com.mchange.v2.c3p0.impl.NewProxyConnection@66ee2542 System.out.println(conn); //调用存储过程 } }); } 13. dynamic-update:class节点的属性不设置的话执行更新操作的话,会更新全部的属性值,设置之后仅更新修改后的属性值 *好处:减少数据库的操作 /** * dynamic-update:class节点的属性,不设置的话执行更新操作的话,会更新全部的属性值,设置之后仅更新修改后的属性值 *好处:减少数据库的操作 */ @Test public void testdynamicUpdate(){ Users user = (Users) session.get(Users.class, 4); user.setLoginPwd("1234"); } 14. 主键生成策略:increment主键生成器时会出现并发的问题,连续执行两次该方法,模仿两个线程同时访问同一个数据表 * 由于是自增,但是是两个线程,所以会造成两个线程的id自增之后,id值重复,无法执行SQL语句 /** * 主键生成策略:increment主键生成器时会出现并发的问题,连续执行两次该方法,模仿两个线程同时访问同一个数据表 * 由于是自增,但是是两个线程,所以会造成两个线程的id自增之后,id值重复,无法执行SQL语句 * @throws InterruptedException */ @Test public void testIdGenerator() throws InterruptedException{ Users user = new Users("wangwei", "123", "王伟", "河南省", "19483928495", "[email protected]", new Date()); session.save(user); //Thread.sleep(5000); } 15. ①派生属性②Java 时间和日期类型的 Hibernate 映射 /** * ①派生属性 * ②Java 时间和日期类型的 Hibernate 映射 */ @Test public void testPropertyUpdate(){ Users user = (Users) session.get(Users.class, 1); user.setLoginName("AAA"); System.out.println(user.getDesc()); System.out.println(user.getDate().getClass()); } 16. 大文件属性映射 /** * 大文件属性映射数据库 * @throws Exception */ @Test public void testBlob() throws Exception{ Users user = new Users("wangwei", "123", "王伟", "河南省", "19483928495", "[email protected]", new Date()); user.setContent("CONTENT"); //文件的输入流 InputStream inputStream = new FileInputStream("1.jpg"); Blob image = Hibernate.getLobCreator(session).createBlob(inputStream, inputStream.available()); user.setImage(image); session.save(user); Users user2 = (Users) session.get(Users.class, 1); Blob image2 = user2.getImage(); //输出流输出文件 InputStream inputStream2 = image2.getBinaryStream(); //仅显示文件的大小 System.out.println("图片大小:" + inputStream2.available()); } 17.映射组成关系:即一个没有id的自定义类是另一个自定义类中的属性,那么这个属性可以使用映射组成关系来映射 /** * 映射组成关系:即一个没有id的自定义类是另一个自定义类中的属性,那么这个属性可以使用映射组成关系来映射 */ @Test public void testComponent(){ Worker worker = new Worker(); Pay pay = new Pay(); pay.setMonthlyPay(1000); pay.setYearPay(12000); pay.setVocationWithPay(5); worker.setName("ABC"); worker.setPay(pay); session.save(worker); }

以上方法的需要的 实体类 Users.java

package com.test.withXml.entity; import java.io.Serializable; import java.sql.Blob; import java.util.Date; public class Users implements Serializable { private static final long serialVersionUID = 1L; private Integer id; private String loginName; private String loginPwd; private String name; private String address; private String phone; private String mail; //日期格式 private Date date; //派生的属性 private String Desc; //大文本属性 private String content; //二进制文件 private Blob image; public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Blob getImage() { return image; } public void setImage(Blob image) { this.image = image; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } public String getLoginPwd() { return loginPwd; } public void setLoginPwd(String loginPwd) { this.loginPwd = loginPwd; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getMail() { return mail; } public void setMail(String mail) { this.mail = mail; } public String getDesc() { return Desc; } public void setDesc(String desc) { Desc = desc; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } //1. public Users(String loginName, String loginPwd, String name, String address, String phone, String mail, Date date) { super(); this.loginName = loginName; this.loginPwd = loginPwd; this.name = name; this.address = address; this.phone = phone; this.mail = mail; this.date = date; } //2. public Users() { } @Override public String toString() { return "Users [loginName=" + loginName + ", loginPwd=" + loginPwd + ", name=" + name + ", address=" + address + ", phone=" + phone + ", mail=" + mail + ", date=" + date + "]"; } }

Worker.java

package com.test.withXml.entity; /** * @author * @version: 1.0 * @Created on: 2018-1-17 下午10:03:14 * 类说明:工人 */ public class Worker { private Integer id; private String name; private Pay pay; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Pay getPay() { return pay; } public void setPay(Pay pay) { this.pay = pay; } }

映射文件User.hbm.xml

Worker.hbm.xml



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3