首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Hibernate在from子句中施用子查询

2012-10-16 
Hibernate在from子句中使用子查询最近用到了Hibernate来作为数据处理部分的框架,离线criteria的确很好用,

Hibernate在from子句中使用子查询
    最近用到了Hibernate来作为数据处理部分的框架,离线criteria的确很好用,但在分页上确实让人头疼。要想分页就需要记录的总条数,如果只是一般的查询只需要

/** * 因为需要修改sql,就要传入你新的sql,criteria必须是绑定session的 * 因为我们用到了session * @param sql * @param criteria * @return */public static List<List> wrapAndExecute(String sql, Criteria criteria) {ResultSet rs = null;//最后的结果集PreparedStatement ps = null;//我们自己的PreparedStatementConnection connection = null;//session中获取的连接try {//先转型CriteriaImpl criteriaImpl = (CriteriaImpl) criteria;//获取SessionImplementor类型的sessionSessionImplementor session = criteriaImpl.getSession();//获取factorySessionFactoryImplementor factory = session.getFactory();//获取CriteriaQueryTranslator对象,按照Hibernate源码中的方式生成CriteriaQueryTranslator translator = new CriteriaQueryTranslator(factory, criteriaImpl, criteriaImpl.getEntityOrClassName(), CriteriaQueryTranslator.ROOT_SQL_ALIAS);//从CriteriaQueryTranslator对象中获取保存参数的QueryParameters对象QueryParameters queryParameters = translator.getQueryParameters();//从factory中获取implementors,一般只用一个String[] implementors = factory.getImplementors(criteriaImpl.getEntityOrClassName());//因为只用一个,所以只需要一个loader,按照Hibernate源码中的方式新建//注意有些地方由于非public所以需要用反射,反射部分代码就不贴了,注意invokeMethod要从子类找到父类,直到object//因为有些方法是写在父类中的Loader loader = new CriteriaLoader((OuterJoinLoadable) ReflectUtil.invokeMethod(session,"getOuterJoinLoadable", new Class[] { String.class }, new Object[] { implementors[0] }), factory,criteriaImpl, implementors[0], ((SessionImpl) session).getLoadQueryInfluencers());//按照Hibernate源码方法获取walkerCriteriaJoinWalker walker = new CriteriaJoinWalker((OuterJoinLoadable) factory.getEntityPersister(implementors[0]), translator, factory, criteriaImpl, criteriaImpl.getEntityOrClassName(), session.getLoadQueryInfluencers());//获取了criteria的sqlString criteriaSql = walker.getSQLString();//用传入的sql代替,注意PLACEHOLDER代表criteriaSql的占位符sql = sql.replace(PLACEHOLDER, criteriaSql);//获取session中的连接connection = session.getJDBCContext().getConnectionManager().getConnection();//构建新的PreparedStatementps = connection.prepareStatement(sql);//注意一定要过滤过参数才能绑定queryParameters.processFilters(criteriaSql, session);//通过反射绑定参数ReflectUtil.invokeMethod(loader, "bindParameterValues", new Class[] { PreparedStatement.class,QueryParameters.class, int.class, SessionImplementor.class }, new Object[] { ps, queryParameters,1, session });//获取结果集rs = session.getBatcher().getResultSet(ps);......

呼,好了,终于抠出了criteria的东西了。
最后值得注意的是,由于ResultSet和PreparedStatement是自己创建的,所以需要自己维护,就是要注意关闭咯。至于connection由于是session中获取的,可以不用管,否则这个session如果还有其他操作connection关了就要抛错了。 1 楼 liuluoqiu 2012-06-15   lz,这样是可以获得原生sql,但是里面的参数是?,如何才能显示?中内容啊 2 楼 buptchenliang 2012-09-05   liuluoqiu 写道lz,这样是可以获得原生sql,但是里面的参数是?,如何才能显示?中内容啊
本文目的不是获取完全的sql,只是通过这种方式个性化sql。当然你想获取到完整的sql也是可以的,所有的参数都在QueryParameters 这个类里,你完全可以从这个对象中将每个参数获取,结合带有?的sql就可以得到完整的sql了。

热点排行