hibernate学习笔记(二)

本文深入讲解Hibernate ORM框架的实体规则、实体状态、事务管理及查询操作,包括实体类创建规范、主键策略、HQL与Criteria查询技巧,帮助读者掌握Hibernate核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、hibernate中的实体规则

1.1 实体类创建的规则

1.2 主键类型

1.3 主键生成策略

二、hibernate中的实体状态

2.1 三种状态

2.2 三种状态的转换图

2.3 hibernate中的一级缓存

三、hibernate中的事务

3.1 设置隔离级别

3.2 如何管理事务

四、hibernate中的查询操作

4.1 HQL查询

4.2 Criteria查询

4.3 原生Sql查询

五、总结


一、hibernate中的实体规则

1.1 实体类创建的规则

1.持久化类要有无参构造函数,方便框架new。

2.成员变量私有,提供get/set方法访问。

3.持久化类中的属性尽量使用包装类型,避免数据库字段有可为NULL的情况。

4.持久化类需要提供id属性,对应数据库的主键。

5.持久化类不能用final修饰,因为hibernate是用cglib来生成对象的,代理对象是继承被代理的对象。

1.2 主键类型

1.2.1 自然主键(逻辑主键)

表的业务中,某些业务字段具有不重复且唯一的特性,比如手机号、身份证等就可以作为主键。

1.2.2 代理主键(物理主键)

表的业务中,没有不重复且唯一的特性,我们就用一个没有业务意义的列,比如id属性来作为主键。

1.3 主键生成策略

1.3.1 代理主键

数据库自动生成,不用手动去管理

sequence:oracle中的主键生成策略。

increment:主键自增,有hibernate来维护,每次插入前查询表中id最大值,作+1操作插入。

hilo:高低位算法,由hibernate来维护,开发时不适用。

native:hilo+sequence+identity(自增主键) 自动三选一。

uuid:随机产生的不重复的字符串,主键类型必须为string。

1.3.2 自然主键

自然主键由开发人员手动录入,hibernate不会管理。

二、hibernate中的实体状态

2.1 三种状态

2.1.1 瞬时状态

没有id,没有在session缓存中。

2.1.2 持久化状态

有id,在session缓存中,当事务提交时,hibernate自动提交到数据库。

2.1.3 游离(托管状态)

有id,没有在session缓存中。

2.2 三种状态的转换图

和EntityFramework中的attach和detach一样额,是否被上线文接管中。

2.3 hibernate中的一级缓存

2.3.1 缓存的原理1

2.3.2 缓存的原理2(快照)

使用快照可减少不必要的修改语句的发送

大致和EF的原理都是一样的。

三、hibernate中的事务

3.1 设置隔离级别

                                                                                      
指定hibernate的事务隔离级别                                                                         
0001  1  读未提交(可以去读未提交的数据,这样肯定会乱 所以脏读、虚读、不可重复读都解决不了)                                        
0010  2  读已提交 (隔离到保证读到的数据是已提交的数据,解决了脏读问题)                                                  
0100  4  可重复读 (mysql默认级别)(隔离到保证可以重复读取数据而不出错,解决了脏读和虚读的问题)                                   
1000  8  串行化(解决的所有问题,排队方式访问数据库)                                                            
                                                                                   
<property name="hibernate.connection.isolation">4</property>                               
                                                                                           

3.2 如何管理事务

一般的,我们是在业务层来手动控制事务。

业务之前打开事务,业务之后提交事务,出现异常,回滚事务。

在dao层和service层都会操作到数据库,我们要保证用的是同一个session对象完成,这样才能确保到事务的控制的一致性。我们使用sessionFactory.getCurrentSession来获取与当前线程绑定的session对象。这里需要配置一下:

<!-- 指定session与当前线程绑定 -->                                                  
<property name="hibernate.current_session_context_class">thread</property> 

在项目中可以这么使用:

 

四、hibernate中的查询操作

4.1 HQL查询

HQL全称为Hibernate Query Language,是hibernate独家设计的查询语言,属于面向对象的查询语言,在多表查询但是不复杂的时候常用。

