1.实体类的规则
(1)属性私有
(2)公开的get,set方法
(3)实体类属性作为唯一值(id)
(4)属性不使用基本数据类型,使用对应的包装类。
例:a.八个基本数据类型对应的包装类
- int – Integer
- char—Character、
- 其他的都是首字母大写 比如 double – Double
b.比如 表示学生的分数,假如 int score;
- 比如学生得了0分 ,int score = 0;
- 如果学生没有参加考试,int score = 0;不能准确表示学生是否参加考试
l 解决:使用包装类可以了, Integer score = 0,表示学生得了0分,
表示学生没有参加考试,Integer score = null;
2.主键生成策略
(1)hibernate实体类属性作为唯一值,对应表的主键,主键有不同的生成策略。
(2)hibernate主键生成策略有很多的值
<!-- 设置id增长策略 native:生成表id值就是主键自动自增 -->
<generator class="native"></generator>
(3)在class属性里面有很多值(如上表)
native: 根据使用的数据库帮选择哪个值:
`uid` varchar(255) NOT NULL AUTO_INCREMENT,
uuid:hibernate帮我们生成uuid值
(4) 演示生成策略值 uuid
使用uuid生成策略,实体类id属性类型 必须 字符串类型:private String uid;
配置部分写出uuid值:<generator class="uuid"></generator>
3.对实体类crud操作
(1)添加操作
调用session里面的save方法实现
User user = new User();
user.setUsername("111");
user.setPassword("111");
user.setAddress("111");
session.save(user);
(2)查询操作
调用session里面的get方法实现
//第一个参数:实体类的class
//第二个参数:id值
User user = session.get(User.class, 1);
(3)修改操作
// 根据id查询
User user = session.get(User.class, 2);
user.setUsername("22");
//调用session的方法update修改
//session.update(user);
session.saveOrUpdate(user);
(4)删除操作
调用session里面delete方法实现
User user = session.get(User.class, 2);
session.delete(user);
4.实体类对象状态(概念)
实体类状态有三种
(1)瞬时态:对象里面没有id值,对象与session没有关联
User user = new User();
user.setUsername("111");
user.setPassword("111");
user.setAddress("111");
(2)持久态:对象里面有id值,对象与session关联
User user = session.get(User.class, 1);
(3)托管态:对象有id值,对象与session没有关联
User user = new User();
user.setUid(1);
演示操作实体类对象的方法
(1)saveOrUpdate方法:实现添加、实现修改
// 添加操作(瞬时态)
User user = new User();
user.setUsername("11");
user.setPassword("11");
user.setAddress("11");
session.saveOrUpdate(user);
// 修改操作(持久态)
User user = new User();
user.setUid(2);
user.setUsername("22");
user.setPassword("22");
user.setAddress("22");
session.saveOrUpdate(user);
// 修改操作(托管态)
User user = session.get(User.class, 3);
user.setUsername("33");
session.saveOrUpdate(user);
5.Hibernate的一级缓存
什么是缓存
-> 数据存到数据库里,数据库本身是文件系统,使用流方式操作文件效率不高。
(1)把数据存到内存里面,不需要使用流方式,可以直接读取内存中数据
(2)把数据放到内存中,提供读取效率
Hibernate缓存
-> hibernate框架中提供很多优化方式,hibernate的缓存就是一个优化方式
->hibernate缓存特点:
第一类 hibernate的一级缓存
(1)hibernate的一级缓存默认打开的
(2)hibernate的一级缓存使用范围,是session范围,从session创建到session关闭
范围
(3)hibernate的一级缓存中,存储数据必须 持久态数据
第二类 hibernate的二级缓存
(1)目前已经不使用了,替代技术 redis
(2)二级缓存默认不是打开的,需要配置
(3)二级缓存使用范围,是sessionFactory范围
验证一级缓存存在
->验证方式
(1)首先根据uid=1查询,返回对象
(2)其次再根据uid=1查询,返回对象
第一步执行get方法之后,发送sql语句查询数据库
第二个执行get方法之后,没有发送sql语句,查询一级缓存内容
//1 根据uid=1查询
// 执行第一个get方法是否查询数据库,是否发送sql语句
User user1 = session.get(User.class, 1);
System.out.println(user1);
//2 在 根据uid=2查询
// 执行第二个get方法是否查询数据库,是否发送sql语句
User user2 = session.get(User.class, 1);
System.out.println(user2);
->结果:
Hibernate:
select
user0_.uid as uid1_0_0_,
user0_.username as username2_0_0_,
user0_.password as password3_0_0_,
user0_.address as address4_0_0_
from
t_user user0_
where
user0_.uid=?
->Hibernate一级缓存执行过程
Hibernate一级缓存特性
-> 持久态自动更新数据库
-> 执行过程(了解)
User user = session.get(User.class, 2);
返回的持久化对象,放到一级缓存以及快照区(副本),
user.setUsername("111");
修改以及缓存区内容,但是不会修改快照区的内容。
session.update(user);
第二次不需要执行update方法也能完成更新。
tx.commit();
提交事务时,比较一级缓存和快照区的内容是否相同,不同则把一级缓存的数据
修改到数据库。
Hibernate事务操作
->事务相关概念
1 什么是事务
逻辑上的一组的操作,组成这组操作的各个单元,要么一起成功,要么一起失败。
2 事务特性
3 不考虑隔离性产生问题
4 设置事务隔离级别
(1)mysql默认隔离级别 repeatable read
->Hibernate事务代码规范写法
1 代码结构
try {
开启事务
提交事务
}catch() {
回滚事务
}finally {
关闭
}
@Test
public void testTx() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
// 开启事务
tx = session.beginTransaction();
// 添加
User user = new User();
user.setUsername("小马");
user.setPassword("250");
user.setAddress("美国");
session.save(user);
int i = 10 / 0;
// 提交事务
tx.commit();
} catch (Exception e) {
e.printStackTrace();
// 回滚事务
tx.rollback();
} finally {
// 关闭操作
session.close();
sessionFactory.close();
}
}
->Hibernate绑定session
1 session类似于jdbc的connection
2 实现与本地线程绑定session
3 获取与本地线程session
(1)在hibernate核心配置文件中配置
<property name="hibernate.current_session_context_class">thread</property>
(2)调用sessionFactory里面的方法得到
//提供返回与本地线程帮的session的方法
public static Session getSessionobject() {
return sessionFactory.getCurrentSession();
}
4 获取与本地线程绑定session时候,关闭session报错,不需要手动关闭了
->Hibernate的api使用
Query对象
1 使用query对象,不需要写sql语句,但是写hql语句
(1)hql:hibernate query language
(2)hql和sql语句区别:
- 使用sql操作表和表字段
- 使用hql操作实体类和属性
2 查询所有hql语句:
(1)from 实体类名称
3 Query对象使用
(1)创建Query对象
(2)调用query对象里面的方法得到结果
//1 创建Query对象
Query query = session.createQuery("from User");
//2 调用query对象里面的方法得到结果
List<User> list = query.list();
//遍历list集合四种: 普通for、增强for、迭代器、list迭代器
//遍历set集合两种:增强for、迭代器
//遍历map集合两种:得到所有key,根据key得到value; 得到key-value关系
for (User user : list) {
System.out.println(user);
}
Criteria对象
1 使用这个对象查询操作,但是使用这个对象时候,不需要写语句,直接调用方法实现
2 实现过程
(1)创建criteria对象
(2)调用对象里面的方法得到结果
//1 创建criteria对象
//方法里面参数是实体类class
Criteria criteria = session.createCriteria(User.class);
//2 调用方法得到结果
List<User> list = criteria.list();
SQLQuery对象
1 使用hibernate时候,调用底层sql实现
2 实现过程
(1)创建对象
(2)调用对象的方法得到结果
SQLQuery sqlQuery = session.createSQLQuery("select * from t_user");
List<Object[]> list = sqlQuery.list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
返回list集合每部分是数组
返回list中每部分是对象形式
SQLQuery sqlQuery = session.createSQLQuery("select * from t_user");
//返回的list中每部分是对象形式
sqlQuery.addEntity(User.class);
//调用sqlQuery里面的方法
List<User> list = sqlQuery.list();