----线程1
// 1、查询id为1的用户
User user = userDao.selectById(1L);
// 2、修改用户信息
user.setName("Gump111");
user.setEmail("3218289928@qq.com");
//---------模拟另外一个线程执行了插队操作
// 1、查询id为1的用户
User user2 = userDao.selectById(1L);
// 2、修改用户信息
user2.setName("Gump222");
user2.setEmail("3218289928@qq.com");
// 线程2 执行更新操作
userDao.updateById(user2);
// 线程1执行更新操作
userDao.updateById(user);//如果没有乐观锁,就会覆盖插队线程刚刚修改的值
}
### 五、分页查询
1、导入分页插件,在配置类中添加
```JAVA
// 扫描mapper文件夹
@MapperScan("cn.nongyanxia.mapper")
@EnableTransactionManagement //事务注解
@Configuration
public class MyBatisPlusConfig {
// 注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
2、直接使用Page对象
//测试分页查询
@Test
public void testPage(){
// 查询第一页的5条数据 参数1:当前页 参数2:一页几条
Page<User> page = new Page<>(1,5);
userDao.selectPage(page, null);
page.getRecords().forEach(System.out::println);
// 总数
System.out.println(page.getTotal());
}
六、条件构造器Wrapper
十分重要!!!
我们写一些复杂的sql就可以用它来替代!
官方文档:https://baomidou.com/guide/wrapper.html
1、测试1
代码:
//测试查询1
@Test
void contextLoads() {
// 查询name不为空的用户,并且游戏不为空的用户,并且年龄大于等于18岁的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name")//名字不为空
.isNotNull("email")//邮箱不为空
.ge("age", 18);//大于等于
userDao.selectList(wrapper).forEach(System.out::println);
}
执行的SQL:
SELECT id,name,age,email,version,deleted,create_time,update_time FROM user WHERE deleted=0 AND (name IS NOT NULL AND email IS NOT NULL AND age >= ?)
2、测试2
代码:
@Test
void test02(){
//查询名字等于 Gump 的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "Gump");
User user = userDao.selectOne(wrapper);
System.out.println(user);
}
SQL:
SELECT id,name,age,email,version,deleted,create_time,update_time FROM user WHERE deleted=0 AND (name = ?)
3、测试3
代码:
@Test
void test03(){
//查询年龄在20~30岁之间的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age", 20, 30);
Integer num = userDao.selectCount(wrapper);//查询结果数
System.out.println(num);
}
SQL:
SELECT COUNT( 1 ) FROM user WHERE deleted=0 AND (age BETWEEN ? AND ?)
4、测试4
代码:
//模糊查询
@Test
void test04(){
//查询名字中不包含 G 的用户,并且邮箱是以3开头的
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.notLike("name", "G")
.likeRight("email", "3");
List<Map<String, Object>> maps = userDao.selectMaps(wrapper);
maps.forEach(System.out::println);
}
SQL:
SELECT id,name,age,email,version,deleted,create_time,update_time FROM user WHERE deleted=0 AND (name NOT LIKE ? AND email LIKE ?)
5、测试5
代码:
@Test
void test05(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
// id在子查询中查出来
wrapper.inSql("id", "select id from user where id < 3");
List<Object> objects = userDao.selectObjs(wrapper);
objects.forEach(System.out::println);
}
SQL:
SELECT id,name,age,email,version,deleted,create_time,update_time FROM user WHERE deleted=0 AND (id IN (select id from user where id < 3))
6、测试6
代码:
@Test
void test06(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 通过id进行排序
// 倒序 Asc 正序
wrapper.orderByDesc("id");
List<User> users = userDao.selectList(wrapper);
}
SQL:
SELECT id,name,age,email,version,deleted,create_time,update_time FROM user WHERE deleted=0 ORDER BY id DESC
七、代码自动生成器
AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
由于MyBatis-Plus 从 3.0.3
之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖,由于我配置写了swagger,所以还需要导入swagger的依赖,以及lombok插件
1、pom.xml
<!--MyBatis_Plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!--代码生成器依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.2</version>
</dependency>
<!--默认的模板引擎依赖-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
<!--swagger-->
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2、代码:
package cn.nongyanxia;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
//代码自动生成器
public class GumpCode {
public static void main(String[] args) {
// 需要构建代码生成器对象
AutoGenerator mpg = new AutoGenerator();
//配置策略
//---------1、全局配置
GlobalConfig config = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
config.setOutputDir(projectPath+"/src/main/java");
//设置作者
config.setAuthor("Gump");
//是否打开Windows文件夹
config.setOpen(false);
//是否覆盖
config.setFileOverride(false);
//去service的 i 前缀
config.setServiceName("%sService");
//主键生成策略
config.setIdType(IdType.ASSIGN_UUID);
//日期类型
config.setDateType(DateType.ONLY_DATE);
//是否配置swagger文档
config.setSwagger2(true);
mpg.setGlobalConfig(config);
//--------2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&serverTimezone=GMT%2B8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("529122");
//数据库类型 为MySQL
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//----------3、包的配置
PackageConfig pc = new PackageConfig();
//模块名称
pc.setModuleName("blog");
//生成cn.nongyanxia.blog 的模块
pc.setParent("cn.nongyanxia");
//配置包的名称
pc.setEntity("pojo");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
mpg.setPackageInfo(pc);
//---------4、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("user");
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true); //自动lombok
strategy.setLogicDeleteFieldName("deleted");//逻辑删除字段
strategy.setRestControllerStyle(true);//开启restful的驼峰命名格式
//自动填充配置
TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
TableFill updateTime = new TableFill("update_time", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(createTime);
tableFills.add(updateTime);
strategy.setTableFillList(tableFills);
//乐观锁配置
strategy.setVersionFieldName("version");
strategy.setControllerMappingHyphenStyle(true);//localhost:8080/hello_id_2
mpg.setStrategy(strategy);
mpg.execute();//执行
}
}
3、运行后结果
这样就算成功了!
Q.E.D.