1、 关于在Spring中嵌入hibernate使用sql语句问题:
在使用hibernate的时候,有的时候需要用sql语句来执行,而HibernateDaoSupport方便了操作后,执行sql时候遇到不能执行的问题,
下列方法是一个内部类来执行sql,可以写一个通用方法来执行sql,通常如果没有必要尽量不使用sql,但是有的时候就必须使用了,就想下列的查询分组查询,不想在hibernate中使用一对多关系,而又必须使用group by 哪么只能使用下列方式,
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public List<KnowledgeQueryBean> getKnowledgeQueryInfo() {
List<KnowledgeQueryBean> ListAll = new ArrayList<KnowledgeQueryBean>();
final String sql = "SELECT ky.KNOWLEDGEQUERYID,ky.TITILE,ky.CREATEDATE,eu.USERNAME ,ky.USERID,COUNT(kyr.KNOWLEDGEQUERYID) AS COUNT"+
" FROM KNOWLEDGEQUERY ky LEFT JOIN KNOWLEDGEQUERYANSWER kyr ON ky.KNOWLEDGEQUERYID = kyr.KNOWLEDGEQUERYID" +
" LEFT JOIN EOM_USER eu ON ky.USERID = eu.USER_ID"+
" GROUP BY ky.KNOWLEDGEQUERYID,ky.TITILE,ky.CREATEDATE,eu.USERNAME,ky.USERID ORDER BY ky.CREATEDATE DESC";
ListAll = (List<KnowledgeQueryBean>)this.getHibernateTemplate().execute(
new HibernateCallback(){
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Connection con = session.connection();
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
List<KnowledgeQueryBean> all = new ArrayList<KnowledgeQueryBean>();
while(rs.next()){
KnowledgeQueryBean kqb = new KnowledgeQueryBean();
kqb.setKnowledgeQueryId( rs.getLong("KNOWLEDGEQUERYID"));
kqb.setTitle(rs.getString("TITILE"));
kqb.setCreateDate(rs.getDate("CREATEDATE"));
kqb.setContent(rs.getString("USERNAME"));
kqb.setUserId(rs.getLong("USERID"));
kqb.setCount(rs.getInt("COUNT"));
all.add(kqb);
}
rs.close();
ps.close();
session.flush();
session.close();
return all;
}
}
);
return ListAll;
}
3、 我遇到了很多人——他们既想赶时髦用Hibernate来完成ORM;同时又意图节约学习成本,使用原来纯JDBC时候的书写方式……
Hibernate执行原生SQL语句的方法
如下代码:
(注意该类继承自HibernateDaoSupport ,要在applicationContext.xml中将sessionFactory注入此类中)
public class DaoUtil extends HibernateDaoSupport {
public Object executeMySQL(final String sql){
System.out.println(sql);
return getHibernateTemplate().execute( new HibernateCallback(){
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Connection CurConn = session.connection();
PreparedStatement ps = CurConn.prepareStatement(sql);
ps.execute();
ps.close();
session.flush();
return null;
}
} );
}
public Object executeBetchSQL(final ArrayList sqlList){
return getHibernateTemplate().execute( new HibernateCallback(){
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Connection CurConn = session.connection();
int count = sqlList.size();
for(int i=0;i//System.out.println(sqlList.get(i));
PreparedStatement ps = CurConn.prepareStatement(sqlList.get(i));
ps.execute();
ps.close();
session.flush();
}
return null;
}
} );
}
public static DaoUtil getFromApplicationContext(
ApplicationContext ctx) {
return (DaoUtil) ctx.getBean("DaoUtil");
}
}
2、 再论Spring中的AOP
我在《Spring 初体验》一文中曾提到过Aop , 但是那种方式的AOP写的通知还必须得实现 MethodInterceptor 接口, 今天介绍的这个不用实现接口, 有两种方式实现同样的功能, 一个是使用配置applicationContext.xml的方式, 另外一种则是使用注脚(Annotation)。
现贴出我的练习代码:
Work.java ————接口
public interface Work {
public String doWork();
}
WorkImpl.java ——实现类
public class WorkImpl implements Work {
public String doWork() {
System.out.println("正在工作.....");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("^_^ ^_^ ");
return "ok";
}
}
ArroundLog.java ————切面代码
@Aspect
/**
* 编写切面代码
* @author Administrator
*
*/
public class ArroundLog {
/**
* 在WorkImpl调用之前调用前, 提供日志服务
*/
@Before ("execution(* cn.com.aop.version2.WorkImpl.*(..))")
public Object printLog(){
System.out.println("正准备工作....");
return null;
}
}
Test.java ————测试类
public class Test {
public static void main(String[] args) {
ApplicationContext beanContext = new ClassPathXmlApplicationContext(
new String[]{"applicationContext.xml"} );
Work work = (Work)beanContext.getBean("realWork");
work.doWork();
}
}
配置文件:
!-- 配置真实对象 -->
<bean id="realWork" class="cn.com.aop.version2.WorkImpl" scope="prototype"></bean>
<!-- 配置通知 -->
<bean id="beforeLog" class="cn.com.aop.version2.ArroundLog"></bean>
<!-- 自动产生代理对象 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!-- spring aop 配置 -->
<aop:config>
<!-- 切面配置 -->
<aop:aspect id="myAop" ref="beforeLog">
<!-- 定义连接点 (用于指定那些方法调用时自动调用beforeLog) -->
<aop:pointcut id="method" expression="execution(* cn.com.aop.version2.WorkImpl.*(..))"/>
<!-- 使用通知为方法自动提供服务 -->
<aop:before method="printLog" pointcut-ref="method"/><!-- 在调用method指定的方法之前调用 -->
</aop:aspect>
</aop:config>
注脚的方式:
在ArroungLog.java中加入注脚:
@Aspect ————加在类前
@Before ("execution(* cn.com.aop.version2.WorkImpl.*(..))") ————加在要调用的服务方法前