/* BaseMapper 源码 */
public interface BaseMapper<T> extends Mapper<T> {
// 插入一条记录
int insert(T entity);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 entity 条件删除记录
int deleteById(T entity);
// 根据 columnMap 条件删除记录
int deleteByMap(@Param("cm") Map<String, Object> columnMap);
int delete(@Param("ew") Wrapper<T> queryWrapper);
// 根据 ID 批量删除
int deleteBatchIds(@Param("coll") Collection<?> idList);
// 根据 ID 修改
int updateById(@Param("et") T entity);
// 根据 Wrapper 条件更新记录
int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);
// 根据 ID 查询
T selectById(Serializable id);
// 根据 ID 批量查询
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
// 根据 columnMap 条件查询
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
// 根据 entity 条件查询一条记录
default T selectOne(@Param("ew") Wrapper<T> queryWrapper) {
List<T> ts = this.selectList(queryWrapper);
if (CollectionUtils.isNotEmpty(ts)) {
if (ts.size() != 1) {
throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records", new Object[0]);
} else {
return ts.get(0);
} else {
return null;
default boolean exists(Wrapper<T> queryWrapper) {
Long count = this.selectCount(queryWrapper);
return null != count && count > 0L;
// 根据 Wrapper 条件查询总记录数
Long selectCount(@Param("ew") Wrapper<T> queryWrapper);
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);
// 根据 Wrapper 条件查询全部记录
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);
// 根据 Wrapper 条件查询全部记录 => 注意只返回第一个字段的值
List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);
// 根据 entity 条件查询全部记录(并翻页)
<P extends IPage<T>> P selectPage(P page, @Param("ew") Wrapper<T> queryWrapper);
// 根据 Wrapper 条件查询全部记录(并翻页)
<P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param("ew") Wrapper<T> queryWrapper);
调用 Mapper 层实现 CRUD
@SpringBootTest
public class MyBatisPlusTest {
/* 测试插入数据 */
@Test
void testInsert(){
// 新增用户信息
User user = new User();
user.setName("zs");
user.setAge(22);
user.setEmail("zs@mail.com");
int insert = userMapper.insert(user);
System.out.println("insert => " + insert + "---" + "userId => " +user.getUid());
/* 测试删除数据 */
@Test
void testDelete(){
// 删除用户信息
// int i = userMapper.deleteById(1538798688154005506L);
// System.out.println(i);
// 根据 map 集合所设置的条件删除用户信息
// 执行 SQL => DELETE FROM user WHERE name = ? AND age = ?
// Map<String, Object> map = new HashMap<>();
// map.put("name","zs");
// map.put("age",22);
// int i = userMapper.deleteByMap(map);
// System.out.println(i);
// 通过多个 id 实现批量删除 => DELETE * FROM user WHERE id IN (?,?,?)
List<Long> list = Arrays.asList(1L, 2L, 3L);
int i = userMapper.deleteBatchIds(list);
System.out.println("result => " +i);
/* 测试更新数据 */
@Test
void testUpdate(){
// UPDATE user SET name=?, age=?, email=? WHERE id=?
User user = new User();
user.setUid(4L);
user.setName("jr");
user.setAge(20);
user.setEmail("jr@mail.com");
int i = userMapper.updateById(user);
System.out.println(i);
/* 测试查询数据 */
@Test
void testSelect(){
// User user = userMapper.selectById(1L);
// System.out.println(user);
// List<Long> list = Arrays.asList(1L,2L,3L);
// List<User> users = userMapper.selectBatchIds(list);
// users.forEach(System.out::println);
// 根据 map 集合条件查询 => SELECT id,name,age,email FROM user WHERE name = ? AND age = ?
// Map<String, Object> map = new HashMap<>();
// map.put("name","jr");
// map.put("age","20");
// List<User> users = userMapper.selectByMap(map);
// users.forEach(System.out::println);
// List<User> users = userMapper.selectList(null);
// users.forEach(System.out::println);
// 测试自定义查询
Map<String, Object> stringObjectMap = userMapper.selectMapByIdByZs(1L);
System.out.println(stringObjectMap);
MybatisPlus 不止提供通用的 mapper 还提供通用的 service。即 service 也可使用其提供的通用 service 中的方法。IService 与其实现类 ServiceImpl 封装了常见的业务层逻辑。
IService
// IService 简易源码
public interface IService<T> {... save、remove、update、get、page、list}
ServiceImpl
// ServiceImpl 简易源码
// M 即开发者定义的 xxxMapper、T 是当前操作的实体类对象
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {}
调用 Service 层实现 CRUD
/* service */
public interface UserService extends IService<User> {}
/* service.impl */
// mybatis-plus 提供的通用 service => 不必自己重写 -> 直接继承 IService 的实现类
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}
@SpringBootTest
public class MyBatisPlusServiceTest {
@Autowired
private UserService userService;
@Test
public void testGetCount(){
// 查询总记录数
long count = userService.count();
System.out.println("总记录数 => " + count);
// 批量添加
@Test
public void testInsertMore(){
List<User> list = new ArrayList<>();
for (int i = 1; i <= 5; i++){
User user = new User();
user.setName("gz"+i);
user.setAge(20+i);
list.add(user);
boolean b = userService.saveBatch(list);
System.out.println(b);
// AbstractWrapper 源码
public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T, R, Children>> extends Wrapper<T> implements Compare<Children, R>, Nested<Children, Children>, Join<Children>, Func<Children, R> {
public Children like(boolean condition, R column, Object val) {} // like(数据库字段名, 模糊值)
public Children between(boolean condition, R column, Object val1, Object val2) {} // between(数据库字段名, 范围1, 范围2)
public Children isNotNull(boolean condition, R column) {} // isNotNull(数据库字段名)
组装查询条件
@SpringBootTest
public class MyBatisPlusWrapperTest {
@Autowired
private UserMapper userMapper;
/* 条件构造器 */
// 查询条件
@Test
public void test01(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.like("user_name","a")
.between("age",20,30)
.isNotNull("email");
List<User> list = userMapper.selectList(queryWrapper);
list.forEach(System.out::println);
组装排序条件
@SpringBootTest
public class MyBatisPlusWrapperTest {
@Autowired
private UserMapper userMapper;
/* 条件构造器 */
// 排序条件
@Test
public void test02(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// 先按照年龄降序排再按照升序排
queryWrapper.orderByDesc("age")
.orderByAsc("uid");
List<User> list = userMapper.selectList(queryWrapper);
list.forEach(System.out::println);
组装删除条件
@SpringBootTest
public class MyBatisPlusWrapperTest {
@Autowired
private UserMapper userMapper;
/* 条件构造器 */
// 组装删除条件
@Test
public void test03(){
// 删除邮箱地址为 null 的用户信息
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.isNull("email");
int i = userMapper.delete(queryWrapper);
System.out.println(i);
通过条件构造器实现修改功能
@SpringBootTest
public class MyBatisPlusWrapperTest {
@Autowired
private UserMapper userMapper;
/* 条件构造器 */
// queryWrapper 实现修改操作
@Test
public void test04(){
// 修改年龄大于20且用户名包含a或邮箱为null的用户信息
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age",20)
.like("user_name","aa")
.or()
.isNull("email");
User user = new User();
user.setName("zs");
user.setEmail("zs@mail.com");
int update = userMapper.update(user, queryWrapper); // 参数一设置修改的内容、参数二设置修改的条件
System.out.println(update);
条件优先级
@SpringBootTest
public class MyBatisPlusWrapperTest {
@Autowired
private UserMapper userMapper;
/* 条件构造器 */
// 优先级
@Test
public void test05(){
// 修改用户名包含a且(年龄大于20或邮箱为null)的用户信息
// lambda 中条件优先执行
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name","a")
.and(i -> i.gt("age",20).or().isNull("email"));
User user = new User();
user.setName("gz");
user.setEmail("gz@mail.com");
int update = userMapper.update(user, queryWrapper);
System.out.println(update);
查询指定字段
@SpringBootTest
public class MyBatisPlusWrapperTest {
@Autowired
private UserMapper userMapper;
/* 条件构造器 */
// 组装 select 字句
@Test
public void test06(){
// 查询用户名、年龄、邮箱
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("user_name","age","email");
List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
maps.forEach(System.out::println);
组装子查询
@SpringBootTest
public class MyBatisPlusWrapperTest {
@Autowired
private UserMapper userMapper;
/* 条件构造器 */
// 条件构造器实现子查询
@Test
public void test07(){
// 查询 id 小于等于 100 的用户信息
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("uid","select uid from t_user where uid <= 100");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
@Data
public class Product {
private Long id;
private String name;
private Integer price;
@Version // @Version => 乐观锁版本号字段
private Integer version;
@Configuration
@MapperScan("com.zszy.mybatisplus.mapper")
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
@Data // 等于 @NoArgsConstructor + @AllArgsConstructor + @Getter + @Setter + @EqualsAndHashCode
public class User {
private SexEnum sex;
@SpringBootTest
public class MyBatisPlusEnumTest {
@Autowired
private UserMapper userMapper;
@Test
public void test(){
User user = new User();
user.setName("admin");
user.setEmail("admin@mail.com");
user.setAge(29);
user.setSex(SexEnum.MALE);
int insert = userMapper.insert(user);
System.out.println(insert);
多数据源适用于纯粹多库、读写分离、一主多从、混合模式的开发,通过多库中的表分别获取数据。
创建测试数据库和表
CREATE DATABASE `mybatis_plus_1` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; use `mybatis_plus_1`; CREATE TABLE product ( id BIGINT(20) NOT NULL COMMENT '主键ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称', price INT(11) DEFAULT 0 COMMENT '价格', version INT(11) DEFAULT 0 COMMENT '乐观锁版本号', PRIMARY KEY (id) );
添加测试数据
INSERT INTO product (id, NAME, price) VALUES (1, 'mbp', 100);