Hibernate学习笔记——第四天

一、hibernate的查询方式

1.对象导航查询

   根据id查询某个客户,再查询这个客户里面的所有联系人

@Test
	public void testSelect1(){
		SessionFactory sessionFactory = null;
		Session session = null;
		Transaction transaction = null;
		try{
			sessionFactory = HibernateUtils.getSessionFactory();
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			//1.查询id为1的客户,再查询这个客户里面所有的联系人
			Customer customer = session.get(Customer.class, 1);
			Set<LinkMan> linkman = customer.getSetLinkMan();
			System.out.println(linkman.size());
			transaction.commit();
		}catch(Exception e){
			transaction.rollback();
			e.printStackTrace();
		}finally{
			session.close();
			sessionFactory.close();
		}
	}

2.OID查询

   根据id查询某一条记录,返回对象

Customer customer = session.get(Customer.class, 1);

3.hql查询

   Query对象,hql语句

(1)查询所有     from+实体类名

@Test
	public void testSelect3(){
		SessionFactory sessionFactory = null;
		Session session = null;
		Transaction transaction = null;
		try{
			sessionFactory = HibernateUtils.getSessionFactory();
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			//1.创建query对象
			Query query = session.createQuery("from Customer");
			//2.调用方法
			List<Customer> list = query.list();
			for(Customer c : list){
				System.out.println(c.getCustName());
			}
			transaction.commit();
		}catch(Exception e){
			transaction.rollback();
			e.printStackTrace();
		}finally{
			session.close();
			sessionFactory.close();
		}
	}

 (2)条件查询

//from 实体类名称 where 实体类属性名称 = ? and 实体类属性名称 = ?
                        //1.创建query对象
			Query query = session.createQuery("from Customer C WHERE C.custName = ?0");
			//设置参数
			//query.setString(0, "web");
			query.setParameter(0, "web");
			//2.调用方法 
			List<Customer> list = query.list();
//from 实体类名称 where 实体类属性名称 like ?
                        Query query1 = session.createQuery("from Customer C WHERE C.custName like ?0");
			query1.setParameter(0, "%度%");
			List<Customer> list1 = query1.list();

(3)排序查询

from 实体类名称 order by 实体类属性名称 asc/desc

 (4)分页查询

//1.使用关键字limit实现
SELECT * FROM t_customer LIMIT 0,3

//2.在hql中,在语句中不能使用limit,使用query对象封装的两个方法实现
    //1.创建query对象,写查询所有的语句
    Query query = session.createQuery("from Customer");
    //2.设置分页数据
    //2.1 设置开始位置
    query.setFirstResult(0); 
    //2.2 设置每页记录数
    query.setMaxResults(3);
    //3.调用方法得到结果
    List<Customer> list = query.list();
    for(Customer customer : list){
	System.out.println(customer.getCid()+"-"+customer.getCustName());
    }

 (5)投影查询

          查询不是所有字段值,而是部分字段的值

//select 实体类属性名称1,实体类属性名称2 from 实体类名称
//1.创建query对象,select后面不能写*
Query query = session.createQuery("select cid,custName from Customer");
//2.调用方法得到结果
List<Object[]> list = query.list();
for (Object[] objects : list) {
    System.out.println(objects[0]+" - "+objects[1]);
}

(6)聚集函数使用

       常用的聚集函数,count、sum、avg、max、min  

      

                        //1.创建query对象
			Query query = session.createQuery("select count(*) from Customer");
			//2.调用方法得到结果
			//uniqueResult()方法返回一个Long类型值
			Object obj = query.uniqueResult();
			Long lobj = (Long)obj;
			int iobj = lobj.intValue();
			System.out.println(iobj);

4.QBC查询

   Criteria对象,方法实现,不需要写语句。操作的是实体类和属性

(1)查询所有

                        //1.创建对象
			Criteria criteria = session.createCriteria(Customer.class);
			//2.调用方法
			List<Customer> list = criteria.list();
			for (Customer customer : list) {
				System.out.println(customer.getCid() + " " + customer.getCustName());
			}

(2)条件查询

                        //1.创建对象
			Criteria criteria = session.createCriteria(Customer.class);
			//2.调用方法设置条件值 
			//首先使用add方法,在里面使用类的方法实现条件设置
			//类似于cid=?,custLevel=?
			criteria.add(Restrictions.eq("cid", 1));
			criteria.add(Restrictions.eq("custLevel", "pp"));
			List<Customer> list = criteria.list();
			for (Customer customer : list) {
				System.out.println(customer.getCid() + " " + customer.getCustName());
			}
                        //模糊查询 like()方法
                        criteria.add(Restrictions.like("custName", "%百%"));

