new Module -> 填入属性
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.6.3version>
<relativePath/>
parent>
<groupId>com.ypygroupId>
<artifactId>mybatisplus_quickstartartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>mybatisplus_quickstartname>
<description>mybatisplus_quickstartdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.5.0version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.2.16version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.23version>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.26version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
username: root
password: root
# 开启mybatis-plus日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain=true)
@AllArgsConstructor
@NoArgsConstructor
@Data
@TableName(value = "tb_user")
public class User {
@TableId("id")
private Long id;
private String username;
private String password;
private String gender;
private String addr;
}
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ypy.mybatisplus_quickstart.model.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
@SpringBootTest
class MybatisplusQuickstartApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void testGetAll() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("gender","男");
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
}
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.3)
2023-11-13 14:37:57.566 INFO 4740 --- [ main] .m.MybatisplusQuickstartApplicationTests : Starting MybatisplusQuickstartApplicationTests using Java 1.8.0_221 on DESKTOP-YPYJE7C with PID 4740 (started by ypykip in D:\Application\WorkSpace\self-learn\base-learn\mybatisplus_quickstart)
2023-11-13 14:37:57.566 INFO 4740 --- [ main] .m.MybatisplusQuickstartApplicationTests : No active profile set, falling back to default profiles: default
org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@4d33940d
_ _ |_ _ _|_. ___ _ | _
| | |\/|_)(_| | |_\ |_)||_|_\
/ |
3.5.0
2023-11-13 14:37:59.217 INFO 4740 --- [ main] .m.MybatisplusQuickstartApplicationTests : Started MybatisplusQuickstartApplicationTests in 1.909 seconds (JVM running for 2.778)
2023-11-13 14:37:59.567 INFO 4740 --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
[User(id=9, username=小奥, password=456, gender=男, addr=北京)]
2023-11-13 14:38:00.669 INFO 4740 --- [ionShutdownHook] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} closing ...
2023-11-13 14:38:00.671 INFO 4740 --- [ionShutdownHook] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} closed
Process finished with exit code 0
MyBatisPlus概述
● MyBatisP1us(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率
● 官网:https://mybatis.plus/ (网友送的) https://mp.baomidou.com/
@SpringBootTest
class MybatisplusQuickstartApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void testSave(){
User user = new User();
user.setId(2L).setUsername("tt").setGender("女").setAddr("天津").setPassword("123456");
userMapper.insert(user);
}
@Test
void testPage() {
IPage<User> page = new Page<>(2,3);
userMapper.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());
}
@Test
public void testGetAll() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("gender","男");
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
}
@Component
public class MpInterceptor {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
// 测试
@Test
void testPage() {
IPage<User> page = new Page<>(2,3);
userMapper.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());
}
@Test
public void testGetAll() {
// 方式一: 按条件查询
// QueryWrapper qw = new QueryWrapper<>();
// qw.eq("gender","男");
// 方式二:lambda格式条件查询
// QueryWrapper qw = new QueryWrapper<>();
// qw.lambda().gt(User::getAge,25);
// 方式三: lambda格式条件查询【推荐】
LambdaQueryWrapper<User> qw = new LambdaQueryWrapper<>();
qw.gt(User::getAge,25).lt(User::getAge,30);
// qw.lt(User::getAge,25).or().gt(User::getAge,30);
List<User> users = userMapper.selectList(qw);
System.out.println(users);
}
@Test
public void testUq() {
// 模拟页面传递过来的查询数据
UserQuery uq = new UserQuery();
//uq.setAge(25);
uq.setAge2(30);
// null判定(下限没有设置,查询不出结果数据)
/*LambdaQueryWrapper lqw = new LambdaQueryWrapper<>();
lqw.lt(User::getAge,uq.getAge2());
lqw.gt(User::getAge,uq.getAge());*/
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.lt(uq.getAge2() != null, User::getAge, uq.getAge2());
lqw.gt(uq.getAge() != null, User::getAge, uq.getAge());
// lqw.lt(uq.getAge2() != null, User::getAge, uq.getAge2())
// .gt(uq.getAge() != null, User::getAge, uq.getAge());
List<User> users = userMapper.selectList(lqw);
System.out.println(users);
}
// 只将id和age查询出来,其他为null
@Test
public void testQs(){
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.select(User::getId,User::getAge);
List<User> userList = userMapper.selectList(lqw);
System.out.println(userList);
}
// 分组查询使用到投影
@Test
public void testSelectCount() {
QueryWrapper<User> lqw = new QueryWrapper<>();
lqw.select("count(*) as count, gender");
lqw.groupBy("gender");
List<Map<String, Object>> maps =
userMapper.selectMaps(lqw);
System.out.println(maps);
}
//[{gender=男, count=2}, {gender=女, count=2}]
@Test
public void testCondition() {
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
String username = "乐";
String password = "";
lqw.eq(User::getUsername, username).eq(User::getPassword, password);
User users = userMapper.selectOne(lqw);
System.out.println(users);
// 范围查询: lt le gt ge eq between
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.between(User::getAge,25,30);
List<User> users1 = userMapper.selectList(wrapper);
System.out.println(users1);
// 模糊匹配 like
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.likeRight(User::getUsername,"周");
User user = userMapper.selectOne(queryWrapper);
System.out.println(user);
// 更多查询条件设置参看 https://baomidou.com/pages/10c804/#abstractwrapper
}
属性注解,位置:模型类属性定义上方,作用:设置当前属性对应的数据表的字段关系
范例:
@TableName("tb_user")
public class User {
@TableFiled(value ="pwd", select = false) // 告诉mp pwd 不参与查询
private String password;
@TableFiled(exist = false)
private Integer online; // 表示表里面不存在这个字段
}
package com.baomidou.mybatisplus.annotation;
public enum IdType {
/**
* 数据库ID自增
* 该类型请确保数据库设置了 ID自增 否则无效
*/
AUTO(0),
/**
* 该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
*/
NONE(1),
/**
* 用户输入ID
* 该类型可以通过自己注册自动填充插件进行填充
*/
INPUT(2),
/**
* 分配ID (主键类型为number或string),
* 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(雪花算法)
*
* @since 3.3.0
*/
ASSIGN_ID(3),
/**
* 分配UUID (主键类型为 string)
* 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(UUID.replace("-",""))
*/
ASSIGN_UUID(4);
private final int key;
private IdType(int key) {
this.key = key;
}
public int getKey() {
return this.key;
}
}
如果想要使用数据库的自增策略,那么就可以使用type = IdType.AUTO,
如果需要让程序员自己指定id,那么就可以在实体类上使用type = IdType.INPUT,并且注意,将表上的id生成
策略去掉
如果使用雪花算法生成,则可以使用type=IdType.ASSIGN_ID,这个会生成64bit的数,也就是说数据库表的id
必须是64位的int
如果想要使用uuid,可以使用type=IdType.ASSIGN_UUID.
#applicaiton.yml文件
db-config:
id-type: assign_uuid
table-prefix: tb_
@Test
public void testBatchSearchOrDelete(){
// 批量删除
Object[] ids = new Object[]{8,2};
userMapper.deleteBatchIds(Arrays.asList(ids));
// 批量查询
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 10, 9));
System.out.println(users);
}
@TableLogic(value = "0",delval = "1")
private Integer deleted;
@Test
public void testDelete(){
userMapper.deleteById(1);
}
# 输入logic-delete即可
logic-delete-field: deleted
logic-not-delete-value: 0
logic-delete-value: 1
mp逻辑删除会将delete修改为update语句,并且在查询全部的时候,会加上条件 deleted = 0;
执行原理(依赖版本信息)
==> Preparing: UPDATE tb_user SET version=? WHERE id=? AND version=? AND deleted=0
==> Parameters: 2(Integer), 9(String), 1(Integer)
// 在数据库表中添加一个字段:
alter table tb_user add column version int default 1;
// 在实体类上添加一个属性:
@Version
private Integer version;
// 在mp拦截器上添加乐观锁拦截器
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
// 测试
@Test
void testOptimisticLock() {
// 先查询,后更新
boolean flag = false;
while (!flag) {
User user = userMapper.selectById("9");
user.setId("9").setUsername("version修改");
int count = userMapper.updateById(user);
if (count == 1)
flag = true;
}
}
// 查看输出结果:
==> Preparing: SELECT id,username,password,gender,addr,age,deleted,version FROM tb_user WHERE id=? AND deleted=0
==> Parameters: 9(String)
<== Columns: id, username, password, gender, addr, age, deleted, version
<== Row: 9, 小奥, 456, 男, 北京, 36, 0, 2
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7397c6]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@295bf2a] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@36061cf3] will not be managed by Spring
==> Preparing: UPDATE tb_user SET username=?, password=?, gender=?, addr=?, age=?, version=? WHERE id=? AND version=? AND deleted=0
==> Parameters: version修改(String), 456(String), 男(String), 北京(String), 36(Integer), 3(Integer), 9(String), 2(Integer)
<== Updates: 1