MybatisPlus提供了很多CRUD接口,可以直接使用这些接口来操作数据库。而不用像Mybatis那样写大量的XML文件及SQL语句。
Mapper CRUD接口
主要关键是继承BaseMapper
,其中T是实体类。
使用案例
Mapper层继承BaseMapper接口
@Mapper
public interface StudentMapper extends BaseMapper {
}
测试使用
@SpringBootTest
@Slf4j
public class TestController {
@Autowired
private StudentMapper studentMapper;
@Test
public void testQueryStudentList(){
List studentList = studentMapper.selectList(null);
log.info("studentList========>"+studentList);
}
}
BaseMapper接口中定义了足够我们CRUD的操作方法: Insert、Delete、Update、Select。
// 插入一条记录
int insert(T entity);
案例
@SpringBootTest
public class TestController {
@Autowired
private StudentMapper studentMapper;
@Test
public void testInsert(){
studentMapper.insert(new StudentPO(null,"ls",20,"", SexEnum.WOMAN,1,null));
}
}
// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper wrapper);
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map columnMap);
案例
@Test
public void testDelete(){
// 根据 entity 条件,删除记录
Wrapper wrapper = new QueryWrapper().eq("name", "ls");
studentMapper.delete(wrapper);
// 删除(根据ID 批量删除)
List ids = new ArrayList<>();
ids.add("1");
ids.add("2");
studentMapper.deleteBatchIds(ids);
// 根据 ID 删除
studentMapper.deleteById("1746460971291541505");
// 根据 columnMap 条件,删除记录
Map map = new HashMap<>();
map.put("name","Tom");
map.put("id",3);
studentMapper.deleteByMap(map);
}
// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper whereWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
案例
@Test
public void testUpdate(){
StudentPO studentPO = new StudentPO();
studentPO.setId(3L);
studentPO.setName("sss");
studentMapper.updateById(studentPO);
studentMapper.update(studentPO,new QueryWrapper().eq("id",4));
}
// 根据 ID 查询
T selectById(Serializable id);
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper queryWrapper);
// 查询(根据ID 批量查询)
List selectBatchIds(@Param(Constants.COLLECTION) Collection extends Serializable> idList);
// 根据 entity 条件,查询全部记录
List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper);
// 查询(根据 columnMap 条件)
List selectByMap(@Param(Constants.COLUMN_MAP) Map columnMap);
// 根据 Wrapper 条件,查询全部记录
List
Service CRUD 封装IService (opens new window ) 接口,进一步封装 CRUD 采用 get 查询单行 remove 删除 list 查询集合 page分页 前缀命名方式区分 Mapper 层避免混淆
使用案例
新增StuentService接口及实现类
接口继承 IService
public interface StudentService extends IService {
}
实现类继承ServiceImpl,并指定Mapper和实体类。
@Service
public class StudentServiceImpl extends ServiceImpl implements StudentService {
}
测试使用
注入StudentServiceImpl,并调用Service CRUD 接口中的方法,用法和Mapper CRUD 接口中差不多。
@SpringBootTest
@Slf4j
public class TestController {
@Autowired
private StudentServiceImpl studentService;
@Test
public void testQuery(){
List list = studentService.list();
log.info("studentList========>"+list);
}
}
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection entityList);
// 插入(批量)
boolean saveBatch(Collection entityList, int batchSize);
// TableId 注解存在更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection entityList, int batchSize);
// 根据 queryWrapper 设置的条件,删除记录
boolean remove(Wrapper queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection extends Serializable> idList);
// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection entityList, int batchSize);
// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map getMap(Wrapper queryWrapper);
// 根据 Wrapper,查询一条记录
V getObj(Wrapper queryWrapper, Function super Object, V> mapper);
// 查询所有
List list();
// 查询列表
List list(Wrapper queryWrapper);
// 查询(根据ID 批量查询)
Collection listByIds(Collection extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection listByMap(Map columnMap);
// 查询所有列表
List
// 无条件分页查询
IPage page(IPage page);
// 条件分页查询
IPage page(IPage page, Wrapper queryWrapper);
// 无条件分页查询
IPage> pageMaps(IPage page);
// 条件分页查询
IPage> pageMaps(IPage page, Wrapper queryWrapper);
// 查询总记录数
int count();
// 根据 Wrapper 条件,查询总记录数
int count(Wrapper queryWrapper);
Chain为链式封装
query (查询)
// 链式查询 普通
QueryChainWrapper query();
// 链式查询 lambda 式。注意:不支持 Kotlin
LambdaQueryChainWrapper lambdaQuery();
使用案例
以下四个查询效果相等,只是写法不同。
@Test
public void testQuery2(){
List list1 = studentService.list(new QueryWrapper().eq("name", "ls").eq("age", 20));
log.info("studentList========>"+list1);
List list2 = studentService.list(new LambdaQueryWrapper().eq(StudentPO::getName, "ls").eq(StudentPO::getAge, 20));
log.info("studentList========>"+list2);
List list3 = new QueryChainWrapper<>(studentMapper).eq("name", "ls").eq("age", 20).list();
log.info("studentList========>"+list3);
List list4 = new LambdaQueryChainWrapper<>(studentMapper).eq(StudentPO::getName, "ls").eq(StudentPO::getAge, 20).list();
log.info("studentList========>"+list4);
}
update(更新)
// 链式更改 普通
UpdateChainWrapper update();
// 链式更改 lambda 式。注意:不支持 Kotlin
LambdaUpdateChainWrapper lambdaUpdate();
使用案例
以下四个更新效果相等,只是写法不同。
@Test
public void testUpdate2(){
StudentPO studentPO = new StudentPO();
studentPO.setId(3L);
studentPO.setName("sss");
studentService.update(studentPO,new QueryWrapper().eq("name", "ls").eq("age", 20));
studentService.update(studentPO,new LambdaQueryWrapper().eq(StudentPO::getName, "ls").eq(StudentPO::getAge, 20));
new UpdateChainWrapper<>(studentMapper).eq("name", "ls").eq("age", 20).update(studentPO);
new LambdaUpdateChainWrapper<>(studentMapper).eq(StudentPO::getName, "ls").eq(StudentPO::getAge, 20).update(studentPO);
}
- 实体类只需继承 Model 类即可进行强大的CRUD 操作
- 需要项目中已注入对应实体的BaseMapper
使用案例
继承Model类
@Data
@TableName(value = "student",excludeProperty = {"age"})
public class StudentPO extends Model {
@OrderBy(sort = 1)
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long id;
@OrderBy(asc = true,sort = 2)
@TableField(value = "name",condition = SqlCondition.LIKE)
private String name;
private Integer age;
@TableField(exist = false)
private String email;
private SexEnum sex;
@Version
private Integer version;
@TableField("is_delete")
@TableLogic(value = "0",delval = "1")
private Integer isDelete = 0;
}
调用CRUD方法
@Test
public void testActiveRecord(){
StudentPO studentPO = new StudentPO(null,"ls",20,"", SexEnum.WOMAN,1,null);
studentPO.insert();
studentPO.insert();
studentPO.selectAll();
studentPO.updateById();
studentPO.deleteById();
}
- 对selectList查询后的结果用Stream流进行了一些封装,使其可以返回一些指定结果,简洁了api的调用
- 需要项目中已注入对应实体的BaseMapper
// 查询表内记录,封装返回为Map<属性,实体>
Map keyMap(LambdaQueryWrapper wrapper, SFunction sFunction, Consumer... peeks);
// 查询表内记录,封装返回为Map<属性,实体>,考虑了并行流的情况
Map keyMap(LambdaQueryWrapper wrapper, SFunction sFunction, boolean isParallel, Consumer... peeks);
使用案例
@Test
public void testQuery3(){
Map map = SimpleQuery.keyMap(new LambdaQueryWrapper()
.in(StudentPO::getName,"Tom","Sandy"),StudentPO::getName);
log.info("map========>"+map);
}
/**
* 输出结果:map========>
* {
* Tom=StudentPO(id=3, name=Tom, age=null, email=null, sex=null, version=null, isDelete=0),
* Sandy=StudentPO(id=4, name=Sandy, age=null, email=null, sex=null, version=null, isDelete=0)
* }
*/
// 查询表内记录,封装返回为Map<属性,属性>
Map map(LambdaQueryWrapper wrapper, SFunction keyFunc, SFunction valueFunc, Consumer... peeks);
// 查询表内记录,封装返回为Map<属性,属性>,考虑了并行流的情况
Map map(LambdaQueryWrapper wrapper, SFunction keyFunc, SFunction valueFunc, boolean isParallel, Consumer... peeks);
使用案例
@Test
public void testQuery4(){
Map map = SimpleQuery.map(new LambdaQueryWrapper()
.in(StudentPO::getName,"Tom","Sandy"),StudentPO::getId,StudentPO::getName);
log.info("map========>"+map);
}
// 输出结果:map========>{3=Tom, 4=Sandy}
// 查询表内记录,封装返回为Map<属性,List<实体>>
Map> group(LambdaQueryWrapper wrapper, SFunction sFunction, Consumer... peeks);
// 查询表内记录,封装返回为Map<属性,List<实体>>,考虑了并行流的情况
Map> group(LambdaQueryWrapper wrapper, SFunction sFunction, boolean isParallel, Consumer... peeks);
// 查询表内记录,封装返回为Map<属性,分组后对集合进行的下游收集器>
M group(LambdaQueryWrapper wrapper, SFunction sFunction, Collector super T, A, D> downstream, Consumer... peeks);
// 查询表内记录,封装返回为Map<属性,分组后对集合进行的下游收集器>,考虑了并行流的情况
M group(LambdaQueryWrapper wrapper, SFunction sFunction, Collector super T, A, D> downstream, boolean isParallel, Consumer... peeks);
使用案例
@Test
public void testQuery5(){
Map> map = SimpleQuery.group(new LambdaQueryWrapper()
.in(StudentPO::getName,"Tom","Sandy"),StudentPO::getId);
log.info("map========>"+map);
}
/**
* 输出结果:map========>
* {
* 3=[StudentPO(id=3, name=Tom, age=null, email=null, sex=null, version=null, isDelete=0)],
* 4=[StudentPO(id=4, name=Sandy, age=null, email=null, sex=null, version=null, isDelete=0)]
* }
*/
// 查询表内记录,封装返回为List<属性>
List list(LambdaQueryWrapper wrapper, SFunction sFunction, Consumer... peeks);
// 查询表内记录,封装返回为List<属性>,考虑了并行流的情况
List list(LambdaQueryWrapper wrapper, SFunction sFunction, boolean isParallel, Consumer... peeks);
使用案例
@Test
public void testQuery6(){
List list = SimpleQuery.list(new LambdaQueryWrapper(),StudentPO::getSex);
log.info("list========>"+list);
}
// 输出结果:list========>[WOMAN, WOMAN, null, null, null, null, WOMAN, MAN]
@Test
public void testQuery7(){
List list = SimpleQuery.list(new LambdaQueryWrapper(), StudentPO::getSex, new Consumer() {
@Override
public void accept(StudentPO studentPO) {
// 如果性别为空,则设置为MAN
studentPO.setSex(Optional.ofNullable(studentPO.getSex()).orElse(SexEnum.MAN));
}
});
log.info("list========>"+list);
}
// 输出结果:list========>[WOMAN, WOMAN, MAN, MAN, MAN, MAN, WOMAN, MAN]
- 使用静态调用的方式,执行CRUD方法,避免Spring环境下Service循环注入,简洁代码,提升效率
- 需要项目中已注入对应实体的BaseMapper
Db类所有静态方法
public static boolean save(T entity);
public static boolean saveBatch(Collection entityList);
public static boolean saveBatch(Collection entityList, int batchSize);
public static boolean saveOrUpdateBatch(Collection entityList);
public static boolean saveOrUpdateBatch(Collection entityList, int batchSize);
public static boolean removeById(Serializable id, Class entityClass);
public static boolean removeById(T entity);
public static boolean remove(AbstractWrapper queryWrapper);
public static boolean updateById(T entity);
public static boolean update(AbstractWrapper updateWrapper);
public static boolean update(T entity, AbstractWrapper updateWrapper);
public static boolean updateBatchById(Collection entityList);
public static boolean updateBatchById(Collection entityList, int batchSize);
public static boolean removeByIds(Collection extends Serializable> list, Class entityClass);
public static boolean removeByMap(Map columnMap, Class entityClass);
public static boolean saveOrUpdate(T entity);
public static T getById(Serializable id, Class entityClass);
public static T getOne(AbstractWrapper queryWrapper);
public static T getOne(T entity);
public static T getOne(T entity, boolean throwEx);
public static T getOne(AbstractWrapper queryWrapper, boolean throwEx);
public static List listByMap(Map columnMap, Class entityClass);
public static List listByIds(Collection extends Serializable> idList, Class entityClass);
public static Map getMap(AbstractWrapper queryWrapper);
public static Map getMap(T entity);
public static long count(Class entityClass);
public static long count(T entity);
public static long count(AbstractWrapper queryWrapper);
public static List list(AbstractWrapper queryWrapper);
public static List list(IPage page, AbstractWrapper queryWrapper);
public static List list(Class entityClass);
public static List list(IPage page, Class entityClass);
public static List list(T entity);
public static List list(IPage page, T entity);
public static List> listMaps(AbstractWrapper queryWrapper);
public static List> listMaps(IPage extends Map> page, AbstractWrapper queryWrapper);
public static List> listMaps(Class entityClass);
public static List> listMaps(IPage extends Map> page, Class entityClass);
public static List> listMaps(T entity);
public static List> listMaps(IPage extends Map> page, T entity);
public static List listObjs(Class entityClass);
public static List listObjs(AbstractWrapper queryWrapper);
public static List listObjs(AbstractWrapper queryWrapper, SFunction super T, V> mapper);
public static List listObjs(Class entityClass, SFunction super T, V> mapper);
public static >> E pageMaps(E page, Class entityClass);
public static >> E pageMaps(E page, AbstractWrapper queryWrapper);
public static IPage page(IPage page, Class entityClass);
public static IPage page(IPage page, AbstractWrapper queryWrapper);
public static QueryChainWrapper query(Class entityClass);
public static KtQueryChainWrapper ktQuery(Class entityClass);
public static LambdaQueryChainWrapper lambdaQuery(Class entityClass);
public static UpdateChainWrapper update(Class entityClass);
public static KtUpdateChainWrapper ktUpdate(Class entityClass);
public static LambdaUpdateChainWrapper lambdaUpdate(Class entityClass);
public static boolean saveOrUpdate(T entity, AbstractWrapper updateWrapper);
public static V getObj(AbstractWrapper queryWrapper, SFunction super T, V> mapper);
protected static Class getEntityClass(Collection entityList);
protected static Class getEntityClass(AbstractWrapper queryWrapper);
protected static Class getEntityClass(T entity);
protected static TableInfo getTableInfo(Class entityClass);
使用案例
@Test
public void testQuery8(){
List list = Db.list(Wrappers.lambdaQuery(StudentPO.class)
.in(StudentPO::getName,"Tom","Sandy"));
log.info("list========>"+list);
StudentPO byId = Db.getById(1, StudentPO.class);
log.info("byId========>"+byId);
}