Hibernate(10) 查询

版权声明:转载需经同意,谢谢! https://blog.csdn.net/Big_KK/article/details/82082873

通过Hibernate查询信息

Hibernate提供了多种的查询方式来进行数据的获取。可以通过对象OID查询、导航查询、HQL语句查询,QBC查询,下面各自对这三种方式的查询步骤做出一个简单的汇总

下面的查询使用到了一些实体以及数据,数据实体包括代表消费者的实体Customer、代表收货地址的实力Address。二者为1对多的映射关系,下面是他们各自的值:
这里写图片描述
这里写图片描述

下面的例子将以上面的两个实体进行举例,为了节约篇幅,下面的代码片段都只写主要的,遵循下面的格式:

     @Test
    public void test(){
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction transaction = null;
        try {
            sessionFactory = HibernateUtils.getSessionFactory();
            session = sessionFactory.getCurrentSession();
            transaction = sessnTransaction();


             //举例所用代码片段    
             ......

            transaction.commit();
        }catch (Exception e){
            transaction.rollback();
        }finally {
            sessionFactory.close();
        }
    }

1、OID查询

就是之前所说到的通过get() / load()方法获取一个实体对象的方式,比较简单。

//在Customer实体所映射的表里面获取 id=1 的信息, 立即到对数据库进行查询。
Customer customer1 = (Customer) session.get(Customer.class, 1);

//在Customer实体所映射的表里面获取 id=2 的信息, 只有在下文使用到customer2非id的信息时候采取进行加载
Customer customer2 = (Customer) session.load(Customer.class, 2);

//上面两个方法的细节可以了解 Hibernate的延时加载机制,但都可以获取对象

2、对象导航查询

是在使用IOD获取到实体的基础上,再通过该实体获取其对应的N端集合或1端的实体对象。就本例而言,可以在获取一个消费者实体后,进而通过该实体获取消费者的所有地址集合(对应的N端集合)。反之,在先获取一个地址实体之后,也可以直接获取它所对应的消费者(1端实体)。具体示例代码如下:

    //获取一个消费者
    Customer customer = (Customer) session.get(Customer.class, 1);
    //可以直接使用getXXX()方法将其收货地址集合获取到,XXX在建立二者的映射关系时候已经添加,此处为addressSet
    Set<Address>  addresses  = customer.getAddressSet();
    //后续操作
    for(Address address : addresses){
         System.out.println(address.toString());
    }

上面演示的是1对多的映射关系,同样适用于多对多映射关系的对象导航查询,这里不再举例

3、HQL查询

HQL(Hibernate Query Language),Hibernate提供的查询语言,与sql语言类似。可以使用Query对象执行所构建的语句,Query对象可以从Session对象里面获取。通过HQL实现的查询主要包括:查询所有,条件查询,模糊查询,排序查询,分页查询投影查询,聚集函数查询,多表查询。下面将这些查询的简单示例列出:

3.1查询所有:

HQL语句格式: from 实体类类名。
示例:[from Address] 查询Address实体所对应的表的所有记录
    Query query = session.createQuery("from Address");
    //执行list()方法将按照上面所构建的语句获取结果,返回List
    List<Address> list = query.list();
    //后续操作
    for(Address address : list){
        System.out.println(address.toString());
    }

3.2按条件查询:

HQL语句格式:from 实体类类名 where 实体类属性 = ? and 实体类属性n = ? \\
示例:[from Address where id = ?] 查询Address所对应的表里id = ?的行,具体值需要指定

      上面所创建的语句需要使用Query对象提供的方法进行指定,可以使用setParameter(index, value)或者使用setXXX(index, value), XXX表示具体的包装类类型。与JDBC中填充PreparedStatement对象中预编译的SQL语句所使用的方法是类似的。
      index表示第几个待填充的值,在Hibernate里面,第1个待填充的值索引为0,而不是1!这一点与PreparedStatement对象是不同的。而value指的是填充的值

    Query query = session.createQuery("from Address  where id < ?");
    //query.setParameter(index, value)也可以使用该方法设置
    query.setInteger(0,6);
    List<Address> list = query.list();
    //对list的后续操作......

3.3模糊查询

其实也算是条件查询的一种,like后跟得表达式有如下规则:

        * % 代替任意个字符,相当于正则的 .+
        * _ 代替一个字符,相当于正则的 .
        * [abc] 代替下列字符的任意单一字符,
        * [^abc]或者[!abc] 排除下列字符的任意单一字符, 同样与正则类似
HQL语句格式:from 实体类类名 where 实体类属性 like ?
示例[from Address where address like 北京市% ] 查询出地址以北京市开头的信息
    Query query = session.createQuery("from Address  where address like ? ");
    //query.setParameter(index, value)也可以使用该方法设置
    query.setString(0, "北京市%");
    List<Address> list = query.list();

3.4升/降序查询

