##更新于2015/02/09,第三种方法方法改进,service实现上不须要加泛型java
使用通用dao和通用service能够减小代码的开发。能够将经常使用的增删改查放到通用dao中。对不一样的or框架,基本上都有本身的实现如SpringJPA的Repository就提供了经常使用的增删改查方法。而MyBatis借助代码生成工具也能够生成经常使用方法的映射spring
这里只针对Mybatis。若是使用代码生成工具,会有一个问题:每一个Mapper里面都有一些方法(增晒改查)。维护起来的话还好。只是在写service的时候会有一个问题。好比UserMapper里面有 insert(User user)
, find(Integer id)
, delete(Integer id)
等方法,则在service中也要有这些方法的实现。假设每一个Mapper有5个方法。则service也须要有5个方法的实现。若是有10个实体类。mapper能够省略(由生成工具生成),可是service有50个方法。到后期确定很差进行维护mybatis
该通用Mapper使用了Spring-mybatis。因此没有实现类,而是直接调用xml文件中的同名方法。之因此将通用Mapper抽出来主要是为了方便些通用的servicemvc
好处:具体Service实现类简单,若是本身没有特殊的方法,继承BaseServiceImpl以后不须要写任何东西app
很差之处:框架
每一个通用方法都须要传递映射参数:好比findById,若是是UserService调用,则须要这样写:userService.findById(1,UserMapper.class),这样在BaseMapperImpl中才能够经过class.getName获得映射的名称dom
并且在BaseMapperImpl中写得比较死。修改起来比较复杂ide
第一:不须要在方法上写各类泛型参数,同时也不须要在各类方法中传递映射参数工具
第二:通用dao也不须要写实现:mybatis-spring所倡导的的一致this
很差之处:
须要在每一个Service实现类中写上:
@Autowired public void setBaseMapper(UserMapper userMapper){ super.setBaseMapper(userMapper); }
并且关键的是@Autowired不能少。这个在开发过程当中很差进行限制
package cn.liuyiyou.yishop.mapper; import java.io.Serializable; public interface BaseMapper<T,ID extends Serializable> { int deleteByPrimaryKey(ID id); int insert(T record); int insertSelective(T record); T selectByPrimaryKey(ID id); int updateByPrimaryKeySelective(T record); int updateByPrimaryKeyWithBLOBs(T record); int updateByPrimaryKey(T record); }
package cn.liuyiyou.yishop.service; import java.io.Serializable; public interface BaseService<T,ID extends Serializable> { void setBaseMapper(); int deleteByPrimaryKey(ID id); int insert(T record); int insertSelective(T record); T selectByPrimaryKey(ID id); int updateByPrimaryKeySelective(T record); int updateByPrimaryKeyWithBLOBs(T record); int updateByPrimaryKey(T record); }
package cn.liuyiyou.yishop.service.impl; import java.io.Serializable; import cn.liuyiyou.yishop.mapper.BaseMapper; import cn.liuyiyou.yishop.service.BaseService; public abstract class AbstractService<T, ID extends Serializable> implements BaseService<T, ID> { private BaseMapper<T, ID> baseMapper; public void setBaseMapper(BaseMapper<T, ID> baseMapper) { this.baseMapper = baseMapper; } @Override public int deleteByPrimaryKey(ID id) { return baseMapper.deleteByPrimaryKey(id); } @Override public int insertSelective(T record) { return baseMapper.insertSelective(record); } @Override public T selectByPrimaryKey(ID id) { return baseMapper.selectByPrimaryKey(id); } @Override public int updateByPrimaryKeySelective(T record) { return baseMapper.updateByPrimaryKey(record); } @Override public int updateByPrimaryKeyWithBLOBs(T record) { return baseMapper.updateByPrimaryKeyWithBLOBs(record); } @Override public int updateByPrimaryKey(T record) { return baseMapper.updateByPrimaryKey(record); } @Override public int insert(T record) { return baseMapper.insert(record); } }
package cn.liuyiyou.yishop.mapper; import java.util.List; import org.springframework.stereotype.Repository; import cn.liuyiyou.yishop.domain.ProductCategory; @Repository public interface ProductCategoryMapper extends BaseMapper<ProductCategory, Long>{ /** * 经过父id获得类目列表 * @param praentId * @return */ List<ProductCategory> selectByParent(Long parent); }
package cn.liuyiyou.yishop.service.impl; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.liuyiyou.yishop.domain.Ad; import cn.liuyiyou.yishop.domain.Product; import cn.liuyiyou.yishop.mapper.AdMapper; import cn.liuyiyou.yishop.mapper.ProductMapper; import cn.liuyiyou.yishop.service.ProductService; @Service public class ProductServiceImpl extends AbstractService<Product,Long> implements ProductService { @Autowired private ProductMapper productMapper; @Autowired private AdMapper adMapper; //这句必需要加上。否则会报空指针异常,由于在实际掉用的时候不是BaseMapper调用,而是这个productMapper @Autowired public void setBaseMapper(){ super.setBaseMapper(productMapper); } @Override public Map<String,Object> testTwo() { Product product = productMapper.selectByPrimaryKey(1l); Ad ad = adMapper.selectByPrimaryKey(1l); Map<String,Object> map = new HashMap<String,Object>(); map.put("product", product); map.put("ad", ad); return map; } }
这一种算是第二种的改进。避免了在ServiceImpl中写@Autowired
去掉,privste BaseMapper<T,ID> baseMapper。
package cn.liuyiyou.yishop.service.impl; import java.io.Serializable; import cn.liuyiyou.yishop.mapper.BaseMapper; import cn.liuyiyou.yishop.service.BaseService; public abstract class AbstractService<T, ID extends Serializable> implements BaseService<T, ID>{ @Override public abstract BaseMapper<T, ID> getMapper() ; @Override public int deleteByPrimaryKey(ID id) { return getMapper().deleteByPrimaryKey(id); } @Override public int insert(T record) { return getMapper().insert(record); } @Override public int insertSelective(T record) { return getMapper().insertSelective(record); } @Override public T selectByPrimaryKey(ID id) { return getMapper().selectByPrimaryKey(id); } @Override public int updateByPrimaryKeySelective(T record) { return getMapper().updateByPrimaryKeySelective(record); } @Override public int updateByPrimaryKeyWithBLOBs(T record) { return getMapper().updateByPrimaryKeyWithBLOBs(record); } @Override public int updateByPrimaryKey(T record) { return getMapper().updateByPrimaryKey(record); } }
具体的Service实现。在这个里面,经过抽象的Service,来强制具体Service实现getMapper方法,而不须要在该方法上加@Autowired。
package cn.liuyiyou.yishop.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.liuyiyou.yishop.domain.Ad; import cn.liuyiyou.yishop.mapper.AdMapper; import cn.liuyiyou.yishop.mapper.BaseMapper; import cn.liuyiyou.yishop.service.AdService; import cn.liuyiyou.yishop.service.BaseService; @Service public class AdServiceImpl extends AbstractService<Ad,Long> implements AdService { @Autowired public AdMapper adMapper; @Override public BaseMapper<Ad, Long> getMapper() { return adMapper; } }
之因此记录下来的缘由是由于,在service接口上没有使用泛型
package cn.liuyiyou.springmvc.mapper; import java.io.Serializable; /** * User: liuyiyou * Date: 14-12-27 * Time: 下午11:39 */ public interface BaseMapper<T,ID extends Serializable> { //只须要这个就能够了,并不须要具体的实现,只须要在Service中设置BaseMapper T findById(ID id); Integer insert(T t); } package cn.liuyiyou.springmvc.service; import java.io.Serializable; /** * User: liuyiyou * Date: 14-12-27 * Time: 下午11:53 */ public interface BaseService <T,ID extends Serializable>{ T findById(ID id); int insert(T t); } package cn.liuyiyou.springmvc.service; import cn.liuyiyou.springmvc.mapper.BaseMapper; import java.io.Serializable; /** * User: liuyiyou * Date: 14-12-27 * Time: 下午11:54 */ public abstract class BaseServiceImpl<T,ID extends Serializable> implements BaseService<T,ID> { public abstract BaseMapper getMapper(); @Override public T findById(ID id) { return (T) getMapper().findById(id); } @Override public int insert(T t) { return getMapper().insert(t); } } package cn.liuyiyou.springmvc.service; import cn.liuyiyou.springmvc.domain.User; public interface UserService extends BaseService { boolean addUser(User user); } package cn.liuyiyou.springmvc.service; import cn.liuyiyou.springmvc.mapper.BaseMapper; import cn.liuyiyou.springmvc.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import cn.liuyiyou.springmvc.domain.User; @Service @Transactional(value="transactionManager") public class UserServiceImpl extends BaseServiceImpl implements UserService{ @Autowired private UserMapper userMapper; @Override public BaseMapper getMapper(){ return userMapper; } public boolean addUser(User user) { int reuslt = userMapper.insert(user); if (reuslt>0) return true; return false; } }