• Hibernate HQL与原生SQL(存储过程)


    Query接口
    1.list()和iterate()方法的区别在于iterate()先通过select语句查找所有id字段的值,然后如果session缓存(一级缓存)中已经存在id对应的对象就直接添加到查询结果中,否则再根据id额外查询这条记录。

    2.Query和Criteria共同有的方法

    list(),uniqueResult(),setMaxResults(),setFirstResult()

    HQL

    操作的都是属性和类名,不是数据库的字段和表

    1.如果查询的类含有子类,则返回类及其子类的所有表的数据。如from java.lang.Object。

    2.query.list返回类型

    (1)."select id from Product",List<Integer> list=query.list()

    (2).hql="select id,name,price from Product",则query.list()返回的类型应该转换为List<Object[]>

    (3).hql="select new Product(id,name,price) from Product"(前提是存在对应的构造函数),则query.list()返回的类型可以转换为List<Product>

    (4).hql="select new map(id,name,price) from Product",则List<Map> list=query.list(); key值为0,1,2

    3.别名

    select p.name as name from Product [as] p

    如果select new map(p.id as id,p.name as name,p.price as price) from Product p,则List<Map> list=query.list(),map中的key不再是0,1,2,而是"id","name"等。

    4.not子句用于表示查询条件的非

    from Product where not (price<250)

    5.参数占位符

         (1). "from Product where id<?" query.setInteger(0,12); 

         (2). "from Product where id< :big"  query.setInteger("big",12);

    6.HQL函数

     current_time() current_date() current_timestamp() length() upper() lower() trim()

    7.更新

    String hql="update Product set name='雨伞' where id=4";

    Query query=session.createQuery(hql);

    query.executeUpdate();

    8.内连接

    String hql="select p from Product p [inner] join p.category";

    hql="select p from Product p,Category c where p.category=c";

    hql="select p from Product p,Category c where p.category.id=c.id";

    //QBC

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

    criteria.createCriteria("category");

    //category为Product类的属性,类型为Category

    9.左外连接 select c from Category c left outer join c.products order by c.id 

    Category中有Set类型的属性products

    这里HQL比SQL稍有区别,如果要关联的表本身已经映射为类的某个属性,可以直接写join 属性名,而标准的连接语句为 select c.*,p.* from category c left outer join product p on c.id=p.category_id;

    QBC方式的左外连接

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

    criteria.setFetchMode("products",FetchMode.JOIN);

    (Oracle9iDialect不支持有外连接,要改用Oracle9Dialect)
    10.立即加载连接对象

    String hql="select c from Category c left outer join fetch c.products order by c.id";               

    Hibernate仅适用一条sql语句。不然则先查询主动方,待需要时再根据关联外键查关联的另一方。

    11.命名HQL

    在类的映射配置文件中Product.hbm.xml,

        <query name="selectProducts">

        <![CDATA[select p from Product p where p.id between :begin and :end]]>

        </query>

    在代码:

    Query query=session.getNamedQuery("selectProducts");

    query.setInteger("begin",2);

    query.setInteger("end",5);

    原生SQL

    1.

    String sql="select p.name,p.price,p.category_id,c.name from " +

            "pro p,category c where p.category_id=c.id";

    SQLQuery query=session.createSQLQuery(sql);

    List<Object[]> list=query.list();           

    2.addScalar()减少Hibernate底层使用ResultSetMetaData提高效率

    String sql="select * from pro";

    SQLQuery query=session.createSQLQuery(sql);

    query.addScalar("id", Hibernate.INTEGER);

    query.addScalar("name",Hibernate.STRING);

    query.addScalar("price",Hibernate.FLOAT);

    query.addScalar("category_id",Hibernate.INTEGER);

    List<Object[]> list=query.list();

    3.使Hibernate直接将返回结果封装为对应的Bean类

            String sql="select * from product";

                    SQLQuery query=session.createSQLQuery(sql);

                    query.addEntity(Product.class);

                    List<Product> list=query.list();

    或者用大括号指定要查询的字段:

                    String sql="select {p.*} from product p";

                    SQLQuery query=session.createSQLQuery(sql);

                    query.addEntity("p",Product.class);

                    List<Product> list=query.list();

    4.带参(与上文HQL方式类似)

                    String sql="select {p.*} from product p where p.id=?";

                    SQLQuery query=session.createSQLQuery(sql);

                    query.addEntity("p",Product.class);

                    query.setParameter(0, 5);//从0开始

    setParameter是通用方法,具体可用setInteger,setString等
    5.命名的SQL

    在Bean的映射文件中

    <sql-query name="selProducts">

              <![CDATA[select {p.*} from product p where p.id between :begin and :end]]>

      <return alias="p" class="com.tazi.domin.Product"></return>

    </sql-query>

    注意与HQL命名查询的区别(sql-query和query),但使用时都是用Query,而不是SQLQuery

    Query query=session.getNamedQuery("selProducts");

    query.setParameter("begin",2);

    query.setParameter("end",5);

     

    如果返回一个标量,你必须使用<return-scalar>元素来指定字段的别名和 Hibernate类型

    <sql-query name="mySqlQuery">
        <return-scalar column="name" type="string"/>
        <return-scalar column="age" type="long"/>
        SELECT p.NAME AS name,
               p.AGE AS age,
        FROM PERSON p WHERE p.NAME LIKE 'Hiber%'
    </sql-query>

    6.调用存储过程

    oracle创建如下存储过程:

    1 create or replace procedure getLog(record_ref out sys_refcursor,inputId in log201112.id%type)
    2 AS
    3 begin
    4 open record_ref for
    5 select * from log201112 where id=inputId;
    6 end getLog;
    7 /

    映射文件中配置命名sql查询如下:

    1     <sql-query name="getLog" callable="true">
    2 <return alias="log201112" class="com.tazi.domin.Log"/>
    3 {call getLog(?,:inputId)}
    4 </sql-query>

    注释:第一个?是out类型参数,第二个是in参数

    代码如下:

    1         Query query=session.getNamedQuery("getLog");
    2 query.setInteger("inputId", 2);
    3 Log log=(Log)query.uniqueResult();
    4 System.out.println(log.getCreateTime());

    Hibernate使用JDBC

    创建存储过程updateLogContent,在oracle中

    1 create or replace procedure updateLogContent(
    2 inputId in log201112.id%type,newContent in log201112.content%type)
    3 AS
    4 begin
    5 update log201112 set content=newContent where id=inputId;
    6 end updateLogContent;
    7 /

    原来的session.connection()已经建议不使用,改为Work,session调用Work的execute会自动把conn传递作参数。

     //Work是一个接口
    Work work=new Work() {
    public void execute(Connection conn) throws SQLException {

    // TODO Auto-generated method stub
    String procedure="{call updateLogContent(?,?)}";

    CallableStatement cstmt=conn.prepareCall(procedure);
    //cstmt.registerOutParameter(1, OracleTypes.CURSOR);
    cstmt.setInt(1, 2);

    cstmt.setString(2, "新的日志");
    cstmt.executeUpdate();
    }
    };
    session.doWork(work);



  • 相关阅读:
    GDOI模拟赛Round 1
    Codeforces 241B
    Codeforces 325E
    Codeforces 235E
    Codeforces 293B
    Codeforces 263E
    快速傅里叶变换FFT
    后缀自动机
    NOI2011 Day2
    NOI2014 Day2
  • 原文地址:https://www.cnblogs.com/tazi/p/2293693.html
Copyright © 2020-2023  润新知