Hibernate入门2
实体类的编写规则
- 要求实体类的属性是私有的
- 要求实体类中的私有属性有公开的get和set方法(设置器和访问器)
- 要求实体类有一个属性作为唯一值(一般使用id值)
- 实体类属性建议不使用基本数据类型,使用基本数据类型对应的包装类(原因:假如使用int表示学生分数,当学生的分数为0的时候,可以使用int score=0,但是如果学生没有参加考试的话,那么如何表示,这样的话,相对于使用int来表示,可能会有点局限性,那么我们可以使用int的包装类型Integer来表示的话,就相对于比较的方便,如学生成绩为0的话,可以用0进行表示,学生没有参加考试的话,可以使用null值进行表示)
Hibernate主键的生成策略
- Hibernate要求实体类里面有一个属性作为唯一值,对应表主键,主键可以有不同的生成策略
- Hibernate主键的生成策略又很多的值,最主要的是(native和uuid)
实体类操作
对实体类的crud(增删改查)操作
添加操作: Session的save()方法
1 public void add() { 2 3 SessionFactory sf = Tools.getSessionFactory(); 4 5 Session session = sf.openSession(); 6 7 Transaction tx = session.beginTransaction(); 8 9 /** 10 11 * 创建对象 12 13 */ 14 15 User user = new User(); 16 17 user.setPassword("123"); 18 19 user.setUsername("Alleys"); 20 21 session.save(user); 22 23 tx.commit(); 24 25 /** 26 27 * 释放资源 28 29 */ 30 31 session.close(); 32 33 sf.close(); 34 35 }
查询操作(根据id查询):Session的get()方法get方法的第一个参数是实体类的Class对象,第二个参数是id值
1 public void select() { 2 3 SessionFactory sf = Tools.getSessionFactory(); 4 5 Session session = sf.openSession(); 6 7 Transaction tx = session.beginTransaction(); 8 9 User user = session.get(User.class, 1); 10 11 System.out.println(user); 12 13 tx.commit(); 14 15 /** 16 17 * 释放资源 18 19 */ 20 21 session.close(); 22 23 sf.close(); 24 25 }
修改操作:使用Session的update()方法,一般是先查询看是否存在此条记录,然后在修改
1 public void update() { 2 3 SessionFactory factory = Tools.getSessionFactory(); 4 5 Session session = factory.openSession(); 6 7 Transaction tx = session.beginTransaction(); 8 9 // 先查询,id为1的记录是否存在,将密码修改为456 10 11 User user = session.get(User.class, 1); 12 13 if(user==null) { 14 15 System.out.println("此记录不存在..."); 16 17 return; 18 19 } 20 21 // 更新数据 22 23 user.setPassword("456"); 24 25 session.update(user); 26 27 tx.commit(); 28 29 session.close(); 30 31 factory.close(); 32 33 }
删除操作:Session的delete()方法,传参数,就是传递一个对象
1 public void delete() { 2 3 SessionFactory factory = Tools.getSessionFactory(); 4 5 Session session = factory.openSession(); 6 7 Transaction tx = session.beginTransaction(); 8 9 // 先查询,id为1的记录是否存在,存在的话删除 10 11 User user = session.get(User.class, 1); 12 13 if(user==null) { 14 15 System.out.println("此记录不存在..."); 16 17 return; 18 19 } 20 21 session.delete(user); 22 23 tx.commit(); 24 25 session.close(); 26 27 factory.close(); 28 29 } 30 31 32 33 public void delete2() { 34 35 SessionFactory factory = Tools.getSessionFactory(); 36 37 Session session = factory.openSession(); 38 39 Transaction tx = session.beginTransaction(); 40 41 // 先查询,id为1的记录是否存在,存在的话删除 42 43 User user = new User(); 44 45 user.setUid(6); 46 47 session.delete(user); 48 49 tx.commit(); 50 51 session.close(); 52 53 factory.close(); 54 55 }
实体类的对象的三种状态:
瞬时态:对象里面没有id值,对象与session没有关联
持久态:对象中有id值,对象与session有关联
对象通过session查出来,与session有关,且user中有id值
托管态:对象中有id值,但是对象和session没有关联
saveOrUpdate()方法,此方法即能进行保存也能进行更新操作。
对于这个方法而言,如果实体类的对象是瞬时态的时候,做的是添加的操作
1 public void show_saveOrUpdate_method() { 2 3 /** 4 5 * 瞬时态 6 7 */ 8 9 SessionFactory factory = Tools.getSessionFactory(); 10 11 Session session = factory.openSession(); 12 13 Transaction tx = session.beginTransaction(); 14 15 // 先查询,id为1的记录是否存在,存在的话删除 16 17 User user = new User(); 18 19 user.setPassword("123456789"); 20 21 user.setUsername("Lily"); 22 23 session.saveOrUpdate(user); 24 25 tx.commit(); 26 27 session.close(); 28 29 factory.close(); 30 31 }
如果实体类的对象是持久态或者托管态的话,做的是更新操作
1 public void show_saveOrUpdate_method() { 2 3 /** 4 5 * 瞬时态 6 7 */ 8 9 SessionFactory factory = Tools.getSessionFactory(); 10 11 Session session = factory.openSession(); 12 13 Transaction tx = session.beginTransaction(); 14 15 User user = session.get(User.class, 7); 16 17 user.setPassword("5446546"); 18 19 session.saveOrUpdate(user); 20 21 tx.commit(); 22 23 session.close(); 24 25 factory.close(); 26 27 } 28 29 30 31 public void show_saveOrUpdate_method() { 32 33 /** 34 35 * 瞬时态 36 37 */ 38 39 SessionFactory factory = Tools.getSessionFactory(); 40 41 Session session = factory.openSession(); 42 43 Transaction tx = session.beginTransaction(); 44 45 /*// 先查询,id为1的记录是否存在,存在的话删除 46 47 User user = new User(); 48 49 user.setPassword("123456789"); 50 51 user.setUsername("Lily"); 52 53 session.saveOrUpdate(user); 54 55 tx.commit();*/ 56 57 /*User user = session.get(User.class, 7); 58 59 user.setPassword("5446546"); 60 61 session.saveOrUpdate(user);*/ 62 63 User user = new User(); 64 65 user.setUid(7); 66 67 user.setPassword("8888888"); 68 69 session.saveOrUpdate(user); 70 71 tx.commit(); 72 73 session.close(); 74 75 factory.close(); 76 77 }
Hibernate的一级缓存
什么是缓存?
数据存到数据库里面,数据库本身是文件系统,使用流方式操作文件效率不是很高。
- 把数据存到内存中,就不需要使用流的方式,可以直接读取内存中数据
- 把数据放到内存中,提高读取效率
而在Hibernate中为我们提供了很多的优化的方式,其中一个就是Hibernate缓存
Hibernate的缓存的特点:
(1) hibernate的一级缓存
- hibernate的一级缓存默认是开启的
- hibernate的一级缓存使用范围,是session范围,从session的创建到session的关闭为止
- hibernate的一级缓存中,要求实体类对象的保存数据的状态必须是持久态数据
(2) hibernate的二级缓存
- hibernate的二级缓存目前已经不使用了,替代技术redis
- hibernate的二级缓存默认是不用打开的,需要进行配置
- hibernate的二级缓存的使用范围,就是sessionFactory的范围,也就是整个项目的范围
一级缓存会自动更新数据库,在没有调用update方法的时候
1 public void testCache() { 2 3 SessionFactory factory = Tools.getSessionFactory(); 4 5 Session session = factory.openSession(); 6 7 Transaction tx = session.beginTransaction(); 8 9 User user = session.get(User.class, 7); 10 11 user.setPassword("5446546"); 12 13 tx.commit(); 14 15 session.close(); 16 17 factory.close(); 18 19 }
Hibernate的事务操作
什么是事务?
数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。
事务的特性
原子性(Atomicity):
事务是数据库的逻辑工作单位,它对数据库的修改要么全部执行,要么全部不执行。
一致性(Consistemcy):
事务前后,数据库的状态都满足所有的完整性约束。
隔离性(Isolation):
并发执行的事务是隔离的,一个不影响一个。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。通过设置数据库的隔离级别,可以达到不同的隔离效果。
持久性(Durability):
在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
不考虑隔离性产生的问题
脏读
不可重复读
虚读或者幻读
设置事务的隔离级别
Mysql的默认隔离级别为repeatable read
事务代码的标准写法:
1 public void testTx() { 2 3 // 事务代码的规范写法 4 5 Transaction tx = null; 6 7 SessionFactory factory = null; 8 9 Session session = null; 10 11 try { 12 13 factory = Tools.getSessionFactory(); 14 15 session = factory.openSession(); 16 17 tx = session.beginTransaction(); 18 19 User user = session.get(User.class, 7); 20 21 user.setPassword("5446546"); 22 23 tx.commit(); 24 25 } catch (Exception e) { 26 27 tx.rollback(); 28 29 } finally { 30 31 session.close(); 32 33 factory.close(); 34 35 } 36 37 }
Hibernate绑定Session:
在进行事务的处理的时候,要保证事务的正确的执行,那么我们需要保证进行事务处理的数据库连接对象是同一个链接对象。在以前可以使用Java提供的ThredLocal本地线程进行绑定,保证在事务处理的时候,使用的是同一个Connection对象。而在Hibernate中我们进行事务的处理,也必须要保证session对象是同一个Session。但是在Hibernate中我们不需要自己进行实现了,因为Hibernate已经帮我们全部封装好了,但是Hibernate使用的底层原理,也是用的ThreadLocal。
要在Hibernate中进行事务处理,那么就要使Session绑定本地线程,要绑定Session的话,那么我们就需要在Hibernate的核心配置文件中进行配置处理,然后在调用SessionFactory中的方法得到:
核心配置文件的配置:
<!-- 配置数据库的事务处理绑定到本地线程 -->
<property name="hibernate.current_session_context_class">thread</property>
调用Session方法进行使用:(要得到本地线程,那么必须先配置核心文件,否则得不到)
factory.getCurrentSession();
Hibernate的其他API
Query类查询所有记录:
使用Query类进行查询操作,我们需要些sql语句,但是需要些hql语句。
Hql:hibernate query language,hibernate提供的查询语句,这个hql语句和sql语句很相似
Hql和sql的区别:
使用sql操作的是表和表的字段
使用hql操作的是实体类和属性
Hql语句规范:form 实体类名称
使用Query查询的步骤:
先创建Query对象
通过Query类的对象调用Query类中的方法进行操作
代码:
1 public void testQueryClass() { 2 3 Transaction tx = null; 4 5 SessionFactory factory = null; 6 7 Session session = null; 8 9 try { 10 11 factory = Tools.getSessionFactory(); 12 13 session = factory.openSession(); 14 15 tx = session.beginTransaction(); 16 17 /** 18 19 * 第一步:创建Query对象 20 21 */ 22 23 Query query = session.createQuery("from User"); 24 25 List<User> users = query.list(); 26 27 System.out.println(users); 28 29 tx.commit(); 30 31 } catch (Exception e) { 32 33 tx.rollback(); 34 35 } finally { 36 37 session.close(); 38 39 factory.close(); 40 41 } 42 43 }
Criteria类查询所有记录:
使用Criteria类进行查询操作,不需要写查询语句,直接调用方法实现即可
使用步骤:
创建Criteria对象
调用对象里面的方法得到结果集
代码:
1 public void testCriteriaClass() { 2 3 Transaction tx = null; 4 5 SessionFactory factory = null; 6 7 Session session = null; 8 9 try { 10 11 factory = Tools.getSessionFactory(); 12 13 session = factory.openSession(); 14 15 tx = session.beginTransaction(); 16 17 /** 18 19 * 第一步:创建Criteria对象 20 21 */ 22 23 Criteria criteria = session.createCriteria(User.class); 24 25 /** 26 27 * 查询 28 29 */ 30 31 List<User> users = criteria.list(); 32 33 System.out.println(users); 34 35 tx.commit(); 36 37 } catch (Exception e) { 38 39 tx.rollback(); 40 41 } finally { 42 43 session.close(); 44 45 factory.close(); 46 47 } 48 49 }
SQLQuery类查询所有记录:
使用SQLQuery时候,调用底层的sql实现
实现步骤:
创建对象
调用对象的方法
代码:
public void testQueryClass() { Transaction tx = null; SessionFactory factory = null; Session session = null; try { factory = Tools.getSessionFactory(); session = factory.openSession(); tx = session.beginTransaction(); /** * 第一步:创建Query对象 */ Query query = session.createQuery("from User"); List<User> users = query.list(); System.out.println(users); tx.commit(); } catch (Exception e) { tx.rollback(); } finally { session.close(); factory.close(); } }