4.1.1 基本查询

@Test                                                                                    
public void testHql(){                                                                   
	Session session = HibernateUtils.getCurrentSession();                                
	Transaction tx = session.beginTransaction();                                         
	//创建hql语句,hql的特点时不含任何和数据库相关的语句、关键字,里边只有面向对象的类名啥的                                     
	String hql = "from Customer";                                                        
	//根据hql创建hql的查询对象,内部自动编译为sql语句                                                       
	Query query = session.createQuery(hql);                                              
	                                                                                     
	List<Customer> list = query.list();                                                  
	                                                                                     
	//关闭资源                                                                               
	System.out.println(list);                                                            
	tx.commit();                                                                         
}                                                                                        

4.2.2 条件查询

占位符方式:

@Test                                                                                   
public void testHql1(){                                                                 
	Session session = HibernateUtils.getCurrentSession();                               
	Transaction tx = session.beginTransaction();                                        
	//创建hql语句,hql的特点时不含任何和数据库相关的语句、关键字,里边只有面向对象的类名啥的                                    
	String hql = "from Customer where id = ?";                                          
	//根据hql创建hql的查询对象,内部自动编译为sql语句                                                      
	Query query = session.createQuery(hql);                                             
	                                                                                    
	//设置参数                                                                              
	query.setParameter(0, 3);                                                           
	List<Customer> list = query.list();                                                 
	                                                                                    
	//关闭资源                                                                              
	System.out.println(list);                                                           
	tx.commit();                                                                        
}                                                                                       

命名占位符:

@Test                                                                                   
public void testHql2(){                                                                 
	Session session = HibernateUtils.getCurrentSession();                               
	Transaction tx = session.beginTransaction();                                        
	//创建hql语句,hql的特点时不含任何和数据库相关的语句、关键字,里边只有面向对象的类名啥的                                    
	String hql = "from Customer where id = :id";                                        
	//根据hql创建hql的查询对象,内部自动编译为sql语句                                                      
	Query query = session.createQuery(hql);                                             
	                                                                                    
	//设置参数                                                                              
	query.setParameter("id", 2);                                                        
	List<Customer> list = query.list();                                                 
	                                                                                    
	//关闭资源                                                                              
	System.out.println(list);                                                           
	tx.commit();                                                                        
}                                                                                       

分页查询:

@Test                                                                                   
public void testHql3(){                                                                 
	Session session = HibernateUtils.getCurrentSession();                               
	Transaction tx = session.beginTransaction();                                        
	//创建hql语句,hql的特点时不含任何和数据库相关的语句、关键字,里边只有面向对象的类名啥的                                    
	String hql = "from Customer";                                                       
	//根据hql创建hql的查询对象,内部自动编译为sql语句                                                      
	Query query = session.createQuery(hql);                                             
	                                                                                    
	int page = 1,size = 2;                                                              
	//设置参数limit ?,?                                                                     
	query.setFirstResult((page-1)*size);                                                
	query.setMaxResults(size);                                                          
	List<Customer> list = query.list();                                                 
	                                                                                    
	//关闭资源                                                                              
	System.out.println(list);                                                           
	tx.commit();                                                                        
}                                                                                       

4.2 Criteria查询

Criteria是hibernate自创的面向对象的无语局的查询,适合单表查询。

4.2.1 基本查询

@Test                                                            
public void testCriteria(){                                      
	Session session = HibernateUtils.getCurrentSession();        
	Transaction tx = session.beginTransaction();                 
	//创建和Customer类相关的Criteria(标准,条件)对象                           
	Criteria query = session.createCriteria(Customer.class);     
	List<Customer> list = query.list();                          
	                                                             
	//关闭资源                                                       
	System.out.println(list);                                    
	tx.commit();                                                 
}                                                                

4.2.2 条件查询

