简洁的spring ,hibernate web架构模式
大家用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; } } }