对于SERVICE层有哪些是可以被公共出来的东西?
1.对于单张表的增、删、改、查(单条查、批量查、分页查)功能
作用: 所有对单张表的crud操作,都可以通过通用Mapper来简化代码
可参考day98_ssm中第五天和第六天
讲通用Mapper之前我们先讲动态代理Mapper,动态代理Mapper就是不需要再写具体的Mapper接口实现了,直接通过Mapper接口+方法和Mapper映射文件相关联
Mapper接口的动态代理实现,需要满足以下条件:
而通用Mapper则更简单,只有自定义的Mapper接口实现了Mapper
功能: 对于单张表的增、删、改、查(单条查、批量查、分页查)功能
两个点需要注意:
在通用service中,我们并不知道返回值具体是什么,那怎么办?写Object,太原始了,之后还要强转,对了.我们可以使用泛型,那么我们应该是定义泛型类还是单独定义泛型方法,答案是泛型类,所有方法都能用这个泛型
@SuppressWarnings("unchecked")
public abstract class BaseService {
public abstract Mapper getMapper();
// 当前Service上泛型的字节码对象
private Class clazz;
{
// 读取当前类上的泛型
ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
clazz = (Class) type.getActualTypeArguments()[0];
}
/**
* 根据主键进行查询
* @param id
* @return
*/
public T queryById(Long id){
return this.getMapper().selectByPrimaryKey(id);
}
/**
* 查询全部
* @return
*/
public List queryAll(){
return this.getMapper().select(null);
}
/**
* 根据条件查询1条数据。
* @param record
* @return
*/
public T queryOne(T record){
return this.getMapper().selectOne(record);
}
/**
* 根据条件查询多条数据
* @param record
* @return
*/
public List queryListByWhere(T record){
return this.getMapper().select(record);
}
/**
* 根据条件分页查询
* @param record
* @return
*/
public PageInfo queryPageListByWhere(T record, Integer page, Integer rows){
PageHelper.startPage(page, rows);
List list = this.getMapper().select(record);
return new PageInfo<>(list);
}
/**
* 插入数据
* @param record
* @return
*/
public Integer save(T record){
record.setCreated(new Date());
record.setUpdated(record.getCreated());
return this.getMapper().insert(record);
}
/**
* 插入数据,只操作record中的非空属性
* @param record
* @return
*/
public Integer saveSelective(T record){
record.setCreated(new Date());
record.setUpdated(record.getCreated());
return this.getMapper().insertSelective(record);
}
/**
* 更新数据
* @param record
* @return
*/
public Integer update(T record){
record.setUpdated(new Date());
// TODO 这里如何解决用户传入的created属性的问题?
return this.getMapper().upateByPrimaryKey(record);
}
/**
* 更新数据,只操作record中的非空属性
* @param record
* @return
*/
public Integer updateSelective(T record){
record.setUpdated(new Date());
// 保证created字段不会被修改
record.setCreated(null);
return this.getMapper().updateByPrimaryKeySelective(record);
}
/**
* 根据主键进行删除
* @param id
* @return
*/
public Integer deleteById(Long id){
return this.getMapper().deleteByPrimaryKey(id);
}
/**
* 批量删除
* @param id
* @return
*/
public Integer deleteByIds(String property, List
我们可以在自己的service子类中定义对应的Mapper,当然既然用了通用Mapper,我们可以更简洁的,在通用service中注入Mapper,那怎么注入呢,因为@Autowired是通过类型和id注入,如果没有类型压根无法注入
所有的通用Mapper都实现了Mapper
public class BaseService {
@Autowired
public Mapper service;
}
想法固然是美好的,但是当之后我们自定义的Mapper越来越多后,同一个接口下可能有很多子类,Spring无法自我判断,所以我们得想个更好的方法
既然在父类中,我们并不知道Mapper应该是什么泛型,但是我们在子类实现时,是指定应该用什么Mapper,所以我们可以在通用service中定义一个抽象方法,当子类调用父类方式时,因为是抽象方法,所以实际上还是调用子类中的提供的Mapper,但优点是父类中方法能引用这个Mapper
public abstract class BaseService {
public abstract Mapper getMapper();
......
}
注意哦,抽象方法的存在是为了让人实现的,所以必须是public
其中在save方法时,我们除了用户添加的信息外,还有设计Updated和Created的时间,这两个值也应该写在通用service中,此时是要我们T extends BasePojo就能使用BasePojo中方法设置值