[toc]
1.MyBatis-plus基础
1.1.mybatis-plus简介
MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
MyBatis-plus官网:https://baomidou.com/
特点:
- 润物无声:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。
- 效率至上:只需简单配置,即可快速进行单表 CRUD 操作,从而节省大量时间。
- 丰富功能:代码生成、自动分页、逻辑删除、自动填充等功能一应俱全
1.2.基本使用
插入依赖
1 2 3 4 5
| <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-spring-boot3-starter</artifactId> <version>3.5.7</version> </dependency>
|
配置文件,这里只配置了数据库,可以加上mybatis-plus加入相关配置,也可以单独创建一个java配置类,专门用于配置mybatis-plus
1 2 3 4 5 6 7 8 9 10
| spring: datasource: driver-class-name: org.h2.Driver username: root password: test sql: init: schema-locations: classpath:db/schema-h2.sql data-locations: classpath:db/data-h2.sql
|
编写实体类
1 2 3 4 5 6 7
| @Data public class User { private Long id; private String name; private Integer age; private String email; }
|
编写Mapper接口类UserMapper
1 2 3
| public interface UserMapper extends BaseMapper<User> {
}
|
要想让spring知道这个bean,有俩种方式
在Mapper接口上加上@Mapper注解,自动注入(推荐)
在启动类添加@MapperScan扫描注解,扫描Mapper文件夹
1.3.注解映射
上面实例中,实体类名与表名,包括属性名与字段名都是完全一致的,所以mybatis-plus是可以识别的。但在实际开发中,很有可能会出现表名与实体类名不一致,或者属性名与字段名不一致的情况。此时就需要使用注解来进行映射。
● @TableName:表名注解,标识实体类对应的表。
● @TableId:主键注解(可以使用 type=IdType.AUTO 形式指定主键生成策略)
● @TableField:字段注解(非主键)
一般在代码中,实体类应该跟数据库中字段名保持一致,这是规范做法
主键生成策略
主键生成策略类型 | 描述 |
---|
AUTO | 数据库 ID 自增 |
INPUT | insert 前自行 set 主键值 |
ASSIGN_ID | 分配 ID(主键类型为 Number(Long 和 Integer)或 String) |
ASSIGN_UUID | 分配 UUID,主键类型为 String |
使用对应策略时,要注意数据库中主键属性与对应策略保持一致,否则无法应用,如果第一次Snowflake生成之后删掉后面应用策略的时候还是生成Snowflake,需要把数据库对应表删除重新建
1.4.命名转换问题
在实际开发中,项目中的类名、属性名,包括数据库中的表名、字段名,这些命名要严格遵守规范。一般来说:
● 在数据库设计中,由于数据库不区分大小写,所以都采用下划线命名法。
● 在java中,类名都采用帕斯卡命名法(大驼峰),属性名都采用驼峰命名法。
在配置文件加入:
1 2 3 4 5 6 7 8 9 10
| mybatis-plus: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: id-type: auto
|
可以开启mybatis-plus的驼峰命名
日志可以使运行时控制台打印输出的SQL语句
1.5.关闭命名转换功能
如果数据库中没有采用下划线命名法,那么可以在SpringBoot的application.yml配置文件中关闭此功能:
1 2 3
| mybatis-plus: configuration: map-underscore-to-camel-case: false
|
默认开启
2.BaseMapper核心接口
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
public interface BaseMapper<T> extends Mapper<T> {
int insert(T entity);
int deleteById(Serializable id);
int deleteById(T entity);
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<?> idList);
int updateById(@Param(Constants.ENTITY) T entity);
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
T selectById(Serializable id);
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
default T selectOne(@Param(Constants.WRAPPER) 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"); } return ts.get(0); } return null; }
default boolean exists(Wrapper<T> queryWrapper) { Long count = this.selectCount(queryWrapper); return null != count && count > 0; }
Long selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
<P extends IPage<T>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
<P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); }
|
查看BaseMapper核心接口的源代码,这里详细说明了封装的增删改查方法