使用第三方组件
guid:--link
1导入对应依赖
2研究依赖如何配置
3代码如何编写
4提高扩展技术能力
新建数据库,测试用
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);真实开发,version乐观锁,deleted逻辑删除,gmt_create,gmt-modified
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');导入依赖包
<!-- 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>使用mybatis-plus可以节省代码,尽量不要同时导入mybatis和mybatis-plus,因为会有冲突
连接数据库,配置applicaiton.properties
spring.datasource.username=koa2weibo
spring.datasource.password=passMYblog123
spring.datasource.url=jdbc:mysql://rm-uf6t9m0yx22dxrya5no.mysql.rds.aliyuncs.com:3306/koa2weibo?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=UTF8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# useSSL=true会报错,空了研究下原因
#mysql8.0需要增加时区,否则报错
#mysql8.0
#配置mybatis-plus日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl传统方式:
pojo层--》dao层(连接mybatis层,配置mapper.xml)--》service层--〉controller层
新的开发方式:使用了mybatis-plus之后
pojo层--》mapper接口--〉使用
新方法:
pojo层
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}Mapper,UserMapper接口interface
package com.xuwen.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xuwen.pojo.User;
import org.springframework.stereotype.Repository;
//在对应的Mapper上,继承(extends)基本的接口,BaseMapper<泛型>
//@Repository注解,代表是dao层
@Repository
public interface UserMapper extends BaseMapper<User> {
//所有的CRUD已经编写完成!已经不需要像以前一样,配置一大堆文件了
}
main方法,需要添加注解,去扫描Mapper下面的包,不写报错
@MapperScan("com.xuwen.mapper")
@SpringBootApplication
public class MybatisPlusDemoApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusDemoApplication.class, args);
}
}测试一下,先@Autowired注入,Mapper的信息
//测试
@SpringBootTest
class MybatisPlusDemoApplicationTests {
//注入
//继承了BaseMapper,所有的方法均来自,父类,我们也可以编写自己的扩展方法
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
//查询所有用户
//必传的蚕食是Wrapper,是一个条件构造器,不用先写null
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
}截图信息

CRUD扩展
insert
//测试插入
@Test
public void testInsert(){
User user = new User();
user.setName("文文学java");
user.setAge(18);
user.setEmail("betsyxw@gmail.com");
int result = userMapper.insert(user);
System.out.println("受影响的行数:"+result);
System.out.println(user);
}主键生成策略,UUID,雪花算法,redis生成,zookeeper生成
分布式系统唯一ID生成方案
snowflask是twitter的分布式ID,结果是一个Long的id,雪花算法id
修改实体类:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
//全球唯一,默认id,IdType.ID_WORKER
@TableId(type = IdType.ID_WORKER)
private Long id;
private String name;
private Integer age;
private String email;
}我们需要配置数据库,主键自增,
1实体类上,需要自增@TableId(type = IdType.AUTO)
2数据库要勾选自增。
更新
//测试更新
@Test
public void testUpdate(){
User user = new User();
user.setId(5L);
user.setName("世界上没有学不会,只有自己懒");
//注意,updateById,参数是一个对象
int i = userMapper.updateById(user);
System.out.println("受影响的行数"+i);
}自动填充
创建时间,修改时间。基本都是数据库自动更新,自动更新!!!
阿里巴巴开发手册,gtm_create,gmt_modified
方式一:数据库级别--推荐使用
数据表中新增字段,gtm_create,gtm_modified(create_time,update_time)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
private Date createTime;
private Date updateTime;
}方式二:代码级别
乐观锁,悲观锁
乐观锁:十分乐观,觉得不会出现问题,如果出现问题,再次更新值测试,version
悲观锁:十分悲观,干什么都会出问题,干什么都会上锁,再去操作。
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
https://baomidou.com/guide/interceptor-optimistic-locker.html#optimisticlockerinnerinterceptor
A线程
update user set name="kuangshen", version = version+1
where id = 2 and version =1;
B线程
update user set name= "kuangshen", version = version+1
where id= 2 and version =1;第一步给数据库,新增version字段
mybatis-plus自带的乐观锁插件

