hibernate框架使用详解二
三、hibernate中的实体创建规则
3.1实体类创建的注意事项
- 持久化类提供无参数构造
- 成员变量私有,提供公有get/set方法访问,需要提供属性
- 持久化类中的属性,应尽量使用包装类型。包装类允许的数据范围更多,如int不能为null,而Integer允许为null
- 持久化类需要提供oid,与数据库中的主键列对应。数据库表没有主键的,不能使用hibernate框架
- 不能使用final修饰class。hibernate使用cglib代理生成代理对象,代理对象是继承被代理对象。如果被final修饰,将无法生成代理。
3.2主键类型
3.2.1自然主键(少见)
表的业务列中,有某业务列符合,并且具有不重复的特征时,可以作为主键使用。例如人员信息的身份证号或手机号。
3.2.2代理主键(常见)
表的业务列中没有不重复的特征时,创建一个没有业务意义的列作为主键。例如常用的id列
3.3主键生成策略
3.3.1代理主键
identity:主键自增.由数据库来维护主键值.录入时不需要指定主键。
sequence: Oracle中的主键生成策略。
increment(了解): 主键自增.由hibernate来维护.每次插入前会先查询表中id最大值.+1作为新主键值。开发过程中不用,效率低,并且存在并发安全性问题。
hilo(了解): 高低位算法.主键自增.由hibernate来维护.开发时不使用。
native:hilo+sequence+identity 自动三选一策略。开发中最常用。
uuid: 产生随机字符串作为主键. 主键类型必须为string 类型。
3.3.2自然主键
assigned:自然主键生成策略. hibernate不会管理主键值.由开发人员自己录入。
在实体对应的映射文件中,配置主键的生成策略
<id name="cust_id" column="cust_id">
<!-- generator:主键生成策略
identity:主键自增.由数据库来维护主键值,录入时不需要指定主键
increment:主键自增,由hibernate来维护,每次插入前会先查询表中ID最大值,+1作为主键值
开发过程中不用,效率低,并且存在并发安全性问题
sequence:Oracle中的主键生成策略
Hilo:高低位算法。主键自增,由hibernate来维护。开发时不使用。
native:hilo+sequence+identity 自动三选一策略
uuid:产生随机字符串作为主键,主键类型必须为string类型
assigned:自然主键生成策略。hibernate不会管理主键值,由开发人员自己录入
-->
<!-- <generator class="identity"></generator> -->
<!-- <generator class="increment"></generator> -->
<generator class="native"></generator>
</id>
四、hibernate中的对象状态
4.1对象的三种状态
- 瞬时状态:没有id,没有在session缓存中
- 持久化状态:有id,在session缓存中
- 游离|托管状态:有id,没有在session缓存中
@Test
//查看三种状态
public void fun1() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
Customer customer = new Customer(); // 没有id,没有与session关联 => 瞬时状态
customer.setCust_name("联想"); // 瞬时状态
session.save(customer); // 有id,与session有关联 => 持久化状态
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
@Test
//三种状态特点
//save方法:其实不能理解为保存,将瞬时状态转化为持久化状态
//主键自增:执行save方法时,为了将对象转化为持久化状态。必须生成id值,所以需要执行insert语句生成
//increment:执行save方法,为了生成id,会执行查询id最大值的sql语句。
public void fun2() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
Customer customer = new Customer(); // 没有id,没有与session关联 => 瞬时状态
customer.setCust_name("联想"); // 瞬时状态
session.save(customer); // 有id,与session有关联 => 持久化状态
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
@Test
//三种状态特点
//持久化状态特点:持久化状态对象的任何变化都会自动同步到数据库中
public void fun3() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
Customer customer = session.get(Customer.class, 1l); // 持久化状态对象
customer.setCust_name("华硕");
//session.update(customer); 不需要执行update,数据库的数据也已经发生了变化
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
4.2对象的三种状态转换图
五、hibernate中的一级缓存
缓存的作用:提高效率。
hibernate中的一级缓存也是为了提高操作数据库的效率。
目的:
- 提高查询效率
- 减少不必要的修改语句发送
六、hibernate中的事务
6.1事务
6.1.1事务特性
acid:原子性、一致性、隔离性、持久性
6.1.2事务并发问题
==1.脏读;2.不可重复读;3.幻|虚读 ==
6.1.3事务的隔离级别
读未提交 - - - 123
读已提交 - - - 23
可重复读 - - - 3 MySQL默认级别
串行化
6.2hibernate中指定事务的隔离级别
在hibernate的配置文件中,指定hibernate的隔离级别
<!-- 指定hibernate操作数据库时的隔离级别
#hibernate.connection.isolation 1|2|4|8
0001 1 读未提交
0010 2 读已提交
0100 4 可重复读
1000 8 串行化
-->
<property name="hibernate.connection.isolation">4</property>
6.3hibernate在项目中管理事务
业务开始之前打开事务,业务执行之后提交事务. 执行过程中出现异常.回滚事务。
在dao层操作数据库需要用到session对象。在service控制事务也是使用session对象完成。 我们要确保dao层和service层使用的使用同一个session对象。
在hibernate中,确保使用同一个session的问题,hibernate已经帮我们解决了.。我们开发人员只需要调用sf.getCurrentSession()方法即可获得与当前线程绑定的session对象。
注意1: 调用getCurrentSession方法必须配合主配置中的一段配置,也即在hibernate的配置文件中加入
<!-- 指定session与当前线程绑定 -->
<property name="hibernate.current_session_context_class">thread</property>
注意2:通过getCurrentSession方法获得的session对象.当事务提交时,session会自动关闭.不要手动调用close关闭.
实例:
七、hibernate中的批量查询语句
hibernate提供三种批量查询语句。
7.1HQL查询-hibernate Query Language(多表查询,但不复杂时使用)
Hibernate独家查询语言,属于面向对象的查询语言。
7.1.1基本查询
@Test
//基本查询
public void fun1() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//1>、书写HQL语句
String hql = "from Customer "; //查询所有customer对象
//2>、根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//3>、根据查询对象获得查询结果
List list = query.list(); //返回list结果
//query.uniqueResult(); //接收唯一的查询结果
System.out.println(list);
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
7.1.2条件查询
7.1.2.1基本条件查询
@Test
//条件查询
public void fun2() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//1>、书写HQL语句
String hql = "from Customer where cust_id = 1"; //查询所有customer对象
//2>、根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//3>、根据查询对象获得查询结果
Customer customer = (Customer) query.uniqueResult(); //接收唯一的查询结果
System.out.println(customer);
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
7.1.2.2问号占位符
@Test
//条件查询
//问号占位符
public void fun3() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//1>、书写HQL语句
String hql = "from Customer where cust_id = ?"; //查询所有customer对象
//2>、根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
query.setParameter(0, 1l);
//3>、根据查询对象获得查询结果
Customer customer = (Customer) query.uniqueResult(); //接收唯一的查询结果
System.out.println(customer);
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
7.1.2.3命名占位符
@Test
//条件查询
//命名占位符
public void fun4() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//1>、书写HQL语句
String hql = "from Customer where cust_id = :cust_id"; //查询所有customer对象
//2>、根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
query.setParameter("cust_id", 1l);
//3>、根据查询对象获得查询结果
Customer customer = (Customer) query.uniqueResult(); //接收唯一的查询结果
System.out.println(customer);
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
7.1.3分页查询
@Test
//分页查询
public void fun5() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//1>、书写HQL语句
String hql = "from Customer"; //查询所有customer对象
//2>、根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
//query.setParameter("cust_id", 1l);
//设置分页信息
query.setFirstResult(1);
query.setMaxResults(1);
//3>、根据查询对象获得查询结果
List list = query.list();
System.out.println(list);
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
7.2 Criteria查询(单表条件查询)
Hibernate自创的无语句面向对象查询
7.2.1基本查询
@Test
//基本查询
public void fun1() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
Criteria criteria = session.createCriteria(Customer.class); //查询所有的customer对象
List<Customer> list = criteria.list();
System.out.println(list);
//Customer customer = (Customer) criteria.uniqueResult();
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
7.2.2条件查询
@Test
//条件查询
// > gt
// >= ge
// < lt
// <= le
// == eq
// != ne
// in in
// between and betweem
// like like
// is not null isNotNull
// is null isNull
// or or
// and and
public void fun2() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class); //查询所有的customer对象
//添加查询参数
criteria.add(Restrictions.eq("cust_name", "联想"));
List<Customer> list = criteria.list();
System.out.println(list);
//Customer customer = (Customer) criteria.uniqueResult();
//System.out.println(customer);
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
7.2.3查询总条数
@Test
//查询总记录数
public void fun3() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class); //查询所有的customer对象
//设置查询的聚合函数 => 总行数
criteria.setProjection(Projections.rowCount());
//执行查询
Long count = (Long) criteria.uniqueResult();
System.out.println(count);
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
7.2.4分页查询
@Test
//分页查询
public void fun4() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class); //查询所有的customer对象
//设置分页信息
criteria.setFirstResult(0);
criteria.setMaxResults(2);
List<Customer> list = criteria.list();
System.out.println(list);
//Customer customer = (Customer) criteria.uniqueResult();
//System.out.println(customer);
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
7.3原生SQL查询(复杂的业务查询)
原生sql查询,就是正常的写SQL语句进行查询
7.3.1基本查询
@Test
//基本查询
public void fun1() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//1、书写sql语句
String sql = "select * from cst_customer";
//2、创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
//3、调用方法查询结果
List<Object[]> list = query.list();
//query.uniqueResult();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
@Test
//基本查询
public void fun2() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//1、书写sql语句
String sql = "select * from cst_customer";
//2、创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
//指定将结果封装到哪个对象中
query.addEntity(Customer.class);
//3、调用方法查询结果
List<Customer> list = query.list();
//query.uniqueResult();
System.out.println(list);
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
7.3.2条件查询
@Test
//条件查询
public void fun3() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//1、书写sql语句
String sql = "select * from cst_customer where cust_id = ?";
//2、创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
query.setParameter(0, 1l);
//指定将结果封装到哪个对象中
query.addEntity(Customer.class);
//3、调用方法查询结果
List<Customer> list = query.list();
//query.uniqueResult();
System.out.println(list);
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}
7.3.3分页查询
@Test
//分页查询
public void fun4() {
//1、获得session
Session session = HibernateUtils.openSession();
//2、控制事务
Transaction transaction = session.beginTransaction();
//3、执行操作
//-----------------------------
//1、书写sql语句
String sql = "select * from cst_customer limit ?,?";
//2、创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
query.setParameter(0, 0);
query.setParameter(1, 2);
//指定将结果封装到哪个对象中
query.addEntity(Customer.class);
//3、调用方法查询结果
List<Customer> list = query.list();
//query.uniqueResult();
System.out.println(list);
//-----------------------------
//4、提交事务,关闭资源
transaction.commit();
session.close(); // 有id,没有与session关联 => 游离|托管状态
}