主要利用Hibernate中封装的一个转换器实现类:QueryTranslatorImpl,
hql语句中无参数时,用下面的方法:
/**
* 将hql语句转换为sql语句,无参数
*
* @param hql
* 要转换的hql语句
* @return 可执行的sql语句,当返回null,可以通过getResultMsg()方法查看处理结果信息
*/
public static String transHqlToSql(String hql) {
// 当hql为null或空时,直接返回null
if (hql == null || hql.equals("")) {
resultMsg = nullMsg;
return null;
}
// 获取当前session
Session session = DbUtil.currentSession();
// 得到session工厂实现类
SessionFactoryImpl sfi = (SessionFactoryImpl) session
.getSessionFactory();
// 得到Query转换器实现类
QueryTranslatorImpl queryTranslator = new QueryTranslatorImpl(hql, hql,
Collections.EMPTY_MAP, sfi);
queryTranslator.compile(Collections.EMPTY_MAP, false);
// 得到sql
String sql = queryTranslator.getSQLString();
// 关闭session
DbUtil.closeSession();
return sql;
}
public class DbUtil {
private static final SessionFactory sessionFactory;
public static final ThreadLocal session = new ThreadLocal();
private static Configuration configuration = new Configuration();
private static String configFile = "/hibernate.cfg.xml";
static {
try {
sessionFactory = configuration.configure(configFile)
.buildSessionFactory();
} catch (Throwable ex) {
ex.printStackTrace();
throw new ExceptionInInitializerError(ex);
}
}
public static Session currentSession() throws HibernateException {
Session s = (Session) session.get();
if (s == null || !s.isOpen()) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
}
在hibernate.cfg.xml配置文件中加入:
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
可在控制台打印出格式化后的HQL语句,然后可使用上面的方法转为可执行的SQL语句,在其中有用到sql函数时,要与数据源对应,比如nvl()函数用于Oracle数据库,在mysql数据库中用ifnull()函数,否则可能报错,在转换sql语句时尽量消除别名,以下为消除as后别名的方法:
/**
* 删除sql中as后的别名
* hql转换后的别名默认为:as col_x_0_ (x 为从0开始的数字)
* @param sql
* @return
*/
public static String delByName(String sql) {
int asNum = getCount(sql, "as");
for (int i = 0; i <= asNum; i++) {
sql = sql.replaceAll("as col_" + String.valueOf(i) + "_0_", "");
}
return sql;
}
public static int getCount(String str, String scan) {
int count = 0;
int index = 0;
while (((index = str.indexOf(scan)) != -1)) {
// 想个办法截取字符串中查找字符,并将查找当前匹配字符之后的字符串重新
// 赋值给字符串
str = str.substring(index + 1);
count++;
}
return count;
}