简洁的spring ,hibernate web架构模式

黑色金属 2014-07-21

大家用springhibernate,ibatis开放web应用时,所谓3层架构,Dao,service,然后web层,但是据我的经验,一个熟手的代码编写者最终大量的时间都花在业务的实现,特别是service不应为了实现基本的crud的动态参数查询而专门去写dao接口,dao实现,service接口,service实现,还没有写业务逻辑,心都已经疲了,所以这些常规的操作要把她们都封装起来,用一个很简洁的调用方式,不要为了所谓的设计而设计,要符合实际开发状态而实践高效的模式。。。(个人经验,希望大家交流)

使用这个抽象的service基类,相关领域继承她实现自己的service(个人建议实现的领域相关service应该要封装实现具体的逻辑,而不是CRUD,和一些查询),也可以空实现;

配置事务,由spring接管事务的管理。

下面代码看起来长,其实也就是几个很简单的公共方法,就能搞定日常开放的数据库操作,

把时间花在下具体的业务逻辑上,不要总是把时间化在接口和接口实现上;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import ly.tool.utils.ref.ReflectUtils;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Transactional;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.jhzp.domain.Article;
import com.jhzp.domain.base.BaseDomain;

public abstract class BaseService {
	
	protected Logger log=Logger.getLogger(getClass());

	@Autowired
	private SessionFactory sessionFactory;
	@Autowired
	private SqlMapClient sqlMapClient;

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	protected Session getHibernateSession(){
		return this.getSessionFactory().getCurrentSession();
	}
	protected HibernateTemplate getHibernateTemplate() {
		return new HibernateTemplate(this.sessionFactory);
	}

	protected SqlMapClient getSqlMapClient() {
		return sqlMapClient;
	}

	protected void setSqlMapClient(SqlMapClient sqlMapClient) {
		this.sqlMapClient = sqlMapClient;
	}
	/**
	 * ibatis 动态参数查询 ,返回的类型要在sql语句及ibatis配置文件中写好
	 */
	@Transactional(readOnly=true)
	public List ilist(String selectId,Map params) throws SQLException{
		return this.getSqlMapClient().queryForList(selectId, params);
	}
	
	/**
	 * 20140707 新增通用方法 
	 */
	@Transactional
	public void delete(BaseDomain domain,Integer id){
		Object obj=this.getHibernateSession().get(domain.getClass(),id);
		this.getHibernateSession().delete(obj);
	}
	@Transactional
	public void update(BaseDomain domain,Integer id){
		Object obj=this.getHibernateSession().get(domain.getClass(),id);
		this.getHibernateSession().update(obj);
	}
	@Transactional(readOnly=true)
	public Object getById(Class clazz,Integer id){
		return this.getHibernateSession().get(clazz, id);
	}
	@Transactional
	public void create(BaseDomain domain){
		this.getHibernateSession().save(domain);
	}
	
	@Transactional(readOnly=true)
	public List hlistByParams(Class dclazz,Map<String,Object> params){
		log.info("传递的查询参数:"+params);
		return this.queryByParam(getHibernateSession(), dclazz, params);
	}
	@Transactional(readOnly=true)
	public List hlistByHqlAndParams(String hql,Map<String,Object> params){
		return this.queryByParamAndHql(getHibernateSession(),hql, params);
	}
	
	/**
	 * hibernate 动态参数查询 ,查询参数形式只能是: name=:name,
	 * 其他形式的查询使用自定义hql的查询queryByParamAndHql
	 */
	protected List queryByParam(Session session,Class dclazz,Map<String,Object> params){
		List<String> fnamel=ReflectUtils.listPropNames(dclazz);
		Set<String> pnames=params.keySet();
		List<String> pnamel=new ArrayList<String>();
		Iterator<String> iter=pnames.iterator();
		while(iter.hasNext()){
			String pname=iter.next();
			if(null!=params.get(pname) && fnamel.contains(pname)){
				pnamel.add(pname);
			}
		}
		String hql="from "+dclazz.getSimpleName();
		if(pnamel.size()>0){
			hql=hql+" where ";
		}
		StringBuilder sdb=new StringBuilder();
		sdb.append(hql);
		int count=0;
		for(String pname:pnamel){
			if(!fnamel.contains(pname)){
				log.info(" pname: "+pname+"参数跟属性名不同,返回了,fnamel列表: "+fnamel);
				return null;
			}
			
			if(count>0){
				sdb.append(" and "+ pname+" = :"+pname);
			}else
				sdb.append(pname+" = :"+pname);
			count++;
		}
		hql=sdb.toString();
		log.info("打印生成的hql: "+hql);
		Query query=session.createQuery(hql);
		for(String pname:pnamel){
			Object obj=params.get(pname);
			if(obj instanceof String){
				query.setParameter(pname, obj);
			}else if(obj instanceof BigDecimal){
				query.setBigDecimal(pname, ((BigDecimal)obj));
			}else if(obj instanceof BigInteger){
				query.setBigInteger(pname, ((BigInteger)obj));
			}else if(obj instanceof Boolean){
				query.setBoolean (pname, ((Boolean)obj));
			}else if(obj instanceof Byte){
				query.setByte(pname, ((Byte)obj));
			}else if(obj instanceof Calendar){
				query.setCalendar(pname, ((Calendar)obj));
			}else if(obj instanceof Date){
				log.info("应用到了"+Date.class);
				query.setDate(pname, ((Date)obj));
			}else if(obj instanceof Double){
				query.setDouble(pname, ((Double)obj));
			}else if(obj instanceof Integer){
				query.setDouble(pname, ((Integer)obj));
			}else if(obj instanceof Locale){
				query.setLocale(pname, ((Locale)obj));
			}else if(obj instanceof Long){
				query.setLong(pname, ((Long)obj));
			}else{
				query.setParameter(pname, obj);
			}
			
		}
		
		return query.list();
//		return null; 
	}
	 
	/**
	 * 自定义hql,传递动态的参数
	 */
	protected List queryByParamAndHql(Session session,String hql,Map<String,Object> params){
		Query query=session.createQuery(hql);
		for(String pname:params.keySet()){
			if(hql.contains(pname)){
				Object obj=params.get(pname);
				if(obj instanceof String){
					query.setParameter(pname, obj);
				}else if(obj instanceof BigDecimal){
					query.setBigDecimal(pname, ((BigDecimal)obj));
				}else if(obj instanceof BigInteger){
					query.setBigInteger(pname, ((BigInteger)obj));
				}else if(obj instanceof Boolean){
					query.setBoolean (pname, ((Boolean)obj));
				}else if(obj instanceof Byte){
					query.setByte(pname, ((Byte)obj));
				}else if(obj instanceof Calendar){
					query.setCalendar(pname, ((Calendar)obj));
				}else if(obj instanceof Date){
					log.info("应用到了"+Date.class);
					query.setDate(pname, ((Date)obj));
				}else if(obj instanceof Double){
					query.setDouble(pname, ((Double)obj));
				}else if(obj instanceof Integer){
					query.setDouble(pname, ((Integer)obj));
				}else if(obj instanceof Locale){
					query.setLocale(pname, ((Locale)obj));
				}else if(obj instanceof Long){
					query.setLong(pname, ((Long)obj));
				}else{
					query.setParameter(pname, obj);
				}
			}
		}
		
		try {
			return query.list();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("第二查询出错了。");
			return null;
		}
	}
}

相关推荐

LetonLIU / 0评论 2020-05-29
东方咖啡屋 / 0评论 2020-01-06