hibernate笔记2

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找到所需的对象。


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());
}


快照区都是Session对象的,当Session对象一消失,都会消失

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();

}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值