1、实体类编写规则
1、 实体类里面属性私有的
2 、私有属性使用公开的set和get方法操作
3 、要求实体类有属性作为唯一值(一般使用id值)
4 、实体类属性建议不使用基本数据类型,使用基本数据类型对应的包装类
(1)八个基本数据类型对应的包装类
-int – Integer
-char—Character、
- 其他的都是首字母大写比如 double – Double
(2)比如表示学生的分数,假如 int score;
- 比如学生得了0分,int score = 0;
- 如果表示学生没有参加考试,int score = 0;不能准确表示学生是否参加考试
解决方法:使用包装类可以了, Integer score = 0,表示学生得了0分,
表示学生没有参加考试,Integer score = null; /*hibernate要求实体类有一个属性唯一的*/
private Integer uid;
private String username;
private String password;
private String address;
private Integer score;
2、Hibernate主键生成策略
1、hibernate要求实体类里面有一个属性作为唯一值,对应表主键,主键可以不同生成策略
2、hibernate主键生成策略有很多的值3 、在class属性里面有很多值
(1)native:根据使用的数据库帮选择哪个值,主键自增长
(2)uuid:之前web阶段写代码生成uuid值,hibernate帮我们生成uuid值
4 、演示生成策略值 uuid
(1)使用uuid生成策略,实体类id属性类型必须字符串类型
private String userName;
private String uid;
(2)配置部分写出uuid值
<!-- 2 配置实体类id和表id对应 hibernate要求实体类有一个属性唯一值 hibernate要求表有字段作为唯一值 -->
<!-- id标签 name属性:实体类里面id属性名称 column属性:生成的表字段名称 -->
<id name="uid" column="uid">
<!-- 设置数据库表id增长策略 native:生成表id值就是主键自动增长 uuid:随机生成不重复的16位字符 -->
<generator class="uuid"></generator>
</id>
配置后主键生成效果:
3、实体类操作
1、对实体类crud操作
(1)添加操作:调用session里面的save方法实现
@Test //添加功能
public void testSave() {
// 调用工具类得到 sessionFactory
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
// 获取session
Session session = sessionFactory.openSession();
// 开启事务
Transaction tr = session.beginTransaction();
//添加功能
User user = new User();
user.setAddress("china");
user.setPassword("123");
user.setScore(null);
user.setUsername("mick");
//调用session的save方法实现添加
session.save(user);
// 提交事务
tr.commit();
// 关闭
session.close();
sessionFactory.close();
}
@Test
// 根据id查询
public void testQueryByID() {
// 调用工具类得到 sessionFactory
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
// 获取session
Session session = sessionFactory.openSession();
// 开启事务
Transaction tr = session.beginTransaction();
//根据id查询
//调用session中的get方法
//第一个参数是实体类的class
//第二个参数是要查询的id
User user = session.get(User.class, 3);
// 提交事务
tr.commit();
// 关闭
session.close();
sessionFactory.close();
}
(2)修改操作
1、 首先查询,修改值
(1)根据id查询,返回对象
1、 修改id值为1的username值
2、使用session中的get得到对象
3、向返回的对象中设置值
4、调用session中的update
@Test
// 修改操作
public void testUpdateByID() {
// 调用工具类得到 sessionFactory
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
// 获取session
Session session = sessionFactory.openSession();
// 开启事务
Transaction tr = session.beginTransaction();
//修改操作
//修改id值为1的username值
//使用session中的get得到对象
//第一个参数是实体类的class
//第二个参数是要查询的id
User user = session.get(User.class, 1);
//向返回的对象中设置值
user.setUsername("lucy");
//调用session中的update
session.update(user);
// 提交事务
tr.commit();
// 关闭
session.close();
sessionFactory.close();
}
控制台输出hibernate语句为:
(3)删除操作
1、 删除id值为1的数据
2、使用session中的get得到对象
3、 使用session中的delete方法
@Test
// 删除操作
public void testDeleteByID() {
// 调用工具类得到 sessionFactory
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
// 获取session
Session session = sessionFactory.openSession();
// 开启事务
Transaction tr = session.beginTransaction();
// 删除操作
// 删除id值为1的数据
// 使用session中的get得到对象
// 第一个参数是实体类的class
// 第二个参数是要查询的id
User user = session.get(User.class, 1);
//使用session中的delete删除
session.delete(user);
// 提交事务
tr.commit();
// 关闭
session.close();
sessionFactory.close();
}
1 、调用session里面delete方法实现
4、实体类对象状态(概念)
1 、实体类状态有三种
(1)瞬时态:对象里面没有id值,对象与session没有关联
User user = new User();
user.setAddress("china");
user.setPassword("123");
user.setScore(null);
user.setUsername("mick");
(2)持久态:对象里面有id值,对象与session关联,hibernate在持久态中会自动更新数据库,这是由hibernate机制中的一级缓存默认打开造成的
User user = session.get(User.class, 3);
(3)托管态:对象有id值,对象与session没有关联
User user = new User();
user.setUid("1");
2 、演示操作实体类对象的方法(使用的是实体类对象状态)
(1)saveOrUpdate方法:实现添加、实现修改
实体类对象为瞬时态时,实体类对象的状态是瞬时态时,saveorupdate是添加:
@Test
// 瞬时态添加
public void testSaveOrUptateAppend() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tr = session.beginTransaction();
// 添加操作
// 实体类对象的状态是瞬时态时,saveorupdate是添加
User user = new User();
user.setUsername("jack");
user.setPassword("a123");
user.setAddress("朝鲜");
session.saveOrUpdate(user);
tr.commit();
session.close();
sessionFactory.close();
}
实体类对象为托管态时,实体类对象的状态是托管态时,saveorupdate是修改:
@Test
//托管态时,saveorupdate修改
public void testSaveOrUptateRemix() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tr = session.beginTransaction();
// 添加操作
// 实体类对象的状态是托管态时,saveorupdate是修改
User user = new User();
// 托管态
user.setUid(6);
user.setUsername("rose");
user.setPassword("a125");
user.setAddress("阿尔巴尼亚");
session.saveOrUpdate(user);
tr.commit();
session.close();
sessionFactory.close();
}
实体类对象为持久态时,实体类对象的状态是持久态时,saveorupdate是修改:
@Test
//实体类对象的状态是持久态时,saveorupdate是修改
public void testSaveOrUptate() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tr = session.beginTransaction();
// 添加操作
// 实体类对象的状态是持久态时,saveorupdate是修改
User user = session.get(User.class, 4);
user.setUsername("lilei");
session.saveOrUpdate(user);
tr.commit();
session.close();
sessionFactory.close();
}
5、Hibernate的一级缓存
1、什么是缓存
数据存到数据库里面,数据库本身是文件系统,使用流方式操作文件效率不是很高。
(1)把数据存到内存里面,不需要使用流方式,可以直接读取内存中数据
(2)把数据放到内存中,提供读取效率2、Hibernate缓存
1、hibernate框架中提供很多优化方式,hibernate的缓存就是一个优化方式
2、hibernate缓存特点:
第一类 hibernate的一级缓存
(1)hibernate的一级缓存默认打开的
(2)hibernate的一级缓存使用范围,是session范围,从session创建到session关闭范围
(3)hibernate的一级缓存中,存储数据必须持久态数据
第二类 hibernate的二级缓存
(1)目前已经不使用了,替代技术 redis
(2)二级缓存默认不是打开的,需要配置
(3)二级缓存的使用范围是sessionFactory范围
第三类 hibernate三级缓存
(1)指的是外置缓存中的查询缓存由于查询缓存依赖于class缓存,所以说三级缓存是基于二级缓存之上的
6、验证一级缓存的存在
1 验证方式
(1)首先根据uid=1查询,返回对象
(2)其次再根据uid=1查询,返回对象2、Hibernate一级缓存执行过程
![](https://i-blog.csdnimg.cn/blog_migrate/aa8697af1bd02e7c821b62eaf606840c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/af0b16e2fec936b61bbad5078eb7a646.png)
6、Hibernate事务操作
1 、什么是事务
事务是恢复和并发控制的基本单位
2 、事务特性
原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性
3、 不考虑隔离性产生问题
(1)脏读
(2)不可重复读
(3)虚读
4设置事务隔离级别
(1)mysql默认隔离级别 repeatable read7、Hibernate事务代码规范写法
1 、代码结构
try {
开启事务
提交事务
}catch() {
回滚事务
}finally {
关闭
}
标准写法:
package com.hibernate_stu.Untils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
static Configuration cfg = null;
static SessionFactory sessionFactory = null;
//静态代码块实现
static {
//加载核心配置文件
cfg = new Configuration();
cfg.configure();
sessionFactory = cfg.buildSessionFactory();
}
//提供返回与本地线程绑定的session
public static Session getSessionObject(){
return sessionFactory.getCurrentSession();
}
//提供方法返回sessionFactory
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void main(String[] args) {
}
}
再写标准实现代码:
package com.hibernate_stu.hibernatetest;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate_stu.Untils.HibernateUtils;
import com.hibernate_stu.entity.Customer;
import com.hibernate_stu.entity.LinkMan;
public class HibernateAdd {
@Test
public void hibernateAdd(){
SessionFactory factory = null;
Session session=null;
Transaction transaction = null;
try{
factory=HibernateUtils.getSessionFactory();
session=factory.openSession();
transaction=session.beginTransaction();
transaction.commit();
}catch(Exception e){
transaction.rollback();
e.printStackTrace();
}finally{
session.close();
factory.close();
}
}
}
8、Hibernate绑定session
1、session类似于jdbc的connection,与 ThreadLocal(本地线程)相似
2 、帮实现与本地线程绑定session
3 、获取与本地线程session
(1)在hibernate核心配置文件中配置(2)调用sessionFactory里面的方法得到
4、 获取与本地线程绑定session时候,关闭session报错,不需要手动关闭了
配置完的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 第一部分: 配置数据库信息 必须的 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day2</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">Huang123</property>
<!-- 第二部分: 配置hibernate信息 可选的 -->
<!-- 输出底层sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 输出底层sql语句格式 -->
<property name="hibernate.format_sql">true</property>
<!-- hibernate帮创建表,需要配置之后 update: 如果已经有表,更新,如果没有,创建 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置数据库方言 在mysql里面实现分页 关键字 limit,只能使用mysql里面 在oracle数据库,实现分页rownum 让hibernate框架识别不同数据库的自己特有的语句 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!--配置本地线程绑定session -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 第三部分: 把映射文件放到核心配置文件中 必须的 -->
<mapping resource="cn/itcast/entity/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
9、Hibernate的api使用
1、Query对象
1 、使用query对象,不需要写sql语句,但是写hql语句
(1)hql:hibernate query language,hibernate提供查询语言,这个hql语句和普通sql语句很相似
(2)hql和sql语句区别:
- 使用sql操作表和表字段
- 使用hql操作实体类和属性
2 、查询所有hql语句:
(1)格式:from实体类名称
3、Query对象使用
(1)创建Query对象
(2)调用query对象里面的方法得到结果
@Test
public void testQuery() {
// 使用Query不需要写Query语句,但是需要写hql语句
// hibernate query language
// 与普通sql很相似,区别是:使用普通sql操作的是数据库表与表里的字段,使用hql操作的是实体类与实体类属性
// 查询所有hql语句:from 实体类名称
// query对象使用:1.创建query对象 2.使用对象里的方法进行查询
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
// 演示query对象的使用
// 创建query对象
Query createQuery = session.createQuery("from User");
List<User> list = createQuery.list();
// 使用query对象得到里面的方法得到结果
for (User user : list) {
System.out.println(user);
}
transaction.commit();// 提交事务
} catch (Exception e) {
e.printStackTrace();
transaction.rollback();// 回滚
} finally {
session.close();
sessionFactory.close();
}
}
2、Criteria对象
1、 使用这个对象查询操作,但是使用这个对象时候,不需要写语句,直接调用方法实现
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();
// 演示Criteria对象的使用
// 创建Criteria对象
Criteria criteria = session.createCriteria(User.class);
List<User> list = criteria.list();
// 使用Criteria对象得到里面的方法得到结果
for (User user : list) {
System.out.println(user);
}
transaction.commit();// 提交事务
} catch (Exception e) {
e.printStackTrace();
transaction.rollback();// 回滚
} finally {
session.close();
sessionFactory.close();
}
}
3、SQLQuery对象
1、 使用hibernate时候,调用底层sql实现
2 、实现过程
(1)创建对象
(2)调用对象的方法得到结果
// 使用SQLQuery对象进行查询操作的时候,可以编写底层SQL语句进行查询
@Test
public void testCriteria() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
try {
sessionFactory = HibernateUtils.getSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
// 演示SQLQuery对象的使用
// 创建SQLQuery对象
SQLQuery sqlQuery = session.createSQLQuery("Select * from t_user");
// 默认返回的是数组
// List<Object[]> list = sqlQuery.list();
// //使用SQLQuery对象得到里面的方法得到结果
// for (Object[] object : list) {
// System.out.println(Arrays.toString(object));
// }
// 让其返回的每部分的是一个对象的形式
sqlQuery.addEntity(User.class);
// 使用SQLQuery对象得到里面的方法得到结果
List<User> list = sqlQuery.list();
for (User user : list) {
System.out.println(user);
}
transaction.commit();// 提交事务
} catch (Exception e) {
e.printStackTrace();
transaction.rollback();// 回滚
} finally {
session.close();
sessionFactory.close();
}
}
返回list集合每部分是数组:
返回list中每部分是对象形式
本章小结:
1、 实体类编写规则
2、 hibernate主键生成策略
(1)native
(2)uuid
3 、实体类操作
(1)crud操作
(2)实体类对象状态
4、 hibernate的一级缓存(默认打开)
5 、hibernate的事务操作
(1)事务代码规范写法
6、hibernate其他的api(查询)
(1)Query
(2)Criteria
(3)SQLQuery