0%

【MyBatisPlus】通用CRUD

关于Mybatis的通用CRUD操作


1 CRUD

1.1 与Mybatis区别

  • Mybatis
  • Mybatis操作数据库,要创建一个Mapper接口,并创建对应的CURD方法
  • 创建完接口,还要创建对应Mapper.xml文件,在里面的文件填写相应的SQL语句
  • MybatisPlus
  • 只需创建一个Mapper接口,此Mapper接口继承与BaseMapper接口,就能够实现对数据库进行CURD操作,无需写SQL,但是复杂的业务还是需要手写SQL来实现

1.2 BaseMapper

  • BaseMapper内部已经创建好了许多通用的CURD方法,所以在我们创建的Mapper接口继承BaseMapper接口后,无需创建接口方法,就可以进行CURD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//BaseMapper源码
public interface BaseMapper<T> extends Mapper<T> {
int insert(T entity);

int deleteById(Serializable id);

int deleteByMap(@Param("cm") Map<String, Object> columnMap);

int delete(@Param("ew") Wrapper<T> queryWrapper);

int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);

int updateById(@Param("et") T entity);

int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);

T selectById(Serializable id);

List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);

List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);

T selectOne(@Param("ew") Wrapper<T> queryWrapper);

Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);

List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);

List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);

List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);

<E extends IPage<T>> E selectPage(E page, @Param("ew") Wrapper<T> queryWrapper);

<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param("ew") Wrapper<T> queryWrapper);
}

1.3 字段注解

  • (1)表名注解
  • @TableName(value = 表名)
  • 表名:如果数据库表名与类名不一致,需要设置此类型,否则会找不到对应的数据库表
  • (2)主键注解
  • @TableId(value = 主键字段名, type = 主键类型)
  • 主键字段名:如果Bean属性id和主键字段名一直,可以不设置
  • 主键类型:
    • IdType.ASSIGN_ID,默认,若我们主键为null,会自动为我们生成主键id并插入
    • IdType.AUTO,数据库ID自增,数据库表使用id自增建议使用此类型
  • (3)字段注解
  • @TableField(value = 字段名, exist = true/false)
  • 字段名:数据库对应字段名,如果一致,可以不用设置
  • exist:是否为数据库存在字段,默认true,若想要对数据库操作忽略此字段,可以设置为false

1.4 全局配置策略

  • 配置类:com.baomidou.mybatisplus.core.MybatisConfiguration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public MybatisConfiguration() {
this.mybatisMapperRegistry = new MybatisMapperRegistry(this);
this.caches = new MybatisConfiguration.StrictMap("Caches collection");
this.resultMaps = new MybatisConfiguration.StrictMap("Result Maps collection");
this.parameterMaps = new MybatisConfiguration.StrictMap("Parameter Maps collection");
this.keyGenerators = new MybatisConfiguration.StrictMap("Key Generators collection");
this.sqlFragments = new MybatisConfiguration.StrictMap("XML fragments parsed from previous mappers");
this.mappedStatements = (new MybatisConfiguration.StrictMap("Mapped Statements collection")).conflictMessageProducer((savedValue, targetValue) -> {
return ". please check " + savedValue.getResource() + " and " + targetValue.getResource();
});

this.useGeneratedShortKey = true;
this.useDeprecatedExecutor = true;
this.mapUnderscoreToCamelCase = true; //开启驼峰命令
this.languageRegistry.setDefaultDriverClass(MybatisXMLLanguageDriver.class);
}

2 插入操作

2.1 基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
//对应BaseMapper接口方法
int insert(T entity)


//使用测试
@Test
public void insertTest() {
User user = new User();
user.setName("C酱");
user.setAge(18);
user.setEmail("CC@qq.com");
userMapper.insert(user);
}

2.2 细节

  • (1)获取当前数据id值
  • 对于主键自增的数据,想要实现数据插入后,顺便获取会该数据的主键值
  • MybatisPlus自动封装好方法,插入成功后,自动将主键值,set回java数据中
1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void insertTest() {
//通用插入
User user = new User();
user.setName("asaki");
user.setAge(18);
user.setEmail("1231231@qq.com");
userMapper.insert(user);
//获取主键值(插入成功后,id值自动被设置)
Integer id = user.getId();
System.out.println(id);
}
  • (2)动态SQL
  • MybatisPlus的插入方法使用的动态SQL,如果插入值为空的话,会自动忽略该字段,不进行sql语句的插入

3 更新操作

3.1 基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//BaseMapper接口对应方法
int updateById(@Param("et") T entity);


//使用
@Test
public void updateTest() {
User user = new User();
user.setId(9);
user.setName("玛利亚");
user.setAge(18);
user.setEmail("myl@qq.com");
//修改
userMapper.updateById(user);
}

3.2 细节

  • (1)动态SQL
  • update方法和insert方法一样,都是有动态SQL,插入值为null自动忽略该字段

4 查询操作

4.1 基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//BaseMapper接口对应方法
T selectById(Serializable id);

T selectOne(@Param("ew") Wrapper<T> queryWrapper);

List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);

List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);

<E extends IPage<T>> E selectPage(E page, @Param("ew") Wrapper<T> queryWrapper);


//使用
@Test
public void selectTest() {
//1、通过主键id查询
User user = userMapper.selectById(1); //SQL:SELECT id,name,age,email FROM user WHERE id=?
System.out.println(user);

//2、多个字段条件查询(注意查询结果只能有一个,否则报错)
User user1 = new User();
user1.setId(6);
user1.setName("C酱");
User user2 = userMapper.selectOne(new QueryWrapper<>(user1)); //SQL:SELECT id,name,age,email FROM user WHERE id=? AND name=?
System.out.println(user2);

//3、通过多个主键id查询多条数据
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
List<User> users = userMapper.selectBatchIds(ids); //SQL:SELECT id,name,age,email FROM user WHERE id IN ( ? , ? )
users.forEach(System.out::println);

//4、多字段条件查询(支持返回多个)
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("name", "C酱");
columnMap.put("age", 18);
List<User> users1 = userMapper.selectByMap(columnMap); //SQL:SELECT id,name,age,email FROM user WHERE name = ? AND age = ?
users1.forEach(System.out::println);

//5、分页查询(暂无效果,需要与分页插件使用才有效果)
Page<User> page = new Page<>(1, 2);
Page<User> userIPage = userMapper.selectPage(page, null); //SQL:SELECT id,name,age,email FROM user
List<User> records = userIPage.getRecords();
records.forEach(System.out::println);
}

5 删除操作

5.1 基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//BaseMapper接口对应的方法
int deleteById(Serializable id);

int deleteByMap(@Param("cm") Map<String, Object> columnMap);

int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);


//使用
@Test
public void deleteTest() {
//1、根据主键id进行删除
userMapper.deleteById(9); //SQL:DELETE FROM user WHERE id=?

//2、多字段条件删除
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("name", "C酱");
columnMap.put("age", 18);
userMapper.deleteByMap(columnMap); //SQL:DELETE FROM user WHERE name = ? AND age = ?

//3、根据主键id批量删除
List<Integer> ids = new ArrayList<>();
ids.add(8);
ids.add(10);
userMapper.deleteBatchIds(ids); //SQL:DELETE FROM user WHERE id IN ( ? , ? )
}

6 MP启动注入SQL

6.1 问题提出

  • 一个Mapper接口继承了BaseMapper之后,可以使用对应BaseMapper的方法。方法有了,但是对应的SQL语句并没有发现。这是因为MybatisPlus启动后会自动注入SQL

6.2 MybatisPlus原理