@Test                                                         
public void testCriteria1(){                                  
	Session session = HibernateUtils.getCurrentSession();     
	Transaction tx = session.beginTransaction();              
	//创建和Customer类相关的Criteria(标准,条件)对象                        
	Criteria query = session.createCriteria(Customer.class);  
	//设置条件表达式                                                 
	query.add(Restrictions.eq("id", 2));                      
	List<Customer> list = query.list();                       
	                                                          
	//关闭资源                                                    
	System.out.println(list);                                 
	tx.commit();                                              
}                                                             

Restrictions.eq("id", 2) 相当于c#中的Expression一样,这里会生成一个表达式树,然后根据表达式树生成sql。类似的还有

         > 				gt
	 >=				ge
	 <				lt
	 <=				le
	 ==				eq
	 !=				ne
	 in				in
	 between and		      between
	 like 			      like
	 is not null 		      isNotNull
	 is null		      isNull
	 or				or
	 and				and

4.2.3 分页查询

@Test                                                         
public void testCriteria3(){                                  
	Session session = HibernateUtils.getCurrentSession();     
	Transaction tx = session.beginTransaction();              
	//创建和Customer类相关的Criteria(标准,条件)对象                        
	Criteria query = session.createCriteria(Customer.class);  
	int page = 1,size = 2;                                    
	query.setFirstResult((page-1)*size);                      
	query.setMaxResults(size);                                
	List<Customer> list = query.list();                       
	                                                          
	//关闭资源                                                    
	System.out.println(list);                                 
	tx.commit();                                              
}                                                             

4.2.4 设置查询记录总数

@Test                                                        
public void testCriteria4(){                                 
	Session session = HibernateUtils.getCurrentSession();    
	Transaction tx = session.beginTransaction();             
	//创建和Customer类相关的Criteria(标准,条件)对象                       
	Criteria query = session.createCriteria(Customer.class); 
                                                             
	//设置要查询的聚合函数或者sql语句                                      
	query.setProjection(Projections.rowCount());             
	                                                         
	Long count = (Long)query.uniqueResult();                 
	                                                         
	//关闭资源                                                   
	System.out.println(count);                               
	tx.commit();                                             
}                                                            

4.3 原生Sql查询

我们可以写原生的sql查询,hibernate帮我们去封装成对象。

4.3.1 基本查询

@Test                                                         
public void testSql(){                                        
	Session session = HibernateUtils.getCurrentSession();     
	Transaction tx = session.beginTransaction();              
	                                                          
	String sql = "select * from customer";                    
	//创建一个sqlquery查询对象                                        
	SQLQuery query = session.createSQLQuery(sql);             
	//设置映射的实体类                                                
	query.addEntity(Customer.class);                          
	                                                          
	List<Customer> list = query.list();                       
	//关闭资源                                                    
	System.out.println(list);                                 
	tx.commit();                                              
}                                                             

4.3.2 条件查询

@Test                                                       
public void testSql1(){                                     
	Session session = HibernateUtils.getCurrentSession();   
	Transaction tx = session.beginTransaction();            
	                                                        
	String sql = "select * from customer where id = ?";     
	//创建一个sqlquery查询对象                                      
	SQLQuery query = session.createSQLQuery(sql);           
	//设置映射的实体类                                              
	query.setParameter(0,2);                                
	query.addEntity(Customer.class);                        
	                                                        
	List<Customer> list = query.list();                     
	//关闭资源                                                  
	System.out.println(list);                               
	tx.commit();                                            
}                                                           

4.3.2 分页查询

@Test                                                     
public void testSql2(){                                   
	Session session = HibernateUtils.getCurrentSession(); 
	Transaction tx = session.beginTransaction();          
	                                                      
	String sql = "select * from customer limit ?,?";      
	//创建一个sqlquery查询对象                                    
	SQLQuery query = session.createSQLQuery(sql);         
	//设置映射的实体类                                            
	query.setParameter(0,1);                              
	query.setParameter(1, 2);                             
	query.addEntity(Customer.class);                      
	                                                      
	List<Customer> list = query.list();                   
	//关闭资源                                                
	System.out.println(list);                             
	tx.commit();                                          
}                                                         

五、总结

今天我们学了hibernate的查询方式,需要灵活使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值