快速入门程序
官网:MyBatis-Plus
maven配置如下依赖文件:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
&lt;dependency&gt;
&lt;groupId&gt;com.alibaba&lt;/groupId&gt;
&lt;artifactId&gt;
druid
&lt;/artifactId&gt;
&lt;version&gt;1.1.16&lt;/version&gt;
&lt;/dependency&gt;
&amp;lt;dependency&amp;gt;
&amp;lt;groupId&amp;gt;org.mybatis.spring.boot&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;mybatis-spring-boot-starter&amp;lt;/artifactId&amp;gt;
&amp;lt;version&amp;gt;3.0.2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
&amp;lt;groupId&amp;gt;com.mysql&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;mysql-connector-j&amp;lt;/artifactId&amp;gt;
&amp;lt;scope&amp;gt;runtime&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;spring-boot-starter-test&amp;lt;/artifactId&amp;gt;
&amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
&amp;lt;groupId&amp;gt;org.mybatis.spring.boot&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;mybatis-spring-boot-starter-test&amp;lt;/artifactId&amp;gt;
&amp;lt;version&amp;gt;3.0.2&amp;lt;/version&amp;gt;
&amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/dependencies&gt;</code></pre>
application.yml:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatislearn?serverTimezone=UTC
username: root
password: root
UserDao:
@Mapper
public interface UserDao extends BaseMapper<User> {
`}`
<br />
Test:
@SpringBootTest
class MplearnApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testGetAll() {
List<User> users = userDao.selectList(null);
System.out.println(users);
}
`}`
<br />
crud使用
新增
@SpringBootTest
class MplearnApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testGetAll() {
User user = new User();
user.setName("测试");
user.setAge(11);
user.setEmail("test@163.com");
userDao.insert(user);
}
}
删除
@Test
void testDelete(){
userDao.deleteById(7);
}
更改
@Test
void testUpdate(){
User user = new User();
user.setId(5);
user.setName("fish");
userDao.updateById(user);
}
查多个
@Test
void testGetAll(){
List<User> userList = userDao.selectList(null);
System.out.println(userList);
}
开启mp日志,输出控制台日志
再application.yml中加入
application.yml
# 开启mp的日志(输出控制台)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
标准分页功能
首先需要开启拦截器:
@Configuration
public class MyConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//1.定义mp拦截器
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//2.添加具体拦截器
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
然后就可以使用标准分页:
@Test
void testGetBypage(){
//1表示第几页,3表示一页多少条
IPage page = new Page(1,3);
userDao.selectPage(page,null);
System.out.println("当前页码值"+page.getCurrent());
System.out.println("每页显示的数量"+page.getSize());
System.out.println("一共多少页"+page.getPages());
System.out.println("一共多少条数据"+page.getTotal());
System.out.println("数据"+page.getRecords());
}
DQL编程控制
条件查询
第一种是直接进行查询,后面的都是使用lambda表达式进行查询的。
@Test
void selectTry(){
//方式一:按条件查询
// QueryWrapper qw = new QueryWrapper();
// qw.lt("age",18);
// List<User> userList = userDao.selectList(qw);
// System.out.println(userList);
//方式二:Lambda格式按条件查询
// QueryWrapper&lt;User&gt; qw = new QueryWrapper&lt;User&gt;();
// qw.lambda().lt(User::getAge,20);
// List&lt;User&gt; userList = userDao.selectList(qw);
// System.out.println(userList);
//方式三:Lambda格式按条件查询
LambdaQueryWrapper&amp;lt;User&amp;gt; lqw = new LambdaQueryWrapper&amp;lt;User&amp;gt;();
// lqw.lt(User::getAge,20); // lqw.gt(User::getAge,8); //或者直接使用链式编程:10-30岁之间 // lqw.lt(User::getAge,20).gt(User::getAge,8); //小于十岁或者大于三十岁 lqw.lt(User::getAge,8).or().gt(User::getAge,20); List&lt;User&gt; userList = userDao.selectList(lqw); System.out.println(userList); }
<br />
null值处理
当多条件的时候,有些条件值为空,就不会执行该条件的判断,语法如下:
@Test
void selectNull(){
//模拟页面传递过来的查询数据
UserQuery uq = new UserQuery();
// uq.setAge(10);
uq.setAge2(30);
//空判定
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
// lqw.lt(User::getAge,uq.getAge2());
//先判断第一个参数是否为true,如果是true连接条件,要是是false就不连
lqw.lt(null!=uq.getAge2(),User::getAge,uq.getAge2());
lqw.gt(null!=uq.getAge(),User::getAge,uq.getAge());
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
查询投影
设置查询的字段名,只查询该字段。
@Test
void selectTouying(){
// LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//查询结果只看这些字段,只适用于lambda格式
// lqw.select(User::getId,User::getName);
QueryWrapper<User> lqw = new QueryWrapper<User>();
lqw.select("id","name");
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
}
查询数据总数:
@Test
void selectTouying(){
QueryWrapper<User> lqw = new QueryWrapper<User>();
lqw.select("count(*) as count");
List<Map<String,Object>> userList = userDao.selectMaps(lqw);
System.out.println(userList);
}
}
查询条件
@Test
void selectCondition(){
//类似登录操作
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//等同于=
lqw.eq(User::getName,"Jone").eq(User::getAge,18);
User loginUser = userDao.selectOne(lqw);
System.out.println(loginUser);
}&lt;/code&gt;&lt;/pre&gt;
另一段范围查询
//查询条件
LambdaQueryWrapper&lt;User&gt; lqw = new LambdaQueryWrapper&lt;User&gt;();
//范围查询 lt le gt ge eq between
lqw.between(User::getAge,10,30);
List&lt;User&gt; userList = userDao.selectList(lqw);
System.out.println(userList);
模糊查询:
likeLeft 表示的是左边是 百分号,以j结尾的数据
likeRight 表示的是右边是 百分号 ,以j开头的数据
//查询条件
LambdaQueryWrapper&lt;User&gt; lqw = new LambdaQueryWrapper&lt;User&gt;();
//模糊匹配
lqw.like(User::getName,&quot;j&quot;);
List&lt;User&gt; userList = userDao.selectList(lqw);
System.out.println(userList);
字段映射和表名映射
问题一
使用场景,当属性名字与字段名不匹配的时候使用
-
名称@TableField
-
类型:属性注解
-
位置:模型类属性定义上方。
-
作用:设置当前属性对应的额数据库表中的字段关系
-
范例:
public class User{
@TableField(value=&quot;pwd&quot;)
private String password;
}
-
相关属性
-
value(默认):设置数据库表字段名称
问题二
编码中添加了数据库中未定义的属性
属性中出现了数据库中没有定义的属性。
未定义的属性上面添加注解@TableField(exist = false)
问题三
采用默认查询开放了更多的字段查看权限
通过一个注解,实现指定字段不允许查询
-
名称:@TableField
-
类型:属性注解
-
位置:模型类属性定义上方
-
作用:设置当前属性对应的数据库表中的字段关系
-
范例:
public class User{
@TableField(value=&quot;pwd&quot;,select = false)
private String password;
}
-
相关属性
-
value:设施之数据库表字段名称
-
exist:设置属性再数据库表字段中是否存在,默认为true。此属性无法与value合并使用
-
selsect:设置属性是否参与查询,此属性select()映射配置不冲突。
问题四
表名与编码开发设计不同步
-
名称:@TableName
-
类型:类注解
-
位置:模型类定义上方
-
作用:设置当前类对应与数据库表关系
-
范例:
@TableName(&quot;tbl_user&quot;)
public class User{
private Long id;
}
-
相关属性
-
value:设置数据库表名称。
DML编程控制
id生成策略控制
-
名称:@TableId
-
类型 :属性注解
-
位置:模型类中用于表示主键的属性定义上方
-
作用:设置当前类中主键属性的生成策略
-
范例:
public class User{
@TableId(type = IdType.AUTO)
private Long id;
}
-
相关属性
-
value:设置数据库主键名称
-
type:设置主键的生成策略,值参照IdType枚举值。
全局设置
要是希望全局的id生成策略都是一样的,可以通过去配置文件Application.yml中使用id-type来指定全部id的生成策略。
要是希望类中表名的前缀进行全局设置,可以去配置文件Application.yml中使用table-prefix来进行设置。
![image-20230819104039415](http://static.51tbox.com/static/2024-11-15/col/ebd7b5429d015fbe4804e0c5caa95e6a/e1d46e8edf154137b91e56ef1c98c528.png.jpg "image-20230819104039415")
MP实现多条数据删除
通过传入一个list,然后就可以进行删除
@Test
void testDelete2(){
List&lt;Long&gt; list = new ArrayList&lt;&gt;();
list.add(3L);
list.add(4L);
userDao.deleteBatchIds(list);
}
同理,selectBatchIds也是一样的效果,查询多个id的数据。
逻辑删除
删除操作业务问题:业务数据从数据库中丢弃。
逻辑删除:为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中。
在逻辑删除字段的属性上面添加一个注解@TableLogic(value=&quot;0&quot;,delval = &quot;1&quot;)
,用来进行逻辑删除,设置指定值表示当前数据已经被删除。0表示当前数据正常 ,1表示当前数据已经被删除。
![image-20230819111203815](http://static.51tbox.com/static/2024-11-15/col/ebd7b5429d015fbe4804e0c5caa95e6a/d8c739f8269b401da6433b81864940eb.png.jpg "image-20230819111203815")
如果添加了逻辑操作,那么对数据删除的时候并不会真正删除数据,只会对这个逻辑的数据字段进行Update
,让其显示为不可见状态。
可以直接在全局设置那里进行设置通用的逻辑删除字段。Application.yml
logic-delete--field:deleted
logic-not--delete-value:0 (设置没有删的值)
logic-delete-value:1 (设置删除的值)
![image-20230819111744965](http://static.51tbox.com/static/2024-11-15/col/ebd7b5429d015fbe4804e0c5caa95e6a/33a9f721211e4ab1b43888d0c7bace47.png.jpg "image-20230819111744965")
乐观锁
业务并发现象带来的问题:秒杀。
首先新建一个字段version
。给对应的version属性添加一个注解@Version
,
然后在之前分页拦截器那里,再加一句话即可。
@Configuration
public class MyConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//1.定义mp拦截器
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//2.添加具体拦截器
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
//3.添加乐观锁拦截器
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
}
使用乐观锁:
//1. 先通过要修改的数据id将当前数据查询出来
User user = userDao.selectById(3L);
//2.将要修改的属性注意设置进去
user.setName(&quot;Jock888&quot;);
userDao.updateById(user);
代码生成器
首先需要导入两个配置文件
&lt;!--代码生成器--&gt;
&lt;dependency&gt;
&lt;groupId&gt;com.baomidou&lt;/groupId&gt;
&lt;artifactId&gt;mybatis-plus-generator&lt;/artifactId&gt;
&lt;version&gt;3.4.1&lt;/version&gt;
&lt;/dependency&gt;
&lt;!--Velocity模板引擎--&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.apache.velocity&lt;/groupId&gt;
&lt;artifactId&gt;velocity-engine-core&lt;/artifactId&gt;
&lt;version&gt;2.3&lt;/version&gt;
&lt;/dependency&gt;
然后进行设置相关配置,运行即可自动生成
public class Generator {
public static void main(String[] args) {
AutoGenerator autoGenerator = new AutoGenerator();
DataSourceConfig dataSource = new DataSourceConfig();
dataSource.setDriverName(&quot;com.mysql.cj.jdbc.Driver&quot;);
dataSource.setUrl(&quot;jdbc:mysql://localhost:3306/mybatislearn?serverTimezone=UTC&quot;);
dataSource.setUsername(&quot;root&quot;)
dataSource.setPassword(&quot;root&quot;);
autoGenerator.setDataSource(dataSource);
autoGenerator.execute();
}
`}`
<br />
更多配置,需要去官网查阅即可!