zoukankan      html  css  js  c++  java
  • Hibernate之SQL查询

    Hibernate支持使用原生的SQL语句进行查询。使用原生的SQL的好处是:可以利用某些数据库的特性(不同的数据库SQL 语法会有所差异),

    将原有的使用JDBC作为持久层技术的应用 ,迁移到使用Hibernate作为持久层技术。

    我们知道 使用HQL查询 主要牵涉的是 Query接口,而使用SQL查询 主要牵涉的 是 SQLQuery接口  。

    而SQLQuery接口 是 Query接口的子接口。

    所以 Query接口中的方法 ,均可以在SQLQuery接口中使用 ,SQLQuery接口还多了如下两个方法:

    addEntity():    将查询到的 记录  与  持久化类实体 关联 

    addScalar():    将查询到的 记录的列的值 关联 成 标量值。

    据此 SQL查询可以分为 实体查询 和 标量查询

    1.标量查询

    session.createSQLQuery(String  sql)   查询出来的结果表的 一条记录的列的值 封装成 一个 Object[]  数组。

    然后使用list()方法,得到存有N个Object[] 数组 的list集合。

    如果查询的结果表 的记录只有一个列,那么就不会封装成为Object[]数组,因为没有必要。这时调用list()方法,会得到直接存有记录列值的list集合。

    在调用list()方法 ,封装成集合之前 ,可以调用addScalar()方法进行 ,明确返回值类型的处理。例子:

     @Test
        public void testSQL()
        {
            String sql = "select t.name, t.age , t.birthday from tb_person as t";
            SQLQuery sqlquery= session.createSQLQuery(sql)
                                      .addScalar("name", StandardBasicTypes.STRING)
                                      .addScalar("age", StandardBasicTypes.INTEGER)
                                      .addScalar("birthday", StandardBasicTypes.DATE);      //如果在使用addScalar()方法时,没有包含某列,则该列不会出现在Object[]数组中,尽管已经查出了该列
            List<Object[]> list = sqlquery.list();
            for(int i = 0 ; i < list.size() ; i++)
            {
                Object[] objArray = list.get(i);
                for(int j = 0 ; j < objArray.length ; i++)
                {
                    System.out.println("第"+i+"条记录的列的值:"+ objArray[j]);
                }
            }
                   
        }

    标量查询中 ,addScalar()方法有两个作用:
    指定查询结果包含哪些数据列 -------没有被addScalar()选出的数据列不会包含在最终查询结果中

    指定查询结果中数据列的数据类型

    2.实体查询

    如果查询返回某个数据表的全部数据列(记住:是选出全部数据列,包括通过外键关联存在从表中的属于这条记录的列),且该数据表有对应的持久化类映射,

    我们就可以将查询结果转化为实体查询。

    单表情况,即一个持久化类的属性 通过一张表来存储。例子:

    @Test 
        public void testSQLEntity()
        {
            //持久化Person类  有三个属性 name ,age ,bithday
            String sql  = "select t.* from tb_person as t where t.id = :id ";
            
            SQLQuery sqlquery = (SQLQuery) session.createSQLQuery(sql)
                                                  .addEntity(Person.class)   //将查询的行记录 转化为 类实体对象
                                                  .setInteger("id", 99);     // sql绑定参数
            List<Person> list = sqlquery.list();       //每一条记录封装成 一个Person类的实例对象 ,放在list集合中  
            
            for(int i = 0 ; i < list.size() ; i++)
            {
                Person  p  = (Person)list.get(i);
                System.out.println("第"+i+"个对象的name属性:" + p.getName() );
                System.out.println("第"+i+"个对象的age属性:" + p.getAge() );
                System.out.println("第"+i+"个对象的bithday属性:" + p.getBirthday() );
            }
        }

    多表关联的情况, 如持久化类有集合类型的属性 ,等映射成多表 。例子:

     @Test 
        public void testSQLEntity()
        {
            //持久化Person类  有四个属性 name ,age ,bithday , List<House> 
            String sql  = "select p.* , h.* from tb_person as p , tb_house as h where p.id = h.id and p.id = :id ";   //tb_person表 与 tb_house通过既是主键又是外键的 tb_house的id关联
            
            SQLQuery sqlquery = (SQLQuery) session.createSQLQuery(sql)
                                                  .addEntity(Person.class)   //将查询的行记录 的前部分列转化为 Person类实体对象
                                                  .addEntity(House.class)    //将查询的行记录 转后部分列化为House类实体对象
                                                  .setInteger("id", 99);     // sql绑定参数
            List<Object[]> list = sqlquery.list();       //每一条记录封装成 一个Person类的实例对象和一个House类的实例对象,放在一个Object[]数组中 ,多个Object数组,放在list集合中  
            
            
                   
        }

    命名SQL查询:

    类似于命名HQL查询  

  • 相关阅读:
    合并指定表格指定列的相同文本的相邻单元格
    [转载]>/dev/null 2>&1 含义
    有关cron
    jQuery版本对checkbox影响
    c# 如何获取项目的根目录
    Javascript 字符串组装用函数 format
    sql server 删除数据库
    说说接口封装
    有开放的接口!!!!
    支付宝支付功能的集成
  • 原文地址:https://www.cnblogs.com/wangliyue/p/4170550.html
Copyright © 2011-2022 走看看