##更新於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; } }