1 实体类编写规则
- 实体类里面属性私有的
- 私有属性使用公开的set和get方法操作
- 要求实体类有属性作为唯一值(一般使用id值)
- 实体类属性建议不使用基本数据类型,使用基本数据类型对应的包装类
(1)八个基本数据类型对应的包装类
(2)比如 表示学生的分数,假如 int score;
比如学生得了0分 ,int score = 0; 如果表示学生没有参加考试,int score = 0;不能准确表示学生是否参加考试,解决:使用包装类可以了, Integer score = 0,表示学生得了0分, 表示学生没有参加考试,Integer score = null;
2hibernate主键生成策略
hibernate要求实体类里面有一个属性作为唯一值,对应表主键,主键可以不同生成策略,hibernate主键生成策略有很多的值,如下:
<id name="uid" column="uid">
<!-- 设置数据库表id增长策略
native:生成表id主键自动增长
-->
<generator class="native"></generator>
</id>
主键类型:自然主键和代理主键
- 自然主键:把具有业务含义的字段作为主键
- 代理主键:把不具有业务含义的字段作为主键
Hibernate的主键生成策略如下:
其中最常用的就是native和uuid
3 实体类操作
3.1 添加操作
User user = new User();
user.setUsername("张三");
user.setPassword("123");
user.setAddress("哥伦比亚共和国");
// 调用sesion中的方法实现添加
session.save(user);
// //这个会调用mysql底层的insert语句,但是如果当你先查询一个数据,修改以后,
//然后再调用save方法,它执行的是update语句,不是insert语句
3.2 根据id查询
// 4 根据id查询
// 调用session里面的get方法,第一参数:实体类的字节码对象,第二个参数:id值
User user = session.get(User.class, 1);
System.out.println(user);
//这个会调用mysql底层的select语句
3.3 修改操作
// 4 修改操作
// 先查询,然后再进行修改
// 调用session里面的get方法,第一参数:实体类的字节码对象,第二个参数:id值
User user = session.get(User.class, 1);
user.setUsername("王张飞");
session.update(user);
//这个会调用mysql底层的update语句
3.4 删除操作
有两种方式,第一种是先根据id查询出来,然后再调用session中的delete方法,第二种方法是新建一个对象,然后设置它的id值,然后再进行删除,一般建议第一种。
// 4 删除操作
// 第一种根据id查询对象
// User user = session.get(User.class, 1);
// session.delete(user);
// 第二种新建一个user对象
User user = new User();
user.setUid(2);
session.delete(user);
//该方法会调用底层的delete方法
3.5 实体类对象状态
实体类状态有三种:
- 瞬时态:对象里面没有id值,对象与session没有关联
也就是我们新建一个对象,然后准备插入到数据库中的时候。 - 持久态:对象里面有id值,对象与session关联
对应我们通过id值从数据库里查询到的数据 - 托管态: 对象里面有id值,对象与session没有关联
3.6 SaveOrUpdate
该方法既能实现添加,也能实现修改
User user = new User();
user.setUid(3);
user.setAddress("美国");
user.setPassword("123");
user.setUsername("破马张飞");
session.saveOrUpdate(user);
上面这段代码它实现的是修改操作,因为User对象对应的状态是托管态
User user = new User();
user.setAddress("美国1");
user.setPassword("1231");
user.setUsername("破马张飞1");
session.saveOrUpdate(user);
这段代码实现的是添加操作,因为User对象对应的状态是瞬时态
User user = session.get(User.class, 4);
user.setUsername("sssss");
session.saveOrUpdate(user);
这段代码对应的是修改操作,User对象对应的状态是持久态
4Hibernate缓存
4.1Hibernate的一级缓存
- hibernate的一级缓存默认是打开的
- hibernate的一级缓存使用范围是session范围,从session创建语句开始,到session关闭结束
- hibernate的一级缓存中存储数据必须是持久态的
4.2Hibernate的二级缓存
- 目前已经不使用了,替代技术redis
- 二级缓存默认不是打开的,需要配置
- 二级缓存的使用范围是SessionFactory范围
4.3 验证一级缓存存在
验证方式,首先根据uid=1查询,返回对象,然后再根据uid=1查询,返回对象,当第二次再进行查询的时候,它会先向缓存中查询,没有的话再向数据库里面查
User user = session.get(User.class, 4);
System.out.println(user);
User user1 = session.get(User.class, 4);
System.out.println(user1);
4.4 一级缓存特性
持久态自动更新数据库,也就是说当我们从数据库查询到数据以后,如果修改了里面的内容,在一级缓存中它会自动提交修改的。
Transaction tx = session.beginTransaction();
User user = session.get(User.class, 4);
user.setAddress("33333");
tx.commit();
上面的语句没有调用update方法,但是当提交事务的时候,它依然会执行update语句
5 Hibernate事务
事务代码的规范写法
1 代码结构
try {
开启事务
提交事务
}catch() {
回滚事务
}finally {
关闭
}
具体的示例代码:
public void testTX() {
SessionFactory sessionFactory = null;
Session session = null;
// 3 开启事务
Transaction tx = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
tx = session.beginTransaction();
User user = new User();
user.setUsername("小马");
user.setPassword("sdgag");
user.setAddress("非洲");
session.save(user);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
6 Hibernate绑定session
其底层是使用ThreadLocal来实现。
Hibernate的内部已经将这个事情做完了。我们只需要完成一段配置即可。
Hibernate5中自身提供了三种管理 Session对象的方法
- Session对象的生命周期与本地线程绑定
- Session对象的生命周期与JTA事务绑定
- Hibernate委托程序管理 Session对象的生命周期
在 Hibernate的配置文件中, hibernate.current_session_context_class 属性用于指定 Session管理
方式,可选值包括
- thread: Session对象的生命周期与木地线程绑定
- jia: Session对象的生命周期与JTA事务邦定
- managed: Hibernate委托程序来管理 Session对象的生命周期
- 在hibernate核心配置文件中配置
<property name=" hibernate.current_session_context_class">thread</property>
- 调用sessionFactory里面的方法得到
// 提供返回与本地线程帮的session的方法
public static Session getSessionobject() {
return sessionFactory.getCurrentSession();
}
PS: 获取与本地线程绑定session时候,关闭session报错,不需要手动关闭了
7 Hibernate API
今天实现的功能是查询所有的记录
7.1 Query对象
- 使用query对象,不需要写sql语句,但是写hql语句
- hql:hibernate query language,hibernate提供查询语言,这个hql语句和普通sql语句很相似
- hql和sql语句区别:
- 使用sql操作表和表字段
- 使用hql操作实体类和属性
2 查询所有hql语句:
(1)from 实体类名称
3 Query对象使用
(1)创建Query对象
(2)调用query对象里面的方法得到结果
Query query = session.createQuery("from User");
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
7.2 Criteria 对象
- 使用这个对象查询操作,但是使用这个对象时候,不需要写语句,直接调用方法实现,
- 实现过程
(1)创建criteria对象
(2)调用对象里面的方法得到结果
Criteria criteria = session.createCriteria(User.class);
List<User> list = criteria.list();
for (User user : list) {
System.out.println(user);
}
7.3 SQLQuery对象
- 使用hibernate时候,调用底层sql实现
- 实现过程
(1)创建对象
(2)调用对象的方法得到结果
SQLQuery sqlQuery = session.createSQLQuery("select * from t_user");
sqlQuery.addEntity(User.class);
List<User> list = sqlQuery.list();
for (User user : list) {
System.out.println(user);
}
sqlQuery.addEntity(User.class);使用来设置sqlQuery返回的数据,用User来装,如果没有这一句,它返回的是数组