【Hibernate笔记整理八】检索方式

版权声明:本文为 小异常 原创文章,非商用自由转载-保持署名-注明出处,谢谢!
本文网址:https://blog.csdn.net/sun8112133/article/details/106151609







Hibernate 中提供了很多种的检索方式。下面我们就挨个介绍:


一、OID 检索

OID 检索Hibernate 根据对象的 OID(主键)进行检索的一种方式。

1、使用 get() 方法

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

2、使用 load() 方式

Customer customer = session.load(Customer.class, 1L);


二、对象导航检索

对象导航检索是 Hibernate 根据一个已经查询到的对象,获得其关联对象的一种查询方式。

LinkMan linkMan = session.get(LinkMan.class, 1L);
Customer customer = linkMan.getCustomer();   // 对象导航


三、HQL 检索(*重要)

HQL 查询 的全称是 Hibernate Query Language,它是 Hibernate 的查询语言,是一种面向对象方式的查询语言,语法类似 SQL。通过 session.createQuery(),就可以接收到一个 HQL 查询对象。

1、简单查询

@Test
// 简单查询
public void demo1() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    Query query = session.createQuery("from Customer");
    List<Customer> list = query.list();
    // sql中支持*号的写法:select * from cst_customer; 但是在HQL中不支持*号的写法

    for (Customer customer : list) {
        System.out.println(customer);
    }

    tx.commit();
}

2、别名查询

@Test
// 别名查询
public void demo2() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    //		Query query = session.createQuery("from Customer c");
    Query query = session.createQuery("select c from Customer c");
    List<Customer> list = query.list();
    // sql中支持*号的写法:select * from cst_customer; 但是在HQL中不支持*号的写法

    for (Customer customer : list) {
        System.out.println(customer);
    }

    tx.commit();
}

3、排序查询

@Test
// 排序查询
public void demo3() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    // 默认情况
    //		Query query = session.createQuery("from Customer order by cust_id");
    // 设置降序(升序使用asc,降序使用desc)
    Query query = session.createQuery("from Customer order by cust_id desc");
    List<Customer> list = query.list();

    for (Customer customer : list) {
        System.out.println(customer);
    }

    tx.commit();
}

4、HQL 的条件查询

@Test
// 条件查询
public void demo4() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    // 条件查询
    // 一、按位置绑定:根据参数的位置进行绑定
    // 一个条件
    //		Query query = session.createQuery("from Customer where cust_name = ?");
    //		query.setParameter(0, "李四");
    // 多个条件
    //		Query query = session.createQuery("from Customer where cust_source = ? and cust_name like ?");
    //		query.setParameter(0, "电脑");
    //		query.setParameter(1, "李%");

    // 二、按名称绑定
    Query query = session.createQuery("from Customer where cust_source = :aaa and cust_name like :bbb");
    // 设置参数
    query.setParameter("aaa", "电脑");
    query.setParameter("bbb", "李%");

    List<Customer> list = query.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }

    tx.commit();
}

5、投影查询

投影查询 是查询对象的某个或某些属性。

@Test
// 投影查询
public void demo5() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    // 投影查询
    // 单个属性
    //		Query query = session.createQuery("select c.cust_name from Customer c");
    //		List<Object> list = query.list();
    //		for (Object obj : list) {
    //			System.out.println(obj);
    //		}

    // 多个属性
    //		Query query = session.createQuery("select c.cust_name, c.cust_source from Customer c");
    //		List<Object[]> list = query.list();
    //		for (Object[] objs : list) {
    //			System.out.println(Arrays.toString(objs));
    //		}

    // 查询多个属性,并封装到对象中
    Query query = session.createQuery("select new Customer(cust_name, cust_source) from Customer");
    List<Customer> list = query.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }

    tx.commit();
}

6、分页查询

@Test
// 分页查询
public void demo6() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    // 分页查询
    Query query = session.createQuery("from LinkMan");
    query.setFirstResult(10);  // 从第几条开始,0是第一条
    query.setMaxResults(10);  // 显示多少条
    List<LinkMan> list = query.list();
    for (LinkMan linkMan : list) {
        System.out.println(linkMan);
    }

    tx.commit();
}

7、分组统计查询

@Test
// 分组统计查询
public void demo7() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    // 聚合函数的使用:count(), max(), min(), avg(), sum()
    //		Query query = session.createQuery("select count(*) from Customer");
    //		Object object = query.uniqueResult();   // 唯一结果
    //		System.out.println(object);

    // 分组统计:
    Query query = session.createQuery("select cust_source, count(*) from Customer group by cust_source having count(*) >= 2");
    List<Object[]> list = query.list();
    for (Object[] objs : list) {
        System.out.println(Arrays.toString(objs));
    }

    tx.commit();
}

8、多表查询

我们将 HQL 多表查询与 SQL 多表查询进行对比:

1)SQL 的多表查询

  • 连接查询

    • 交叉连接:最不常用的,笛卡尔积

      select * from A,B;

    • 内连接:inner join(inner 可以省略)

      • 隐式内连接

        select * from A,B where A.id = B.aid;

      • 显式内连接

        select * from A inner join B on A.id = B.aid;

    • 外连接

      • 左外连接:left outer join(outer 可以省略)查到的是左边表(A)的全部信息,以及两个表的公共部分

        select * from A left outer join B on A.id = B.aid;

      • 右外连接:right outer join(outer 可以省略)查到的是右边表(B)的全部信息,以及两个表的公共部分

        select * from A right outer join B on A.id = B.aid;

  • 子查询


