实体类编写规则
1、 实体类里的属性必须为私有
2、 私有属性使用公开的get、set方法
3、 要求实体类有一个属性作为唯一值(类似于主键)
4、 实体类属性建议不使用基本数据类型,建议使用基本数据类型对应的包装类 (如0与null的问题)
Hibernate主键生成策略
1、 hibernate要求实体类里面有一个属性作为唯一值,对应表中的主键,主键可以有不同的生成策略。
2、 hibernate主键生成策略有很多值
<id name="uid" column="uid">
<!-- 设置数据库id增长策略
native:生成表的id值就是主键自动增长
-->
<generator class="native"></generator>
</id>
3、 在class属性中有以下值
实体类操作
crud操作
添加
User user = new User();
user.setUsername("bpf");
user.setPassword("233");
user.setAddress("shanxi");
// 调用session方法添加
session.save(user);
根据ID查询
调用session里面的get方法实现
User user = session.get(User.class, 2);
System.out.println(user);
修改
首先查询,然后修改
// 修改uid=2记录的username值
User user = session.get(User.class, 2);
user.setUsername("王大力");
session.update(user);
删除
// 删除uid=2记录的username值
User user = session.get(User.class, 2);
session.delete(user);
实体类对象的状态
1、 实体类状态有三种
(1) 瞬时态:对象里面没有id值,对象与session没有关联
// 瞬时态
// User user = new User();
// user.setUsername("jack");
// user.setPassword("123");
// user.setAddress("japan");
(2) 持久态:对象里面有id值,对象与session有关联
User user = session.get(User.class, 5);
(3) 托管态:对象有id值,但与session没有关系
// 托管态
// User user = new User();
// user.setUid(2);
// user.setUsername("rose");
// user.setPassword("666");
// user.setAddress("usa");
saveOrUpdate方法:
// 实体类对象状态是瞬时态,做的是添加操作
// 实体类对象状态是托管态或持久态时,做的是修改操作
session.saveOrUpdate(user);
Hibernate一级缓存
Hibernate缓存
1、 Hibernate框架中提供了很多优化方式,hibernate的缓存就是一个优化方式
2、 Hibernate缓存特点:
第一类:hibernate的一级缓存
(1) 默认打开
(2) 使用范围是session的范围(从创建到关闭)
(3) 存储的数据必须是持久态数据
第二类:hibernate的二级缓存
(1) 目前已经不使用了,替代技术:redis
(2) 二级缓存默认不是打开的,需要配置
(3) 使用范围:整个项目范围sessionFactory范围
验证一级缓存的存在
1、 验证方式
(1) 根据uid = 1进行查询,返回对象
(2) 再根据uid=1再进行查询,返回对象
第一次执行get方法后,发送sql语句查询数据库
第二次执行get方法后,没有发送sql语句,而是使用一级缓存中的内容
一级缓存的执行过程
1、 首先查询一级缓存,一级缓存中没有数据,然后查询数据库,返回持久态对象
2、 将返回的持久态对象放入一级缓存中(存的不是整个对象,而是其中的值)
3、 再次查询时,发现一级缓存中存在要查询的数据,直接返回(将值组成新的对象)
一级缓存特性
1、 持久态自动更新数据库
2、 执行原理(了解)
创建session时出现一级缓存,同时出现对应的一个快照区(副本)
A、 查询数据库返回的持久态对象会放入一级缓存和快照区内
B、 更新持久态对象里的值时同时会修改一级缓存中的内容,但是不会修改对应的快照区的内容
C、 提交事务时候,会比较一级缓存和对应快照区的内容是否相同。不相同会把一级缓存的内容更新到数据库,如果相同就不会更新。
Hibernate事务操作
事务相关概念
hibernate事务代码规范
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
//相关事务操作
transaction.commit();
} catch (Exception e) {
transaction.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
Hibernate绑定session
1、 hibernate实现了与本地线程绑定session
2、 为何要进行绑定(两种方式对比)
openSession():
- 总是创建一个新的session对象
- 你需要去明确的关闭session对象
- 在单线程环境它比getCurrentSession()更慢
- 你也不需要去配置任何属性,你就能够使用这个方法
getCurrentSession():
- 如果session不存在,它将创建一个新的session,否则在当前hibernate环境中使用同一个session
- 你不需要去关闭session对象,它将自动被hibernate内部机制关闭
- 在单线程环境它比opensession更快
- 你需要去配置中附加hibernate.current_session_context_class这个属性,才能够调用getCurrentSession()方法否则将会抛出异常
3、 获取与本地线程绑定的session
(1) 在hibernate核心配置文件中配置
<!--绑定session到本地线程 -->
<property name="hibernate.current_session_context_class">thread</property>
(2) 调用sessionFactory里面的方法得到
// 返回与本地线程绑定的session方法
public static Session getSessionObject() {
return sessionFactory.getCurrentSession();
}
3、 不需要手动关闭session
Hibernate的api的使用
Query对象
1、 使用query对象,不需要写sql语句,但是写hql语句
(1) Hibernate query language,hibernate提供的查询语言
(2)hql和sql语句的区别:
使用sql操作的是表和字段
使用hql操作的是实体类和属性
2、 查询所有hql语句
(1) from实体类名称
3、 Query对象的使用
(1) 创建Query对象
(2) 调用方法得到结果
// 使用query对象
@Test
public void testQuery() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
// 1.创建Query对象
Query<User> query = session.createQuery("from User", User.class);
// 2.调用方法得到结果
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
transaction.commit();
} catch (Exception e) {
transaction.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
Criteria对象
1、 使用这个对象也可以查询,但是使用这个对象不需要写hql语句
2、 实现过程
(1) 创建criteria对象
(2) 调用方法得到结果
// 使用criteria对象
@Test
public void testCriteria() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
// 1.创建Query对象
Criteria criteria = session.createCriteria(User.class);
// 2.调用方法得到结果
List<User> list = criteria.list();
for (User user : list) {
System.out.println(user);
}
transaction.commit();
} catch (Exception e) {
transaction.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
SQLQuery对象
1、 使用hibernate时,调用底层sql语句
2、 返回list集合每部分是数组
3、 可以将数组改为对象
@Test
public void testSQLQuery() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
// 创建SQLQuery对象
// SQLQuery sqlQuery = session.createSQLQuery("select * from t_user");
// 调用方法(默认返回list中的每部分是数组)
// List<Object[]> list = sqlQuery.list();
// for (Object[] objects : list) {
// System.out.println(Arrays.toString(objects));
// }
// 可以改为对象
// sqlQuery.addEntity(User.class);
// List<User> list = sqlQuery.list();
//List<User> list = session.createSQLQuery("select * from t_user").addEntity(User.class).list();
//for (User user : list) {
//System.out.println(user);
//}
transaction.commit();
} catch (Exception e) {
transaction.rollback();
} finally {
session.close();
sessionFactory.close();
}
}