Hibernate HQL与原生SQL


Hibernate HQL与原生SQL
2012年01月19日
  Query接口
  1.list()和iterate()方法的区别在于iterate()先通过select语句查找所有id字段的值,然后如果session缓存(一级缓存)中已经存在id对应的对象就直接添加到查询结果中,否则再根据id额外查询这条记录。
  2.Query和Criteria共同有的方法
  list(),uniqueResult(),setMaxResults(),setFirstResu lt()
  HQL
  操作的都是属性和类名,不是数据库的字段和表
  1.如果查询的类含有子类,则返回类及其子类的所有表的数据。如from java.lang.Object。
  2.query.list返回类型
  (1)."select id from Product",List list=query.list()
  (2).hql="select id,name,price from Product",则query.list()返回的类型应该转换为List
  (3).hql="select new Product(id,name,price) from Product"(前提是存在对应的构造函数),则query.list()返回的类型可以转换为List
  (4).hql="select new map(id,name,price) from Product",则List 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 list=query.list(),map中的key不再是0,1,2,而是"id","name"等。
  4.not子句用于表示查询条件的非
  from Product where not (pricec 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 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 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 list=query.list(); 3.使Hibernate直接将返回结果封装为对应的Bean类
  String sql="select * from product";
  SQLQuery query=session.createSQLQuery(sql);
  query.addEntity(Product.class);
  List list=query.list();
  或者用大括号指定要查询的字段:
  String sql="select {p.*} from product p";
  SQLQuery query=session.createSQLQuery(sql);
  query.addEntity("p",Product.class);
  List 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的映射文件中
  
  
  
  
  注意与HQL命名查询的区别(sql-query和query),但使用时都是用Query,而不是SQLQuery
  Query query=session.getNamedQuery("selProducts");
  query.setParameter("begin",2);
  query.setParameter("end",5);
  6.调用存储过程
  oracle创建如下存储过程: 1createorreplaceprocedure getLog(record_ref out sys_refcursor,inputId in log201112.id%type)
  2AS
  3begin
  4open record_ref for
  5select*from log201112 where id=inputId;
  6end getLog;
  7/
  映射文件中配置命名sql查询如下: 1
  2
  3 {call getLog(?,:inputId)} 
  4
  注释:第一个?是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中 1createorreplaceprocedure updateLogContent(
  2 inputId in log201112.id%type,newContent in log201112.content%type)
  3AS
  4begin
  5update log201112 set content=newContent where id=inputId;
  6end updateLogContent;
  7/
  原来的session.connection()已经建议不使用,改为Work,session调用Work的execute会自动把conn传递作参数。 //Work是一个接口
  Work work=new Work() {
  publicvoid 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);

猜你喜欢

转载自ntk006vz.iteye.com/blog/1363838