当我们使用spring mybatis Mapper 自动扫描接口机制,生成Dao ,Mybatis 可以映射自动生成Mapper ,和Bean,XMl 文件。Service实现类可以通过注入相应的Mapper 即可调用Mapper中的方法,但是如果在controller 层或者其他Service类引入其他Service类,想调用自动生成的Mapper方法时,需要在Service 重新封装方法,才可以调用基础Mapper 方法,这就很麻烦。所以在此,构造公用的Service 父类,所有子类继承,即可调用Mapper 原生生成的方法,从而达到在Service中控制事务,并且不用ServiceImpl 实现类,重新封装方法
BaseService 接口,接口的方法和自动生成的Mapper 相对应
package com.ancoin.offical.service.base; import java.util.List; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.session.RowBounds; public interface BaseService<T> { /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ long countByExample(Object ex); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ int deleteByExample(Object ex); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ int deleteByPrimaryKey(Object Id); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ int insert(T entity); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ int insertSelective(T entity); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ List<T> selectByExampleWithRowbounds(Object ex, RowBounds rowBounds); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ List<T> selectByExample(Object ex); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ T selectByPrimaryKey(Object Id); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ int updateByExampleSelective(T record, Object example); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ int updateByExample(T record, Object example); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ int updateByPrimaryKeySelective(T record); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_coin_info * * @mbg.generated */ int updateByPrimaryKey(T entity); }
BaseServiceImpl 实现类
package com.ancoin.offical.service.base.impl; import java.lang.reflect.ParameterizedType; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ibatis.session.RowBounds; import org.apache.ibatis.session.SqlSession; import org.mybatis.spring.mapper.MapperFactoryBean; import org.springframework.util.StringUtils; import com.ancoin.offical.config.SpringContextAware; import com.ancoin.offical.service.base.BaseService; /** * * @author LZH 2018-02-24 * * @param <T> */ public abstract class BaseServiceImpl<T> implements BaseService<T>{ private Class<T> entityclass; private String NameSpace; private SqlSession sqlSession; public BaseServiceImpl() { entityclass =(Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; try { NameSpace = "com.ancoin.offical.dao.def."+entityclass.getSimpleName()+"Mapper."; String beanName = StringUtils.uncapitalize(entityclass.getSimpleName()+"MapperEx"); System.out.println(beanName); MapperFactoryBean mapperFactoryBean = SpringContextAware.getBean("&"+beanName); sqlSession = mapperFactoryBean.getSqlSession(); } catch (Exception e) { e.printStackTrace(); } } @Override public long countByExample(Object ex) { Object obj = sqlSession.selectOne(NameSpace+"countByExample", ex); if(obj==null)return 0; else { return (long) obj; } } @Override public int deleteByExample(Object ex) { return sqlSession.delete(NameSpace+"deleteByExample", ex); } @Override public int deleteByPrimaryKey(Object Id) { return sqlSession.delete(NameSpace+"deleteByPrimaryKey", Id); } @Override public int insert(Object entity) { return sqlSession.insert(NameSpace+"insert", entity); } @Override public int insertSelective(Object entity) { return sqlSession.insert(NameSpace+"insertSelective", entity); } @Override public List selectByExampleWithRowbounds(Object ex, RowBounds rowBounds) { return sqlSession.selectList(NameSpace+"selectByExampleWithRowbounds", ex, rowBounds); } @Override public List<T> selectByExample(Object ex) { return sqlSession.selectList(NameSpace+"selectByExample", ex); } @Override public T selectByPrimaryKey(Object Id) { return sqlSession.selectOne(NameSpace+"selectByPrimaryKey",Id); } @Override public int updateByExampleSelective(Object record, Object example) { Map params = new HashMap(); params.put("record", record); params.put("example", example); return sqlSession.update(NameSpace+"updateByExampleSelective", params); } @Override public int updateByExample(Object record, Object example) { Map params = new HashMap(); params.put("record", record); params.put("example", example); return sqlSession.update(NameSpace+"updateByExample", params); } @Override public int updateByPrimaryKeySelective(Object record) { return sqlSession.update(NameSpace+"updateByPrimaryKeySelective", record); } @Override public int updateByPrimaryKey(Object entity) { return sqlSession.update(NameSpace+"updateByPrimaryKey", entity); } }
这里的NameSpace 是相应类下面的xml 文件配置的NameSpace ,配置不一样,这里的值不一样,哟有一定的规律。beanName这里表示MapperFactoryBean 给每个Mapper生成的动态代理实现,Mapper 在扫描实例化时,会给每个Mapper生成一个MapperFactoryBean 代理实现类,如果不知道,可以 改一下 ,改成MapperFactoryBean mapperFactoryBean = SpringContextAware.getBean(MapperFactoryBean .class); 让它报错,就可以知道当前有多少个Mapper 代理实现类。
我这里在前面加“&”是因为报错时有带&。上面写法注意是为了拿到当前的sqlSession,只要拿到sqlSession 下面一切都好办