第二步:实体类新增字段
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
private Date createTime;
private Date updateTime;
@Version
private Integer version;
}第三步:注册主键
新增文件夹config,新增一个配置类,MybatisPlusConfig类
@MapperScan("com.xuwen.mapper")//注解,是扫描mapper文件夹!
@EnableTransactionManagement//自动管理事务
@Configuration//配置类!!!注解
public class MyBatisPlusConfig {
//注册乐观锁插件
/**
* 旧版
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
批量查询
//批量查询
@Test
public void testSelectByBatchId(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
}条件map查询
//条件查询map
@Test
public void testSelectByBatchIds(){
HashMap<String,Object> map = new HashMap<>();
//自定义要查询的内容
map.put("name","狂神说java");
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}分页
支持的数据库
mysql 、mariadb 、oracle 、db2 、h2 、hsql 、sqlite 、postgresql 、sqlserver 、presto 、Gauss 、Firebird
Phoenix 、clickhouse 、Sybase ASE 、 OceanBase 、达梦数据库 、虚谷数据库 、人大金仓数据库 、南大通用数据库
配置分页拦截器
config里面
@MapperScan("com.xuwen.mapper")//注解,是扫描mapper文件夹!
@EnableTransactionManagement//自动管理事务
@Configuration//配置类!!!注解
public class MyBatisPlusConfig {
//注册乐观锁插件
/**
* 旧版
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}test分页查询
//测试分页查询
@Test
public void testPage(){
Page<User> page = new Page<>(1,5);
userMapper.selectPage(page,null);
page.getRecords().forEach(System.out::println);
}删除操作
逻辑删除
deleted=0
deleted=1
需改实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
private Date createTime;
private Date updateTime;
@Version
private Integer version;
@TableLogic
private Integer deleted;
}
修改config类
@MapperScan("com.xuwen.mapper")//注解,是扫描mapper文件夹!
@EnableTransactionManagement//自动管理事务
@Configuration//配置类!!!注解
public class MyBatisPlusConfig {
//注册乐观锁插件
/**
* 旧版
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
//逻辑删除插件
@Bean
public ISqlInjector sqlInjector(){
return new LogicSqlInjector();
}
}配置application.properites
#配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0性能分析插件
applicaiton.properites
#设置开发环境
spring.profiles.active=devmybatis.config配置类
//逻辑删除组件
public PerformanceInterceptor performanceInterceptor(){
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(100);//sql执行的最大时间,超过这个时间,则不执行
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}条件查询器Wrapper

测试一:复杂条件查询
@SpringBootTest
public class WrapperTest {
//加载类
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
//查询,name不为空,邮箱不为空,年龄大于xx岁的用户
//Wrapper是一个对象
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name")
.isNotNull("email")
.ge("age",12);
userMapper.selectList(wrapper).forEach(System.out::println);
}
}测试二:
//测试二:
@Test
void test2(){
//查询name=文文学java
//eq=equals
//selectOne查询一个数据,如果多个数据请用List或者Map
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","文文学java");
System.out.println(userMapper.selectOne(wrapper));
}测试三:
//测试三:
//between and
@Test
void test3(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age",20,30);
Integer count = userMapper.selectCount(wrapper);
System.out.println(count);
}测试四:
//测试四:
//模糊查询
@Test
void test4(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//左边,右边,区分,%e,e%
wrapper.notLike("name","java")
.likeRight("email","t");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}测试五:
//测试五
//内查询,
@Test
void test5(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//id在自查询中查出
wrapper.inSql("id","select id from user where id<=3");
List<Object> objects = userMapper.selectObjs(wrapper);
objects.forEach(System.out::println);
}测试六
//测试六
//order by
@Test
void test6(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//通过id降序
wrapper.orderByDesc("id");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}代码自动生成器
dao,pojo,service,controller让程序自己写。
添加 代码生成器 依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,用户可以选择自己熟悉的模板引擎,如果都不满足您的要求,可以采用自定义模板引擎。
Velocity(默认):
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>latest-velocity-version</version></dependency>
Freemarker:
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>latest-freemarker-version</version></dependency>
Beetl:
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>latest-beetl-version</version></dependency>
注意!如果您选择了非默认引擎,需要在 AutoGenerator 中 设置模板引擎。
AutoGenerator generator = new AutoGenerator();
// set freemarker engine
generator.setTemplateEngine(new FreemarkerTemplateEngine());
// set beetl engine
generator.setTemplateEngine(new BeetlTemplateEngine());
// set custom engine (reference class is your custom engine class)
generator.setTemplateEngine(new CustomTemplateEngine());
// other config
...
MyBatisPlusConfig配置类
package com.xuwen.config;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.apache.ibatis.javassist.tools.rmi.AppletServer;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* author:xuwen
* Created on 2021/8/7
*/
@MapperScan("com.xuwen.mapper")//注解,是扫描mapper文件夹!
@EnableTransactionManagement//自动管理事务
@Configuration//配置类!!!注解
public class MyBatisPlusConfig {
//注册乐观锁插件
/**
* 旧版
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
//逻辑删除插件
@Bean
public ISqlInjector sqlInjector(){
return new LogicSqlInjector();
}
//sql执行效率插件
public PerformanceInterceptor performanceInterceptor(){
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(100);//sql执行的最大时间,超过这个时间,则不执行
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
}
代码生成器
手工策略,test新建一个类
package com.xuwen;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
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;
/**
* author:xuwen
* Created on 2021/8/8
*/
//Mybatis-plus代码自动生成器
public class xuwenMybaitsCode {
public static void main(String[] args) {
//第一步:构建一个代码生成器 对象
AutoGenerator mpg = new AutoGenerator();
//第二步:配置策略
//1全剧配置-不要倒错包!!com.baomidou.mybatisplus.generator.config.GlobalConfig;
GlobalConfig gc = new GlobalConfig();
//获取当前系统目录
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath+"/src/main/java");
gc.setAuthor("xuwen");
gc.setOpen(false);
gc.setFileOverride(false);
gc.setServiceName("%sService");//去掉Service的I前缀
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true);//swagger开发文档
mpg.setGlobalConfig(gc);
//2设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://rm-uf6t9m0yx22dxrya5no.mysql.rds.aliyuncs.com:3306/koa2weibo?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=UTF8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("koa2weibo");
dsc.setPassword("passMYblog123");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//3配置生成包,生成那些包,包放在哪些位置
PackageConfig pc = new PackageConfig();
pc.setModuleName("blog");
pc.setParent("com.xuwen");
pc.setEntity("pojo");
pc.setMapper("mapper");
pc.setController("controller");
pc.setService("service");
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");//逻辑删除的字段名
//数据库自动填充配置
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
//add添加上方的策略
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
strategy.setTableFillList(tableFills);
//乐观锁
strategy.setVersionFieldName("version");
//驼峰命名开启
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);//Localhost:8080/hello_id_2
//把上方所有的策略,扔到mpg里面
mpg.setStrategy(strategy);
mpg.execute();//执行
}
}