`
javasss
  • 浏览: 67354 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类
最新评论

在hibernate框架下使用Transformers调用sql

 
阅读更多
People using the Criteria API have either transparently or knowingly used a ResultTransformer. A ResultTransformer is a nice and simple interface that allows you to transform any Criteria result element. E.g. you can make any Criteria result be returned as a java.util.Map or as a non-entity Bean.

Criteria TransformersImagine you have a StudentDTO class:
public class StudentDTO

   private String studentName; 
   private String courseDescription;  
   public StudentDTO() {  }       
   ...
}
Then you can make the Criteria return non-entity classes instead of scalars or entities by applying a ResultTransformer:

List resultWithAliasedBean = s.createCriteria(Enrolment.class)
     .createAlias("student", "st").createAlias("course", "co")
     .setProjection( Projections.projectionList()              
                          .add( Projections.property("st.name"), "studentName" )                  
                          .add( Projections.property("co.description"), "courseDescription" )          )         
     .setResultTransformer( Transformers.aliasToBean(StudentDTO.class) )        
      .list();
StudentDTO dto = (StudentDTO)resultWithAliasedBean.get(0);  
This is how ResultTransformer have been available since we introduced projection to the Criteria API in Hibernate 3.
It is just one example of the built in transformers and users can provide their own transformers if they so please.
Jealous programming Since I am more a HQL/SQL guy I have been jealous on Criteria for having this feature and I have seen many requests for adding it to all our query facilities.
Today I put an end to this jealousy and introduced ResultTransformer for HQL and SQL in Hibernate 3.2.
HQL TransformersIn HQL we already had a "kind" of result transformers via the ("select new" http://www.hibernate.org/hib_docs/v3/reference/en/html/queryhql.html#queryhql-select) syntax, but for returning non-entity beans it only provided value injection of these beans via its constructor. Thus if you used the same DTO in many different scenarios you could end up having many constructors on this DTO purely for allowing the "select new" functionality to work.
Now you can get the value injected via property methods or fields instead, removing the need for explicit constructors.

List resultWithAliasedBean = s.createQuery(  "select e.student.name as studentName," +  "       e.course.description as courseDescription" +  "from   Enrolment as e")
       .setResultTransformer( Transformers.aliasToBean(StudentDTO.class))  .list();

StudentDTO dto = (StudentDTO) resultWithAliasedBean.get(0);
  
SQL TransformersWith native sql returning non-entity beans or Map's is often more useful instead of basic Object[]. With result transformers that is now possible.

List resultWithAliasedBean = s.createSQLQuery(  "SELECT st.name as studentName, co.description as courseDescription " +  "FROM Enrolment e " +  "INNER JOIN Student st on e.studentId=st.studentId " +  "INNER JOIN Course co on e.courseCode=co.courseCode")
     .addScalar("studentName")  .addScalar("courseDescription")
     .setResultTransformer( Transformers.aliasToBean(StudentDTO.class))
    .list();

StudentDTO dto =(StudentDTO) resultWithAliasedBean.get(0);

  
Tip: the addScalar() calls were required on HSQLDB to make it match a property name since it returns column names in all uppercase (e.g. "STUDENTNAME"). This could also be solved with a custom transformer that search the property names instead of using exact match - maybe we should provide a fuzzyAliasToBean() method ;)
Map vs. Object[]Since you can also use a transformer that return a Map from alias to value/entity (e.g. Transformers.ALIAS_TO_MAP), you are no longer required to mess with index based Object arrays when working with a result.

List iter = s.createQuery(  "select e.student.name as studentName," +  "       e.course.description as courseDescription" +  "from   Enrolment as e")
     .setResultTransformer( Transformers.ALIAS_TO_MAP ) 
     .iterate();

String name = (Map)(iter.next()).get("studentName");

  
Again, this works equally well for Criteria, HQL and native SQL.

使用SQLQuery
对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口。最简单的情况下,我们可以采用以下形式:

List cats = sess.createSQLQuery( " select * from cats " ).addEntity(Cat. class ).list();这个查询指定了:

SQL查询字符串

查询返回的实体

这里,结果集字段名被假设为与映射文件中指明的字段名相同。对于连接了多个表的查询,这就可能造成问题,因为可能在多个表中出现同样名字的字段。下面的方法就可以避免字段名重复的问题:

List cats = sess.createSQLQuery( " select {cat.*} from cats cat " ).addEntity( " cat " , Cat. class ).list();
这个查询指定了:

SQL查询语句,它带一个占位符,可以让Hibernate使用字段的别名.

查询返回的实体,和它的SQL表的别名.

addEntity()方法将SQL表的别名和实体类联系起来,并且确定查询结果集的形态。

addJoin()方法可以被用于载入其他的实体和集合的关联.

List cats = sess.createSQLQuery(
" select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id " )
.addEntity( " cat " , Cat. class )
.addJoin( " kitten " , " cat.kittens " )
.list();
原生的SQL查询可能返回一个简单的标量值或者一个标量和实体的结合体。

Double max = (Double) sess.createSQLQuery( " select max(cat.weight) as maxWeight from cats cat " )
.addScalar( " maxWeight " , Hibernate.DOUBLE);
.uniqueResult();
除此之外,你还可以在你的hbm文件中描述结果集映射信息,在查询中使用。

List cats = sess.createSQLQuery(
" select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id " )
.setResultSetMapping( " catAndKitten " )
.list();
命名SQL查询
可以在映射文档中定义查询的名字,然后就可以象调用一个命名的HQL查询一样直接调用命名SQL查询.在这种情况下,我们不 需要调用addEntity()方法.

< sql - query name = " persons " >
< return alias = " person " class = " eg.Person " />
Select person.NAME AS {person.name},person.AGE AS {person.age},person.SEX AS {person.sex} FROM PERSON person Where person.NAME LIKE :namePattern
</ sql - query >List people = sess.getNamedQuery( " persons " ).setString( " namePattern " , namePattern)
.setMaxResults( 50 )
.list();
分享到:
评论

相关推荐

    Hibernate中Sql语句

    虽然HQL是Hibernate提供的面向对象的语言,能够方便地映射到Java对象,但在某些场景下使用原生SQL更加灵活高效,例如: - **复杂查询**:当需要执行复杂的数据库操作时,如分组、聚合、子查询等,原生SQL能更好地...

    Criteria hibernate

    在Java开发中,Hibernate是一个非常流行的持久化框架,它简化了数据库操作,使开发者能够用面向对象的方式来处理数据。本篇内容将聚焦于Hibernate中的Criteria查询,这是一种动态构建SQL查询的方法,无需直接编写SQL...

    Criteria(hibernate3.0).rar_Criteria java_criteria Hibernate_hibe

    在Java持久化框架Hibernate中,Criteria API是一种强大的查询工具,它允许开发者以面向对象的方式构建SQL查询,从而避免了直接编写SQL语句的繁琐工作。Criteria API在Hibernate 3.0版本中得到了广泛应用,提供了更...

    NHibernate 执行存储过程

    这通常比直接使用SQL查询更复杂,但在某些情况下可能是更合适的解决方案。 总的来说,NHibernate通过灵活的配置和API支持,使得在.NET应用中执行数据库存储过程变得简单而高效。开发者可以根据项目需求和团队习惯...

    Hibernate深入研究之Criteria.rar

    Hibernate作为Java领域中的一款强大持久化框架,极大地简化了数据库操作,使得开发者能够更加专注于业务逻辑,而非繁琐的SQL语句。本篇将重点探讨Hibernate中的Criteria API,这是一种面向对象的查询方式,它提供了...

Global site tag (gtag.js) - Google Analytics