Struts2.1.6+Spring2.5.6+Hibernate3.3.2+mysql整合+分页模板(2)

六、定义基本类

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<String, Object> request;	//一般少用,因为value stack里就是request
	public Map<String, Object> session;
	public Map<String, Object> application;//基本不用。可以放数据库或者放在一个CLASS里面
	public HttpServletResponse response;


//ServletActionContext.getRequest()同样也可以直接去的request

	public void setRequest(Map<String, Object> request) {
		this.request=request;
	}
	
	public void setSession(Map<String, Object> session) {
		this.session=session;
	}

	public void setApplication(Map<String, Object> 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 <T> void delete(Class<T> entityClass,Object entityId);	

	//删除多条记录
	public <T> void delete(Class<T> entityClass,Object[] entityIds);

	//查找指定ID的实体类数据
	public <T> T find(Class<T> entityClass,Object entityId);	//在方法上定义泛型需要在方法上写<X>,,第一个T是定义泛型,第2个T是返回类型
	
	/**
	 * 获得分页数据
	 * QueryResult<T> 泛型定义在类上。因为需要返回查询的数据List,和查询的总条数,所以需要自定义类型返回2个数据
	 * @param <T>	泛型
	 * @param entityClass 实体类
	 * @param firstIndex 开始索引
	 * @param maxResult 需要获取的记录数
	 * @param wherejpql where条件语句
	 * @param queryParams 条件语句参数
	 * @param orderby 排序,LinkedHashMap先进先出,使用这个是因为先进去的放到第一位,order by key1 desc,key2 asc	
	 * @return
	 */
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstIndex, int maxResult,	String wherejpql,Object[] queryParams,LinkedHashMap<String, String> orderby);
	
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstIndex, int maxResult,String wherejpql,Object[] queryParams);
	
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstIndex, int maxResult,LinkedHashMap<String, String> orderby);
	
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstIndex, int maxResult);
	
	public <T> QueryResult<T> getScrollData(Class<T> 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 <T> void delete(Class<T> entityClass,Object entityid) {
		delete(entityClass, new Object[]{entityid});	//调用下面的方法
	
	}
	
	
	//删除多条记录
	public <T> void delete(Class<T> 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> T find(Class<T> entityClass, Object entityId) {	
		return (T) hibernateTemplate.get(entityClass,(Serializable) entityId);
	}
	
	
	/**
	 * 获得分页数据
	 * QueryResult<T> 泛型定义在类上。因为需要返回查询的数据List,和查询的总条数,所以需要自定义类型返回2个数据
	 * @param <T>	泛型
	 * @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<String , String> orderby=new LinkedHashMap<String, String>();
	 * orderby.put("id", "asc");
	 * QueryResult<TestVo> 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 <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult,
			String wherejpql,Object[] queryParams,LinkedHashMap<String, String> orderby) {
		
		QueryResult qr = new QueryResult<T>();	//定义保存数据类型
		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 <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult,LinkedHashMap<String, String> orderby) {
		return getScrollData(entityClass,firstindex,maxresult,null,null,orderby);
	}
	
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult,String wherejpql,Object[] queryParams) {
		return getScrollData(entityClass,firstindex,maxresult,wherejpql,queryParams,null);
	}

	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult) {
		return getScrollData(entityClass,firstindex,maxresult,null,null,null);
	}

	public <T> QueryResult<T> getScrollData(Class<T> entityClass) {
		return getScrollData(entityClass,-1,-1);	//主方法定义-1为不分页
	}



	/**
	 * 获取实体类的名称
	 * @param <T>
	 * @param entityClass
	 * @return
	 */
	protected <T> String getEntityName(Class<T> 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<String, String> 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<queryParams.length;i++){		//JPA的问号索引是从1开始的,而HibernateTemplate是从0开始的	
				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<User> getScrollData(int firstindex, int maxresult,String wherejpql,Object[] queryParams,LinkedHashMap<String, String> orderby) {
		
		QueryResult<User> qr=userDAO.getScrollData(User.class, firstindex, maxresult, wherejpql, queryParams, orderby);
		return qr;	
	}
}

 

 

(待续)

你可能感兴趣的:(DAO,spring,mysql,Hibernate,ssh)