(3)排序查询

                        //1.创建对象
			Criteria criteria = session.createCriteria(Customer.class);
			//2.调用方法,设置对哪个属性进行排序以及排序规则
			criteria.addOrder(Order.desc("cid"));
			List<Customer> list = criteria.list();
			for (Customer customer : list) {
				System.out.println(customer.getCid() + " " + customer.getCustName());
			}

(4)分页查询

                        //1.创建对象
			Criteria criteria = session.createCriteria(Customer.class);
			//2.调用方法设置分页数据
			//设置开始位置,当前页计算公式:(当前页-1)*每页记录数
			criteria.setFirstResult(0);
			//设置每页显示数据数
			criteria.setMaxResults(3);
			List<Customer> list = criteria.list();
			for (Customer customer : list) {
				System.out.println(customer.getCid() + " " + customer.getCustName());
			}

(5)统计查询

                        //1.创建对象
			Criteria criteria = session.createCriteria(Customer.class);
			//2.设置操作
			criteria.setProjection(Projections.rowCount());
			Object obj = criteria.uniqueResult();
			Long lobj = (Long)obj;
			int count = lobj.intValue();
			System.out.println(count);

 (6)离线查询

                        //1.创建对象
			DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
			//2.最终执行时用到session
			Criteria criteria = detachedCriteria.getExecutableCriteria(session);
			List<Customer> list = criteria.list();

(7)多表查询

         MySQL中实现

         ·内连接

         ·左外连接

         ·右外连接

         HQL实现

         ·内连接

                        Query query = session.createQuery("from Customer c inner join c.setLinkMan");
			//返回额list里面为Object[]数组
                        List list = query.list();

         ·左外连接

                        Query query = session.createQuery("from Customer c left outer join c.setLinkMan");
			//list集合中每部分是数组
                        List list = query.list();

         ·右外连接

                        Query query = session.createQuery("from Customer c right outer join fetch c.setLinkMan");
			List list = query.list();

         ·迫切内连接 

           与内连接的底层实现一致,但返回的list集合中每部分不是数组,而是对象         

                        Query query = session.createQuery("from Customer c inner join fetch c.setLinkMan");
			List list = query.list();

         ·迫切左外连接

                      Query query = session.createQuery("from Customer c left outer join fetch c.setLinkMan");
                      //list集合返回的是对象			
                      List list = query.list();

5.本地sql查询 

    SQLQuery对象,使用普通sql实现  

二、Hibernate的检索策略 

1.立即查询

2.延迟查询

                        // 一调用get方法,就马上发送sql语句,成为立即查询
			Customer customer = session.get(Customer.class, 1);
			System.out.println(customer.getCustName()+" "+customer.getCid());
			// 调用load方法后不会马上发送sql语句
			Customer customer1 = session.load(Customer.class, 2);
			// 返回的对象中包含id值,此时也不发送sql语句
			System.out.println(customer1.getCid());
			// 使用对象中非id值时才发送sql语句
			System.out.println(customer1.getCustName());

  延迟查询又分成两类:

(1)类级别延迟

(2)关联级别延迟:查询某个客户,再查询这个客户下的所有联系人,查询联系人的过程是否需要延迟,这个过程称为关联级别查询

                        //先查询id为1的客户,再查询这个客户里面的所有联系人
			Customer customer = session.get(Customer.class, 1);
			//得到set集合,没有发送语句
			Set<LinkMan> set = customer.getSetLinkMan();
			//使用这个set集合时,发送语句
			System.out.println(set.size());

3.关联级别延迟操作

(1)在映射文件中进行配置

根据客户得到所有联系人,在客户映射文件中配置,在set标签上使用fetch和lazy属性。

//默认情况下,延迟查询
fetch="select" lazy="true"
//select-false,get方法查询联系人时就发送了两条语句,把联系人和set集合都查出来了,效率低一般不用
fetch="select" lazy="false"

//select-extra,极其懒惰,效率高,需要什么查询什么
fetch="select" lazy="extra"

4.批量抓取

查询所有客户,返回list集合,遍历list集合,得到每个客户,得到每个客户所有联系人。

                        //查询所有客户
			Criteria criteria = session.createCriteria(Customer.class);
			List<Customer> list = criteria.list();
			//得到每个客户里面的联系人
			for (Customer customer : list) {
				System.out.println("客户姓名:" + customer.getCustName());
				Set<LinkMan> setLinkMan = customer.getSetLinkMan();
				for (LinkMan linkMan : setLinkMan) {
					System.out.println("联系人姓名:" + linkMan.getLkm_name());
				}
			}

上面代码可以实现,但是效率很低,每次遍历都进行了一次查询。

使用批量抓取优化,在客户的映射文件中,配置set标签,使用batch-size属性,值越大,效率越高。

<set name="setLinkMan" batch-size="10">

猜你喜欢

转载自blog.csdn.net/weufengwangshi_/article/details/86760568