1. 实体类的编写规范
应该遵循javabean的编写规范
Bean是软件开发中的可重用组件
Javabean值的是Java语言编写的可重用的组件,domain、service、dao都可以看成是JavaBean
编写规范:
1类都是public的
2一般都实现序列化接口
3类成员都是私有的
4私有成员都有set/get方式
5类都有默认的无参构造方法
细节:
数据类型的选择问题(选择包装类(Long))
2. Hibernate中的对象标识符
3. Hibernate的主键的生成策略
Native
Sequence用于Oracle数据库,assigned一般不用,Hilo是高低位算法,如下:
5. Hibernate的一级缓存和快照技术
1)什么缓存:内存中的临时数据
2)为什么使用缓存:减少和数据库交互的次数,从而提高效率
3)什么样的数据适用于缓存:经常查询的、并且不经常修改的、同时数据一旦出现问题,对结果影响不大的
4)不适用缓存的数据:不经常查询,经常修改的,如果使用缓存产生了异常,对结果产生了很大的影响,如:股市的牌价,银行的汇率,商品的库存等等
5)Hibernate的一级缓存:它是值Session对象的缓存,一旦Session对象销毁了,一级缓存也就消失了
public void test1(){
Session s=HibernateUtils.openSession();
Transaction tx=s.beginTransaction();
//根据ID查询客户
Customer c=s.get(Customer.class, 8L);//先去数据库查询,并把结果存入一级缓存
System.out.println(c);
//根据ID再次查询客户
Customer c1=s.get(Customer.class,8L);//先去一级缓存中看有没有,有的话直接拿过来,没有的话再去查询
System.out.println(c1);
System.out.println(c==c1);//true
tx.commit();
s.close();//Session关闭,缓存消失
}
其原理如下:根据Session找到对应的类字符串,在根据OID找到所需的对象。
![](https://i-blog.csdnimg.cn/blog_migrate/6814f4e591c317dcedc23694ab097908.png)
6.如果下边这个代码,当查找后继续修改,在此时并未用代码明确写出update,但是在提交的时候,它会去快照区查看是否和一级缓存区的一致(这个是根据OID来判断的),如果一致的话,不会对数据库进行修改,如果不一致的话,则对数据库进行修改
public void test2(){
Session s=HibernateUtils.openSession();
Transaction tx=s.beginTransaction();
//根据ID查询客户
Customer c=s.get(Customer.class, 8L);//先去数据库查询,并把结果存入一级缓存
System.out.println("1111111111"+c.getCusAddress());//此时是西山校区
c.setCusAddress("甘肃省");
//没有写Update
tx.commit();
s.close();//Session关闭,缓存消失
System.out.println("22222222222"+c.getCusAddress());
}
5. Hibernate的对象状态(三种状态、四种状态)
1)瞬时状态(临时状态)
没有OID,和Session没有关系
2)持久化状态
有OID,和session有关系。只有持久化状态的对象才会有一级缓存,没有提交事务之前数据库没有记录,
3)脱管状态(游离状态)
有OID,和session没有关系
4)删除状态(了解)
标志:有OID,和Session有关系,同时已经调用了删除方法,即将从数据库把记录删除,但是事务还未提交,此时的对象状态是删除状态
public class HibernateDemo5 {
@Test
public void test1(){
Customer c=new Customer();//瞬时状态
c.setCusname("练习题");
Session s1=HibernateUtils.openSession();
Transaction tx1=s1.beginTransaction();
c.setCusAddress("大连");//
s1.save(c);//持久化状态
tx1.commit();//没有提交事务之前数据库没有记录
s1.close();
c.setCusAddress("北京");//脱管状态(脱离了Session的管理)
Session s2=HibernateUtils.openSession();
Transaction tx2=s2.beginTransaction();
s2.update(c);//持久化状态
tx2.commit();
s2.close();
System.out.println(c);//脱管状态
}
目的:为了更好掌握,参见下图:
Close()之session不能用了,clear()之后session还是可以用的,下边写一些saveOrUpdate的方法的使用
@Test
public void test2(){
Customer c=new Customer();//瞬时状态
c.setCusname("练习题2");
Session s=HibernateUtils.openSession();
Transaction tx=s.beginTransaction();
s.saveOrUpdate(c);//此时用save方法,因为是从瞬时状态转为持久状态
tx.commit();
s.close();
}
@Test
public void test3(){
Session s=HibernateUtils.openSession();
Transaction tx=s.beginTransaction();
Customer c=s.get(Customer.class, 21L);//持久化状态
tx.commit();
s.close();
c.setCusAddress("更新");
System.out.println(c);//脱管状态
Session s1=HibernateUtils.openSession();
Transaction tx1=s1.beginTransaction();
s1.saveOrUpdate(c);//此时用update方法,因为是从持久状态转为脱管状态
tx1.commit();
s1.close();
}
6. Hibernate中的事物控制
解决问题:让Session对象也符合使用原则
Session对象的使用原则:一个线程只能有一个session
当我们把线程和session绑定之后,hibernate在提交或者回滚事务之后,会自动关闭Session
/**
* 从当前线程上边获取Session对象
* 当我们把线程和session绑定之后,hibernate在提交或者回滚事务之后,会自动关闭Session
*/
public static Session getCurrentSession(){
return factory.getCurrentSession();//只有设置了把session和当前线程绑定了之后,才能使用此方法,不然的到的是null
}
怎么样实现session和线程的绑定(在hibernate配置文件中设置),如下:
<!-- 把session和线程绑定,从而实现一个线程只有一个session -->
<property name="hibernate.current_session_context_class">thread</property>
但是也可以自己写一个函数实现。如下:
private static ThreadLocal<Session>tl=new ThreadLocal<Session>();
publicstatic Session openSession(){
Session s=tl.get();
if(s==null){
tl.set(factory.openSession());
}
s=tl.get();
returns;
}
7. Hibernate中的查询方式
Hibernate查询多条的方式,一共有五种
1.OID查询:get()和Load()方法
2.SQL查询:
SQLQuery()(一般不用);
Session的doWork()方法,它可以拿到Connection
public void testFindAll(){//查询所有
Session s=HibernateUtils.openSession();
Transaction tx=s.beginTransaction();
//使用session对象,获取一个查询对象query
SQLQuery sqlquery=s.createSQLQuery("select * from CUST_CUSTOMER");
//使用sqlquery对象获取结果集
List<Object[]> list= sqlquery.list();//注意,这个查找到的是一个对象数组
for (Object[] o :list){
System.out.print("-----数组中的内容---------");
for( Object a:o){
System.out.println(a);
}
}
tx.commit();
s.close();
}
public void test1(){
//doWork()方法
//获取session对象
Session s=HibernateUtils.openSession();
//调用doWork方法
s.doWork(new Work() {
@Override
public void execute(Connection arg0) throws SQLException {
System.out.print(arg0.getClass().getName());
}
});
}
3.使用HQL查询(使用HQL语句查询数据库)
4.QBC查询(使用Criteria对象查询数据库)
5.对象导航查询
8. Hibernate中的query对象
它是hibernate中HQL查询方式(hibernate query Language)
1. 如何获取该对象:session对象的方法
2. 涉及的对象和方法:createQuery(Stringsql)
3. 方法中参数的含义
SQL:selectcust_id from customer
HQL:select custId from customer
HQL语句是吧sql语句的表明换成类名,把字段名换成实体类的属性名称
//基本查询
@Test
publicvoid test1(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//查询所有的对象
//1获取Query对象
Query query=s.createQuery("from Customer");//注意此时的是实体类对象Customer
//2执行获取结果集
List list=query.list();
for(Object o:list){
System.out.println(o);
}
tx.commit();//此时不需要手动关闭session,因为hibernate会自动关闭
}
单条件查询:注意(在设置?占位符的时候,需要在问号后边加上相应的数字,在设置参数的时候,根据其设置的数字进行赋值)
//条件查询
@Test
publicvoid test2(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//查询所有的对象
//1获取Query对象
//Query query=s.createQuery("from Customer wherecusLevel=?0");//传统的?占位符
//query.setString(0, "23");
Query query=s.createQuery("from Customer where cusLevel = :cusLevel");//hibernate的占位符,用分号开头
//query.setString("cusLevel","23");//可以用之前的jdbc的参数赋值方法
query.setParameter("cusLevel", "23");//hibernate的赋值方法
//2执行获取结果集
List list=query.list();
for(Object o:list){
System.out.println(o);
}
tx.commit();
}
多条件查询:
publicvoid test3(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//查询所有的对象
//1获取Query对象
//Query query=s.createQuery("from Customer where cusLevel = ?0 and cusnamelike ?1");//注意此时的是实体类对象Customer
Query query=s.createQuery("from Customer where cusLevel =:cusLevel and cusnamelike :cusname");
/*query.setString(0, "23");
query.setString(1, "%大连%");*/
query.setParameter("cusLevel", "23");
query.setParameter("cusname", "%大连%");
//2执行获取结果集
List list=query.list();
for(Object o:list){
System.out.println(o);
}
tx.commit();
}
排序查询:默认是升序asc,desc是降序
publicvoid test4(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//查询所有的对象
//1获取Query对象
Query query=s.createQuery("from Customer order by cusID desc");
//2执行获取结果集
List list=query.list();
for(Object o:list){
System.out.println(o);
}
tx.commit();
}
分页查询:
1.Hibernate提供了两个方法setFirstResult()à设置查询开始的记录(数字的设置是当前页减1,再乘以每页显示的条数)
2.setMaxResult()à设置每次查询的条数
不管使用什么数据库,都用的是这两个方法,依据是配置文件的数据库方言
publicvoid test5(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//查询所有的对象
//1获取Query对象
Query query=s.createQuery("from Customer ");
query.setFirstResult(0);//数字的设置是当前页减1,再乘以每页显示的条数
query.setMaxResults(2);
//2执行获取结果集
List list=query.list();
for(Object o:list){
System.out.println(o);
}
tx.commit();
}
统计查询:count avg sum maxmin
注意:uniqueResult()方法只接受返回的结果是唯一的执行结果,若不唯一的话会抛出异常
//统计查询
/**
* 在HQL中使用聚合函数,count sum avg max min
*/
@Test
publicvoid test6(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//查询所有的对象
//1获取Query对象
Query query=s.createQuery(" select count(*) from Customer ");
//2执行获取结果集
/*List list=query.list();
for(Object o:list){
System.out.println(o);
}*/
Long l=(Long) query.uniqueResult();//如果结果唯一的时候,用此方法接受参数,若返回的结果不唯一,会抛出异常
System.out.println(l);
tx.commit();
}
4. 常用的方法说明
9. Hibernate中的Criteria对象
用HQL可以实现的查询也可以通过Criteria实现,是更加面向对象的一种查询方式。把生成语句的过程融入到了方法之中
Criteria是QBC查询(Create By Criteria)
如何获取对象:session.cteateCriteria(Classclass)
涉及对象的方法:CreateCriteria(Classclass)
参数的含义:要查询的实体类字节码
1.基本查询:
//基本查询
@Test
publicvoid test1(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//获取Criteria对象
Criteria criteria=s.createCriteria(Customer.class);
//获取结集
List list=criteria.list();
for(Object o:list){
System.out.println(o);
}
tx.commit();
}
2.条件查询,若有多个条件,直接再添加criteria.add();方法往里面 添加条件
//条件查询
@Test
publicvoid test2(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//获取Criteria对象
Criteria criteria=s.createCriteria(Customer.class);
//添加条件
criteria.add(Restrictions.eq("cusLevel", "23"));
criteria.add(Restrictions.like("cusname", "%大连%"));
//获取结集
List list=criteria.list();
for(Object o:list){
System.out.println(o);
}
tx.commit();
}