HQL语句格式:from 实体类类名 [条件] order by 实体类属性 [desc/asc]
示例:[from Address order by id desc] 对Address对应的表按id进行降序排列,asc升序排列

3.5分页查询

分页不是从HQL语句进行调整,而是通过Query对象的方法:setFirstResult(int) / setMaxResults(int)方法进行,前者设置分页开始的位置,后者设置每一页的记录数。

Query query = session.createQuery("from Address");
//从第4个位置位置开始查询,查询一页,一页数量为2
query.setFirstResult(3);
query.setMaxResults(2);

3.6投影查询

HQL语法格式: select  实体属性 from 实体类类名 [条件] [排序]
示例:[select  address  from  Address]查询出Address实体对应表的address列的所有信息

3.7聚集函数

HQL语法格式:select 函数 from 实体类类名
示例:[select count(*) from Address]查询出Address对应表的信息总条数

在获取单列的信息时候,可以使用uniqueResult()方法获取结果而不是使用list()方法。

Query query = session.createQuery("select count(*) from Address");
Object obj = query.uniqueResult();
//转换为int以便后续使用
System.out.println(Integer.parseInt(obj+""));

3.8内连接

HQL语法格式:from 实体类类名 自定义实体类名称 inner join 自定义实体类名称.所映射另一端实体在本实体的属性
示例:在Customer这个实体中,他所映射的另一端的实体就是与它具有映射关系的Address实体,
     而所映射的Address实体保存在Customer实体里面的addressSet集合。所以HQL可以写为:
     from Customer c inner join c.addressSet

返回的list内部包含的是数组,要想将其内部包含的是对象,需要使用迫切内连接

 Query query = session.createQuery("from Customer c inner join c.addressSet");
 List list = query.list();
 for(Object temp : list){
     Object[] arr = (Object[]) temp;
     //索引0包含了Customer的信息,索引1包含了addressSet的信息
     System.out.println(arr[0]);
 }

3.9迫切内连接

HQL语法格式与内连接基本相同,不过是在join关键字后面加入了又一关键字fench,使用方式与内连接相同

返回对的list集合内部包含的是对象的形式,不再是数组

4.QBC查询

使用hql查询的时候,需要在里面指定执行的名称,而使用QBC的时候,可以直接调用其中的方法来执行特定的功能。执行的功能与HQL基本相同。
执行QBC查询主要使用到了Criteria对象,构建一个新的Criteria对象,并指定class对象以决定操作的实体。

构建一个Criteria对象来操作Addres实体对应的表:Criteria criteria = session.createCriteria(Address.class);

4.1查询所有

QBC在构建完毕之后默认就是查询全表的,所以此时直接调用list()方法就可以得到映射表的所有信息

4.2条件查询

在构建完一个Criteria对象之后,默认查询全部,可以使用Criteria对象的add()方法为其添加查询条件。查询条件可以使用Restrictions对象的静态方法进行构造,传递相应的值构造一个条件添加到Criteria对象里面。常用的条如下,他们都是静态方法,可以直接调用生成条件并添加:
这里写图片描述
每个方法都要求传递一些值,就Restrictions.eq(propertyName, value)方法来讲,要求传入设置相等的属性名称,并传递等于的值,使用实例如下,具体的参数可以查看Hibernate的API说明

 Criteria criteria = session.createCriteria(Address.class);
 //为Criteria对象添加条件 id = 2 
 criteria.add(Restrictions.eq("id", 2));
 //查询Address对应表中id = 2 的信息
 List<Address> list = criteria.list();
 //.......

4.3排序查询

与条件查询类似,排序查询也需要使用addOrder(Order order)方法传递一个表示排序规则的对象Order(注意是hibernate包下的对象),使用比较简单:

Criteria criteria = session.createCriteria(Address.class);

//设置addOrder方法进行排序,传入Order对对象,选择其排序方式并指定排序所依据的属性,升序为Order.asc(propertyName)
criteria.addOrder(Order.desc("id"));

List<Address> list = criteria.list();

4.4分页查询

与HQL语言的分页查询类似,也是使用setFirstResult()方法以及setMaxResults()方法,进而再次获取查询的集合。

4.5聚合函数查询

还是需要传递一个标识聚合函数的对象,与分页查询,排序查询是类似的。只不过它传递的是Projection对象,代表一个聚合函数,使用Criteria对象的setProjection()对象将设置的聚合函数添加。与条件查询一样,也有一个类专门生产聚合函数对象:Projections类包含一系列生成Projection聚合函数的方法,具体的可以参见Hibernate API

4.6离线查询

了解不多,只知道不是通过Session对象生成的,便于使其作为参数进行传递。

            DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Address.class);
            Criteria criteria = detachedCriteria.getExecutableCriteria(session);
            criteria.add(Restrictions.eq("id", 2));
            List<Address> list = criteria.list();
            for(Address address : list){
                System.out.println(address);
            }

猜你喜欢

转载自blog.csdn.net/Big_KK/article/details/82082873