六、定义基本类
1)定义Action基本类-主要定义request,session等
BaseAction.java
package ssh.base;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
public class BaseAction extends ActionSupport implements RequestAware,SessionAware, ApplicationAware,ServletResponseAware{
private static final long serialVersionUID = 4818541693118631758L;
public Map request;//一般少用,因为value stack里就是request
public Map session;
public Map application;//基本不用。可以放数据库或者放在一个CLASS里面
public HttpServletResponse response;
//ServletActionContext.getRequest()同样也可以直接去的request
public void setRequest(Map request) {
this.request=request;
}
public void setSession(Map session) {
this.session=session;
}
public void setApplication(Map application) {
this.application=application;
}
public void setServletResponse(HttpServletResponse response) {
this.response=response;
}
}
2)定义接口DAO类,主要定义CURD,分页等基本相同的接口
DAO.java
package ssh.base;
import java.util.LinkedHashMap;
import ssh.utils.QueryResult;
public interface DAO {
//保存数据
public void save(Object entity);
//更新数据
public void update(Object entity);
//删除单条记录
public void delete(Class entityClass,Object entityId);
//删除多条记录
public void delete(Class entityClass,Object[] entityIds);
//查找指定ID的实体类数据
public T find(Class entityClass,Object entityId);//在方法上定义泛型需要在方法上写,,第一个T是定义泛型,第2个T是返回类型
/**
* 获得分页数据
* QueryResult 泛型定义在类上。因为需要返回查询的数据List,和查询的总条数,所以需要自定义类型返回2个数据
* @param 泛型
* @param entityClass 实体类
* @param firstIndex 开始索引
* @param maxResult 需要获取的记录数
* @param wherejpql where条件语句
* @param queryParams 条件语句参数
* @param orderby 排序,LinkedHashMap先进先出,使用这个是因为先进去的放到第一位,order by key1 desc,key2 asc
* @return
*/
public QueryResult getScrollData(Class entityClass,int firstIndex, int maxResult,String wherejpql,Object[] queryParams,LinkedHashMap orderby);
public QueryResult getScrollData(Class entityClass,int firstIndex, int maxResult,String wherejpql,Object[] queryParams);
public QueryResult getScrollData(Class entityClass,int firstIndex, int maxResult,LinkedHashMap orderby);
public QueryResult getScrollData(Class entityClass,int firstIndex, int maxResult);
public QueryResult getScrollData(Class entityClass);
}
3)定义实现DAO基本接口的DAOImpl的实现类,供其他实现类直接继承
而且必须写@Component注入给Spring管理,然后注入hibernateTemplate,使用protected,其他类继承后可以直接使用
DaoSupport.java
package ssh.base;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.List;
import javax.annotation.Resource;
import javax.persistence.Entity;
import ssh.utils.QueryResult;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;
//定义抽象类继承DAO,抽象出所有实体通用的方法,方便其他类继承就可以了,abstract定义了只能继承。
@Component//放到Spring里,让Spring管理
public abstract class DaoSupport implements DAO {
//注入hibernateTemplate,使用protected,其他类继承后可以直接使用
public HibernateTemplate hibernateTemplate;
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
@Resource //注入hibernateTemplate
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
/**保存数据
* 调用方法:save(new User("shazhuzhu",20)
*/
public void save(Object entity) {
hibernateTemplate.save(entity);
}
/**更新数据
* 调用方法:update(new User(1,"shazhuzhu",20); 其中1为ID
*/
public void update(Object entity) {
hibernateTemplate.update(entity);//把游离状态的实体BENA同步到数据库
}
/**删除单条记录
* 调用方法:delete(User.class,1); 其中1为ID
*/
public void delete(Class entityClass,Object entityid) {
delete(entityClass, new Object[]{entityid});//调用下面的方法
}
//删除多条记录
public void delete(Class entityClass,Object[] entityids) {
for(Object id:entityids){
T t=find(entityClass,id);调用下面的find方法先把实体类查找出来,然后在DEL,这样才能通过ID删除数据
if(t!=null)//先判断需要删除的数据是否存在
hibernateTemplate.delete(t);
}
}
/**查询指定ID的记录
* 调用方法:find(User.class,1); 其中1为ID
*/
@SuppressWarnings("unchecked")
public T find(Class entityClass, Object entityId) {
return (T) hibernateTemplate.get(entityClass,(Serializable) entityId);
}
/**
* 获得分页数据
* QueryResult 泛型定义在类上。因为需要返回查询的数据List,和查询的总条数,所以需要自定义类型返回2个数据
* @param 泛型
* @param entityClass 实体类
* @param firstIndex 开始索引 firstIndex和maxResult都为-1时代表不分页
* @param maxResult 需要获取的记录数
* @param wherejpql where条件语句
* @param queryParams 条件语句参数
* @param orderby 排序,LinkedHashMap先进先出,使用这个是因为先进去的放到第一位,order by key1 desc,key2 asc
* @return
*
* 调用方法
* LinkedHashMap orderby=new LinkedHashMap();
* orderby.put("id", "asc");
* QueryResult qr=testDAO.getScrollData(TestVo.class, 1, 10,"o.name=? and o.title=?",new Object[]{"a","1"},orderby);
* for (TestVo q : qr.getResultlist()) {
* System.out.println(q.getName());
* }
* System.out.println(qr.getTotalrecord());
*/
@SuppressWarnings("unchecked")//不检查类型,不然会有黄色线提示错误。
public QueryResult getScrollData(Class entityClass,int firstindex, int maxresult,
String wherejpql,Object[] queryParams,LinkedHashMap orderby) {
QueryResult qr = new QueryResult();//定义保存数据类型
String entityname = getEntityName(entityClass);//获取实体类名称,方法下面定义了
String hql="select o from "+entityname+" o " + (wherejpql==null? "" :"where " + wherejpql) + buildOrderby(orderby);
System.out.println(hql);
qr.setResultlist(getListForPage(hql, firstindex, maxresult, queryParams));//调用hibernateTemplate的扩张方法进行分页处理
String hql2="select count(o) from "+entityname+" o " + (wherejpql==null? "" :"where " + wherejpql);
Long total=(Long) hibernateTemplate.find(hql2,queryParams).get(0);//查询总记录数
qr.setTotalrecord(total);
return qr;
}
/**
* HibernateTemplate 只支持 .setMaxResults(int) 方法。
* 因此,做 Spring+Hibernate 分页处理要使用到一个接口 org.springframework.orm.hibernate3.HibernateCallback
* 来灵活操作数据库,该接口中有一个未实现的方法 Object doInHibernate (Session session),用以获得并利用 session 进行操作(自动创建、销毁)。
* 分页通用方法
* @param sql HQL查询语句
* @param firstindex 起始记录下标
* @param maxresult 读取记录数
* @return List 结果集
*/
@SuppressWarnings("unchecked")
public List getListForPage(final String hql, final int firstindex, final int maxresult,final Object[] queryParams) {
try {
List list = hibernateTemplate.executeFind(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException,SQLException {
Query query = session.createQuery(hql);
if(firstindex!=-1 && maxresult!=-1){//方便设置-1时不分页
query.setFirstResult(firstindex);
query.setMaxResults(maxresult);
}
setQueryParams(query, queryParams);//调用下面方法插入where传递过来的参数
return query.list();
}
});
return list;
} catch (RuntimeException re) {
throw re;
}
}
public QueryResult getScrollData(Class entityClass,int firstindex, int maxresult,LinkedHashMap orderby) {
return getScrollData(entityClass,firstindex,maxresult,null,null,orderby);
}
public QueryResult getScrollData(Class entityClass,int firstindex, int maxresult,String wherejpql,Object[] queryParams) {
return getScrollData(entityClass,firstindex,maxresult,wherejpql,queryParams,null);
}
public QueryResult getScrollData(Class entityClass,int firstindex, int maxresult) {
return getScrollData(entityClass,firstindex,maxresult,null,null,null);
}
public QueryResult getScrollData(Class entityClass) {
return getScrollData(entityClass,-1,-1);//主方法定义-1为不分页
}
/**
* 获取实体类的名称
* @param
* @param entityClass
* @return
*/
protected String getEntityName(Class entityClass) {
String entityname=entityClass.getSimpleName();//如果实体类上面的@Entity(name=xxx)没有指定名称,直接为默认类名称
Entity entity=entityClass.getAnnotation(Entity.class);//获取@Entity注解
if(entity.name()!=null&&!"".equals(entity.name())){//判断注解的name是否为空
entityname=entity.name();
}
return entityname;
}
/**
* 组装order by语句
* @param orderby
* @return //order by o.key desc,key2 asc
*/
protected String buildOrderby(LinkedHashMap orderby){
StringBuffer orderbyql=new StringBuffer("");
if(orderby!=null && orderby.size()>0 ){
orderbyql.append(" order by ");
for(String key:orderby.keySet()){//取得Map的Key的集合
orderbyql.append("o.").append(key).append(" ").append(orderby.get(key)).append(",");
}
orderbyql.deleteCharAt(orderbyql.length()-1);
}
return orderbyql.toString();
}
/**
* 为Where语句传递参数
* @param query
* @param queryParams
* o.key = ?1 and o.name=?2 这是错误的,JPA的问号索引是从1开始的,而HibernateTemplate是从0开始的,HibernateTemplate执行HQL语句时,HQL的语句中'?'号面是不带数字的
* o.key = ? and o.name=? 正确
*/
protected void setQueryParams(Query query,Object[] queryParams) {
if(queryParams!=null && queryParams.length>0){
for(int i=0;i
query.setParameter(i, queryParams[i]);//如果是JPA:i+1
}
}
}
}
七、写实体类的接口-继承基本接口DAO
UserDAO.java
package ssh.DAO;
import ssh.base.DAO;
public interface UserDAO extends DAO {
//因为继承了基本接口DAO,基本接口DAO已经定义了CURD和分页功能
}
八、写实体类的实现类-继承基本实现类DAOSupport,并继承UserDAO接口
UserDAOImpl.java
package ssh.DAOImpl;
import org.springframework.stereotype.Component;
import ssh.DAO.UserDAO;
import ssh.base.DaoSupport;
@Component
public class UserDAOImpl extends DaoSupport implements UserDAO {
//基本实现类DaoSupport已经实现基本的CURD和分页功能
}
九、定义Service的实现
1)在类前加入@Component,让spring对其初始化
2)用@Resource把userDAO注入进来
UserService.java
package ssh.service;
import java.util.LinkedHashMap;
import javax.annotation.Resource;
import ssh.utils.QueryResult;
import org.springframework.stereotype.Component;
import ssh.DAO.UserDAO;
import ssh.model.User;
@Component
public class UserService {
private UserDAO userDAO;
public UserDAO getUserDAO() {
return userDAO;
}
@Resource
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public void save(User user){
userDAO.save(user);
}
public void update(User user){
userDAO.update(user);
}
public void delete(int id){
userDAO.delete(User.class,id);
}
public User find(int id){
return userDAO.find(User.class, id);
}
/*
* 获取分页数据
*/
public QueryResult getScrollData(int firstindex, int maxresult,String wherejpql,Object[] queryParams,LinkedHashMap orderby) {
QueryResult qr=userDAO.getScrollData(User.class, firstindex, maxresult, wherejpql, queryParams, orderby);
return qr;
}
}
(待续)
分享到:
2011-02-21 18:06
浏览 1908
评论