2)HQL 的多表查询

  • 连接查询
    • 交叉连接
    • 内连接
      • 隐式内连接
      • 显式内连接
      • 迫切内连接
    • 外连接
      • 左外连接
      • 右外连接
      • 迫切左外连接

3)HQL 多表查询测试

@Test
// HQL的多表查询
public void demo8() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    // SQL: select * from cst_customer c inner join cst_linkman l on c.cust_id = l.lkm_cust_id;
    // HQL:内连接 from Customer c inner join c.linkMans
    //		List<Object[]> list = session.createQuery("from Customer c inner join c.linkMans").list();
    //		for (Object[] objs : list) {
    //			System.out.println(Arrays.toString(objs));
    //		}

    // HQL:迫切内连接 其实就是在普通的内连接 inner join 后添加一个关键字 fetch。
    // from Customer c inner join fetch c.linkMans
    // 通过 Hibernate,将另一个对象的数据封装到该对象中
    List<Customer> list = session.createQuery("select distinct c from Customer c inner join fetch c.linkMans").list();  
    for (Customer customer : list) {
        System.out.println(customer);
    }

    tx.commit();
}


四、QBC 检索(*重要)

QBC 查询的全称是 Query By Criteria,它是一种更加面向对象化的查询的方式。并不是所有方式都能使用 QBC,有些地方是不支持 QBC 的。

1、简单查询

@Test
// 简单查询
public void demo9() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    // 获得 Criteria 的对象 
    Criteria criteria = session.createCriteria(Customer.class);
    List<Customer> list = criteria.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }

    tx.commit();
}

2、排序查询

@Test
// 排序查询
public void demo10() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    // 排序查询
    Criteria criteria = session.createCriteria(Customer.class);
    //		criteria.addOrder(Order.asc("cust_id"));  // 升序
    criteria.addOrder(Order.desc("cust_id"));  // 降序
    List<Customer> list = criteria.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }

    tx.commit();
}

3、分页查询

@Test
// 分页查询
public void demo11() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    // 分页查询
    Criteria criteria = session.createCriteria(LinkMan.class);
    criteria.setFirstResult(10);
    criteria.setMaxResults(10);
    List<LinkMan> list = criteria.list();
    for (LinkMan linkMan : list) {
        System.out.println(linkMan);
    }

    tx.commit();
}

4、条件查询

@Test
// 条件查询
public void demo12() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    // 条件查询
    Criteria criteria = session.createCriteria(Customer.class);
    // 设置条件
    /*
	 * =   eq
	 * >   gt
	 * >=  ge
	 * <   lt
	 * <=  le
	 * <>  ne(not equals)
	 * like
	 * in
	 * and
	 * or
	 */
    //		Disjunction disjunction = Restrictions.disjunction();  // 用or连接
    //		disjunction.add(Restrictions.ne("cust_source", "电脑"));
    //		disjunction.add(Restrictions.like("cust_name", "%四"));
    //		criteria.add(disjunction); // 默认用and连接

    criteria.add(Restrictions.ne("cust_source", "电脑"));
    criteria.add(Restrictions.or(Restrictions.like("cust_name", "%四")));   // 这样也可以用or连接

    //		criteria.add(Restrictions.ne("cust_source", "电脑"));
    //		criteria.add(Restrictions.like("cust_name", "%四"));
    List<Customer> list = criteria.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }

    tx.commit();
}

5、统计查询

@Test
// 统计查询
public void demo13() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(Customer.class);
    /*
	 * add             : 普通条件。where 后面条件
	 * addOrder        : 排序
	 * setProjection   : 聚合函数 和 group by having
	 */
    criteria.setProjection(Projections.rowCount());
    Object object = criteria.uniqueResult();
    System.out.println(object);

    tx.commit();
}

6、离线条件查询(SSH整合中经常使用)---- DetachedCriteria

@Test
// 离线条件查询
public void demo14() {
    // Web层
    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
    detachedCriteria.add(Restrictions.like("cust_name", "李%"));

    // Sevice层:直接将 detachedCriteria对象 传过去
    // Dao层:接收到 detachedCriteria对象
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();
    // 绑定session
    Criteria criteria = detachedCriteria.getExecutableCriteria(session);
    List<Customer> list = criteria.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }

    tx.commit();
}


五、SQL 检索

SQL 查询是通过使用 SQL 语句进行查询。

@Test
public void demo15() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    SQLQuery sqlQuery = session.createSQLQuery("select * from cst_customer");

    //		List<Object[]> list = sqlQuery.list();
    //		for (Object[] objs : list) {
    //			System.out.println(Arrays.toString(objs));
    //		}

    sqlQuery.addEntity(Customer.class);
    List<Customer> list = sqlQuery.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }

    tx.commit();
}


博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!



猜你喜欢

转载自blog.csdn.net/sun8112133/article/details/106151609