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);
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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.