@TableName:对数据表名注解 当数据库表名与实体类名不一致时,需要该注解进行制定数据库名.
@TableName("tb_user")
public class User(){...}//表名数据库表tb_user与User进行对应.
@TableId:表主键标识 对主键的类型进行制定如:自增,随机字符串,不指定…
@TableId(value = “id”, type = IdType.AUTO):自增
@TableId(type=IdType.AUTO) private Long id;
@TableId(value = “id”, type = IdType.ID_WORKER_STR):分布式全局唯一ID字符串类型
@TableId(value = “id”, type = IdType.INPUT):自行输入
@TableId(value = “id”, type = IdType.ID_WORKER):分布式全局唯一ID 长整型类型
@TableId(value = “id”, type = IdType.UUID):32位UUID字符串
@TableId(value = “id”, type = IdType.NONE):无状态
@TableField:表字段标识 可以指定字段的一些属性,常常解决的问题有2个
- 1、对象中的属性名和字段名不一致的问题(非驼峰)
- 2、对象中的属性字段在表中不存在的问题
@TableField(exist = false):表示该属性不为数据库表字段,但又是必须使用的。
@TableField(exist = false) private String address;//该字段在数据库中不存在
@TableField(exist = true):表示该属性为数据库表字段。
@TableField(value= "email")//表示数据库的email字段对应实体中的mail属性. private String mail;
@TableField(condition = SqlCondition.LIKE):表示该属性可以模糊搜索。
@TableField(fill = FieldFill.INSERT):注解填充字段 ,生成器策略部分也可以配置!
@FieldStrategy:
@FieldFill
@Version:乐观锁注解、标记
@EnumValue:通枚举类注解
@TableLogic:表字段逻辑处理注解(逻辑删除)
@SqlParser:租户注解
2.Mybatis-Plus整合 3.通用CRUD说明:
- 通用 CRUD 封装baseMapper (opens new window)接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器
- 泛型 T 为任意实体对象
- 参数 Serializable 为任意类型主键 Mybatis-Plus 不推荐使用复合主键约定每一张表都有自己的唯一 id 主键
- 对象 Wrapper 为 条件构造器
// 插入一条记录 int insert(T entity);
测试代码:
@Test
void testInsert() {
User user = new User();
user.setAge(20);
user.setEmail("2422737092@qq.com");
user.setName("赵云");
user.setUserName("zhaoyun");
user.setPassword("123456");
int result = userMapper.insert(user);//返回的是受影响的行数
System.out.println("result = "+result);
System.out.println(user.getId());//自增后的id会回填到对象中.
}
Delete
// 根据 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);
| 类型 | 参数名 | 描述 |
|---|---|---|
| Wrapper | wrapper | 实体对象封装操作类(可以为 null) |
| Collection extends Serializable> | idList | 主键ID列表(不能为 null 以及 empty) |
| Serializable | id | 主键ID |
| Map | columnMap | 表字段 map 对象 |
@Test
public void testDelete(){
int result = userMapper.deleteById(7L);
System.out.println("result==>"+result);
}
@Test
public void testDeleteByMap(){
Map map = new HashMap <>();
map.put("user_name","zhaoyun");
map.put("password", "123456");
//根据map删除数据,多条件之间是and关系
int result = userMapper.deleteByMap(map);
System.out.println("result==>"+result);
}
@Test
public void testDeleteByCondition(){
// QueryWrapper wrapper = new QueryWrapper <>();
// wrapper.eq("user_name","sunqi").eq("password","123456");
// int result = userMapper.delete(wrapper);
//用法二 建议使用这种...
User user = new User();
user.setPassword("123456");
user.setUserName("zhanglong");
QueryWrapper wrapper = new QueryWrapper <>(user);
int result = userMapper.delete(wrapper);
System.out.println("--------------------------result==>"+result);
}
@Test
public void testDeleteBatchIds(){
//根据ID批量删除数据
int result = userMapper.deleteBatchIds(Arrays.asList(17L, 18L));
System.out.println("--------------------------result==>"+result);
}
Update
// 根据 whereWrapper 条件,更新记录 int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper参数说明whereWrapper); // 根据 ID 修改 int updateById(@Param(Constants.ENTITY) T entity);
| 类型 | 参数名 | 描述 |
|---|---|---|
| T | entity | 实体对象 (set 条件值,可为 null) |
| Wrapper | updateWrapper | 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) |
@Test
void testUpdateById(){
User user = new User();
user.setId(1L);//条件:根据id进行变更
user.setAge(21);//除了ID之外的都是要变更的字段.
user.setPassword("6666666");
int resut = this.userMapper.updateById(user);
System.out.println("result ==>> "+resut);
}
//根据条件进行更新
@Test
void testUpdate(){
User user = new User();
user.setAge(20);;
user.setPassword("8888888");
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("user_name","zhangsan");//匹配user_name=zhangsan的数据表中的列.
int result = userMapper.update(user, wrapper);
System.out.println("result ==> "+result);
}
@Test
public void testUpdate2(){
//更新的条件以及字段
UpdateWrapper wrapper = new UpdateWrapper <>();//该UpdateWrapper可以直接使用set方法添加要更新的属性值.
wrapper.eq("id",7).set("age",22);
int result = userMapper.update(null, wrapper);
System.out.println("result ==>>"+result);
}
Select
// 根据 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
| 类型 | 参数名 | 描述 |
|---|---|---|
| Serializable | id | 主键ID |
| Wrapper | queryWrapper | 实体对象封装操作类(可以为 null) |
| Collection extends Serializable> | idList | 主键ID列表(不能为 null 以及 empty) |
| Map | columnMap | 表字段 map 对象 |
| IPage | page | 分页查询条件(可以为 RowBounds.DEFAULT) |
测试代码:
@Test
public void testSelectById(){
User user = userMapper.selectById(2L);
System.out.println(user);
}
@Test
public void testSelectBatchIds(){
List users = userMapper.selectBatchIds(Arrays.asList(2L, 3L, 4L));
for (User user : users) {
System.out.println(user);
}
}
//根据自定义条件进行查询
@Test
public void testSelectOne(){
QueryWrapper wrapper = new QueryWrapper <>();
wrapper.eq("password","123456");
User user = userMapper.selectOne(wrapper);
//查询的数据超过一条时,会抛出异常
System.out.println(user);
}
@Test
public void testSelectCount(){
QueryWrapper wrapper = new QueryWrapper <>();
wrapper.gt("age", 20);
//根据条件查询数据条数
Integer count = userMapper.selectCount(wrapper);
System.out.println("count==>"+count);
}
@Test
public void testSelectList(){
QueryWrapper wrapper = new QueryWrapper <>();
wrapper.like("email", "3258843538");
List userList = userMapper.selectList(wrapper);
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void testSelectPage(){
Page page = new Page <>(3, 1);
QueryWrapper wrapper = new QueryWrapper <>();
wrapper.like("email","3258843538");
IPage iPage = userMapper.selectPage(page, wrapper);
System.out.println("数据总条数:"+iPage.getTotal());
System.out.println("数据总页数"+iPage.getPages());
System.out.println("当前页数"+iPage.getCurrent());
List records = iPage.getRecords();
for (User record : records) {
System.out.println(record);
}
}
和selectPage搭配的配置类:
@Configuration
@MapperScan("com.rg.boot.mapper")//设置Mapper接口的扫描包
//@Mapper:在接口类上添加了@Mapper在运行时,通过动态代理生成接口实现类
// @MapperScan作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在运行时都会生成相应的实现类,这样就不用每个接口都添加@Mapper
public class MybatisPlusConfig {
//分页插件
//PaginationInnerInterceptor
@Bean
public MybatisPlusInterceptor paginationInnerInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
4.配置
在MP中有大量的配置,其中一部分是Mybatis原生的配置,另一部分是MP的配置
4.1基本配置 4.1.1、configLocationMyBatis 配置文件位置,如果您有单独的 MyBatis 配置,请将其路径配置到 configLocation 中。 MyBatis
Configuration 的具体内容请参考MyBatis 官方文档
SpringBoot:
mybatis-plus: config-location: classpath:mybatis-config.xml
SpringMVC:
4.1.2、mapperLocations
MyBatis Mapper 所对应的 XML 文件位置,如果您在 Mapper 中有自定义方法(XML 中有自定义实现),需要进行该配置,告诉 Mapper 所对应的 XML 文件位置。
Spring Boot:
mybatis-plus: mapper-locations: classpath*:mapper/*.xml
Spring MVC:
注意:Maven 多模块项目的扫描路径需以 classpath*: 开头 (即加载多个 jar 包下的 XML 文件)
测试代码:
######################UserMapper.xml(位于mapper文件夹下)################################4.1.3 typeAliasesPackage##########################测试方法#################################################### @Test public void testFindById(){ User user = userMapper.findById(2L); System.out.println(user); } #########################yaml配置文件################################################# mybatis-plus: config-location: classpath:mybatis-config.xml mapper-locations: classpath*:mapper/*.xml
MyBaits 别名包扫描路径,通过该属性可以给包中的类注册别名,注册后在 Mapper 对应的 XML 文件中可以直接使用类名,而不用使用全限定的类名(即 XML 中调用的时候不用包含包名)
SpringBoot:
mybatis-plus: type-aliases-package: com.rg.boot.bean
SpringMVC:
< bean id="sqlSessionFactory" >4.1.4mapUnderscoreToCamelCase
- 类型:boolean
- 默认值:true
是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN(下划线命名) 到经典 Java 属性名 aColumn(驼峰命名) 的类似映射。
注意:此属性在 MyBatis 中原默认值为 false
# 关闭自动驼峰映射,该参数不能和mybatis-plus.config-location同时存在
mybatis-plus:
# config-location: classpath:mybatis-config.xml
configuration:
map-underscore-to-camel-case: false
cache-enabled: false
4.1.5 cacheEnabled
- 类型: boolean
- 默认值: true
全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true。
mybatis-plus:
configuration:
cache-enabled: false
4.2 DB 策略配置
4.3.1、idType
- 类型: com.baomidou.mybatisplus.annotation.IdType
- 默认值: ID_WORKER
全局默认主键类型,设置后,即可省略实体对象中的@TableId(type = IdType.AUTO)配置。
SpringBoot:
mybatis-plus.configuration.map-underscore-to-camel-case=false
SpringMVC:
4.3.2、tablePrefix
- 类型: String
- 默认值: null
表名前缀,全局配置后可省略 @TableName()配置。
SpringBoot:
mybatis-plus.global-config.db-config.table-prefix =tb_
SpringMVC:
5 条件构造器
在MP中,Wrapper接口的实现类关系如下:
可以看到, AbstractWrapper和AbstractChainWrapper是重点实现,接下来我们重点学习AbstractWrapper以及其子类。
allEqallEq(Mapparams) allEq(Map params, boolean null2IsNull) allEq(boolean condition, Map params, boolean null2IsNull)
个别参数说明:
params : key为数据库字段名,value为字段值
null2IsNull : 为true则在map的value为null时调用 isNull 方法,为false时则忽略value为null的
allEq(BiPredicatefilter, Map params) allEq(BiPredicate filter, Map params, boolean null2IsNull) allEq(boolean condition, BiPredicate filter, Map params, boolean null2IsNull)
个别参数说明:
filter : 过滤函数,是否允许字段传入比对条件中
params 与 null2IsNull : 同上
测试代码:
@Test
public void testAllEq(){
Map params = new HashMap <>();
params.put("name", "李四");
params.put("age","20");
params.put("password", null);
QueryWrapper wrapper = new QueryWrapper <>();
//SELECT id,user_name,password,name,age,email FROM tb_user WHERe (password IS NULL AND name = ? AND age = ?)
// wrapper.allEq(params);
// SELECt id,user_name,password,name,age,email FROM tb_user WHERe (name = ? AND age = ?)
//wrapper.allEq(params,false);//false:忽略条件为null的 条件
//SELECt id,user_name,password,name,age,email FROM tb_user WHERe (age = ?)
// wrapper.allEq((k, v) -> (k.equals("age") || (k.equals("id"))), params);//filter : 过滤函数,是否允许字段传入比对条件中
// SELECt id,user_name,password,name,age,email FROM tb_user WHERe (name = ? AND age = ?)
wrapper.allEq((k, v) -> (k.equals("age") || (k.equals("id"))||(k.equals("name"))), params);
List userList = userMapper.selectList(wrapper);
// for (User user : userList) {
// System.out.println(user);
// }
}
基本比较操作:
- eq
- 等于=
- ne
- 不等于 <>
- gt
- 大于 >
- ge
- 大于等于 >=
- lt
- 小于<
- le
- 小于等于 <=
- between
- BETWEEN 值1 AND 值2
- notBetween
- NOT BETWEEN 值1 AND 值2
- In
- 字段 IN(Value.get(0),value.get(1)…)
- notIn
字段 NOT IN (v0, v1, …)
测试代码:
@Test
public void testEq(){
QueryWrapper wrapper = new QueryWrapper <>();
//SELECT id,user_name,password,name,age,email FROM tb_user WHERe (password = ? AND age >= ? AND name IN (?,?,?))
wrapper.eq("password", "123456")
.ge("age", 20)
.in("name", "李四", "王五", "赵六");
List users = userMapper.selectList(wrapper);
for (User user : users) {
System.out.println(user);
}
}
模糊查询
- like
- LIKE ‘%值%’
- 例: like("name", "王")—>name like '%王%'
- notLike
- NOT LIKE ‘%值%’
- 例: notLike("name", "王")—>name not like '%王%'
- likeLeft
- LIKE ‘%值’
- 例: likeLeft("name", "王")—>name like '%王'
- likeRight
- LIKE ‘值%’
- 例: likeRight("name", "王")—>name like '王%'
测试代码:
@Test
public void testLike(){
QueryWrapper wrapper = new QueryWrapper <>();
// SELECT id,user_name,password,name,age,email FROM tb_user WHERe (name LIKE ?)
// %五(String)
wrapper.likeLeft("name", "五");
List users = userMapper.selectList(wrapper);
for (User user : users) {
System.out.println(user);
}
}
逻辑查询
-
or
- 拼接 OR
- 例: eq("id",1).or().eq("name","老王")—>id = 1 or name = '老王'
-
and
-
AND 嵌套
-
例: and(i -> i.eq("name", "李白").ne("status", "活着"))—>and (name = '李白' and status <> '活着')
-
注意事项:主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接)
测试代码:
@Test
public void testOr(){
QueryWrapper wrapper = new QueryWrapper <>();
//SELECT id,user_name,password,name,age,email FROM tb_user WHERe (name = ? OR age = ?)
wrapper.eq("name", "王五").or().eq("age", 21);
List users = userMapper.selectList(wrapper);
for (User user : users) {
System.out.println(user);
}
}
排序
-
order
- 排序:ORDER BY 字段, …
- 例: orderBy(true, true, "id", "name")—>order by id ASC,name ASC
-
orderBy
- 排序:ORDER BY 字段, … ASC
- 例: orderByAsc("id", "name")—>order by id ASC,name ASC
-
orderByAsc
- 排序:ORDER BY 字段, … ASC
- 例: orderByAsc("id", "name")—>order by id ASC,name ASC
-
orderByDesc
- 排序:ORDER BY 字段, … DESC
- 例: orderByDesc("id", "name")—>order by id DESC,name DESC
@Test public void testOrderByAgeDesc(){ QueryWrapperwrapper = new QueryWrapper <>(); // SELECT id,user_name,password,name,age,email FROM tb_user ORDER BY age DESC wrapper.orderByDesc("age"); List users = userMapper.selectList(wrapper); for (User user : users) { System.out.println(user); } }
- 设置查询字段
- 例: select("id", "name", "age")
- 例: select(i -> i.getProperty().startsWith("test"))
@Test
public void testSelect(){
QueryWrapper wrapper = new QueryWrapper <>();
//com.rg.boot.MybatisPlusSpringbootApplicationTests#testSelect
wrapper.eq("name","王五")
.or()
.eq("age",21)
.select("id","name","age");//指定查询的字段
List users = userMapper.selectList(wrapper);
for (User user : users) {
System.out.println(user);
}
}
groupBy
groupBy(R... columns) groupBy(boolean condition, R... columns)
- 分组:GROUP BY 字段, …
- 例: groupBy("id", "name")—>group by id,name
-
isNull
- 字段 IS NULL
- 例: isNull("name")—>name is null
-
isNotNull
- 字段 IS NOT NULL
- 例: isNotNull("name")—>name is not null



