一、简单测试MybatisPlus
1_1.导入数据库脚本
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)
);
DELETE FROM user;
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');
1_2.创建一个springboot项目并导入依赖
不用jdbc???
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
1_3.application连接数据库
spring.datasource.username=root
spring.datasource.password=3333
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatisPlus?useSSl=true&useUnicode=true&characterEncoding=utf-8&serverTimezeno=GMT%2B8
1_4.建立pojo类(和数据库列名相一致)
-------------pojo/user
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
1_5.在main函数处开启mapper接口扫描
扫描我们的mapper文件夹,相当于以往在xml文件中绑定mapper接口和xml文件
@MapperScan("com.junjun.mapper")
@SpringBootApplication
public class MybatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusApplication.class, args);
}
}
1_6.创建UserMapper接口
---------mapper/UserMapper
1.在对应的Mapper接口上面继承BaseMapper类,这样所有的crud已经编写完成了,而不用再写xml文档来实现UserMapper接口
@Repository
public interface UserMapper extends BaseMapper<User> {
}
1_7.测试类
@SpringBootTest
class MybatisPlusApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void testSelectAll() {
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
@Test
public void testInsert(){
User user=new User();
user.setName("junjun");
user.setAge(12);
user.setEmail("3124992817@qq.com");
int insert = userMapper.insert(user);
System.out.println(insert);
}
@Test
public void testUpdate(){
User user=new User();
user.setId(1440230999140052997L);
user.setName("junjun4");
user.setAge(16);
user.setEmail("3124992817@qq.com");
int insert = userMapper.updateById(user);
}
}
二、主键生成策略
1.Auto:1.该属性在数据库中是自增,2.使用@TableId(type = IdType.AUTO)注解 2.input:可以手动输入id,但是如果不输入id,当数据库存在自增时,就会自增,否则为空(当id为主键时,主键为空就会报错)。
public enum IdType {
AUTO(0),
NONE(1),
INPUT(2),
ID_WORKER(3),
UUID(4),
ID_WORKER_STR(5);
private int key;
private IdType(int key) {
this.key = key;
}
public int getKey() {
return this.key;
}
}
2_1.实现自增
只需要修改pojo和数据库就行了 -----------mysql数据库
alter table user change id id bigint auto_increment;
----------pojo/User
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
}
三、自动填充
3_1 数据库级别自动填充
1.当创建这两列时会(通过默认值)自动填充内容create_time和update_time。且当插入数据时也会通过默认值自动填充
3_1_1数据库添加列并配置默认值
alter table user add create_time datetime default current_timestamp;
alter table user add update_time datetime default current_timestamp;
3_1_2 java插入值(不输入time会自动填充)
@Test
public void testInsert(){
User user=new User();
user.setName("junjun100");
user.setAge(12);
user.setEmail("3124992817@qq.com");
int insert = userMapper.insert(user);
System.out.println(insert);
}
??
3_1 代码级别的自动填充
3_1_1在pojo需要自动填充的属性上添加注解
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
3_1_2配置填充策略
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ......");
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ......");
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
3_1_3测试
@Test
public void testInsert(){
User user=new User();
user.setName("junjun100");
user.setAge(12);
user.setEmail("3124992817@qq.com");
int insert = userMapper.insert(user);
System.out.println(insert);
}
-----------结果如下
??
四、乐观锁和悲观锁(多线程防止出现安全问题)
4_1 乐观锁???没学懂
总是默认不出现问题,当出现问题(上锁失败)时就更新
4_1_1 给数据库添加version字段
SELECT * FROM mybatisplus.user;
4_1_2配置乐观锁的插件
@MapperScan("com.junjun.mapper")
@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
4_1_3给user类添加Version字段和@Version注解
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
@Version
private Integer Version;
}
4_1_4测试
@Test
public void testOptimisticLocker(){
User user=userMapper.selectById(1L);
user.setName("root");
user.setEmail("111111111@qq.com");
userMapper.updateById(user);
}
@Test
public void testOptimisticLocker2(){
User user1=userMapper.selectById(1L);
user1.setName("root1111");
user1.setEmail("111111111@qq.com");
User user2=userMapper.selectById(1L);
user2.setName("root2222");
user2.setEmail("111111111@qq.com");
userMapper.updateById(user1);
userMapper.updateById(user2);
}
4_2 悲观锁
总是默认会出现问题,更新时就一定要上锁
五、常用查表
5_1 按数据库中顺序测试批量查询
@Test
public void tesSelectByBatchId(){
List<User> users=userMapper.selectBatchIds(Arrays.asList(1,2,3,7));
users.forEach(System.out::println);
}
5_2 条件查询(除了id之外的条件查询)
@Test
public void tesSelectByName(){
HashMap<String,Object> map=new HashMap<>();
map.put("name","junjun");
List<User> users=userMapper.selectByMap(map);
users.forEach(System.out::println);
}
5_3 分页查询
测试分页查询:1.原生limit 2.pageHelper第三方插件(MP内置了插件)
5_3_1配置拦截器
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor PaginationInterceptor(){
return new PaginationInterceptor();
}
}
5_3_2直接用page来查询(效率较低)
@Test
public void tesPage(){
Page<User> page=new Page<>(2,5);
userMapper.selectPage(page,null);
page.getRecords().forEach(System.out::println);
}
五、常用删表
5_1通过id删除
@Test
public void testDeleteById(){
userMapper.deleteById(1440230999140053005L);
}
5_2 批量删除
@Test
public void testDeleteBatchId(){
userMapper.deleteBatchIds(Arrays.asList(1440230999140053004L,1440230999140052997L));
}
5_3通过map删除
@Test
public void testDeleteMap(){
HashMap<String,Object> map=new HashMap<>();
map.put("name","junjun");
userMapper.deleteByMap(map);
}
5_4逻辑删除
物理删除: 逻辑删除:数据库中没有移除,但是我们查看不到他(如:回收站原理)
5_4_1在数据库中添加一个delete字段
默认0为未删除,1为已删除
alter table user add deleted int(1) not null default 0;
5_4_2导入逻辑删除插件
@Configuration
public class MybatisPlusConfig {
@Bean
public ISqlInjector sqlInjector(){
return new LogicSqlInjector();
}
}
5_4_3使用上述任意删除方式删除
低版本要在application.properties中导入
#mybatis-plus.global-config.db-config.logic-not-delete-value=0
#mybatis-plus.global-config.db-config.logic-delete-value=1
六、附加功能
6_1性能分析插件
用于输出每条sql及其执行的时间
6_1_1导入性能分析插件
@Configuration
public class MybatisPlusConfig {
@Bean
@Profile({"dev","test"})
public PerformanceInterceptor performanceInterceptor(){
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(100);
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
}
6_1_2在application.properties开启dev环境
spring.profiles.active=dev
spring.datasource.username=root
spring.datasource.password=3333
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatisPlus?useSSl=true&useUnicode=true&characterEncoding=utf-8&serverTimezeno=GMT%2B8
#serverTimezeno=GMT%2B8
#配置日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
6_1_3任意查询测试结果
6_2 条件构造器wrap
在测试函数中使用wrapper来限制复杂条件
@SpringBootTest
public class WrapperTest {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads1(){
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper
.isNotNull("name")
.isNotNull("email")
.ge("age",12);
userMapper.selectList(wrapper).forEach(System.out::println);
}
@Test
void test2(){
QueryWrapper<User> wrapper= new QueryWrapper<>();
wrapper.eq("name","jack");
System.out.println(userMapper.selectOne(wrapper));
}
@Test
void test3(){
QueryWrapper<User> wrapper= new QueryWrapper<>();
wrapper.between("age",10,20);
System.out.println(userMapper.selectCount(wrapper));
}
@Test
void test4(){
QueryWrapper<User> wrapper= new QueryWrapper<>();
wrapper
.notLike("name","e")
.like("name","j");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
@Test
void test5(){
QueryWrapper<User> wrapper= new QueryWrapper<>();
wrapper
.inSql("id","select id from user where id<3");
List< Object> objects= userMapper.selectObjs(wrapper);
objects.forEach(System.out::println);
}
@Test
void test6(){
QueryWrapper<User> wrapper= new QueryWrapper<>();
wrapper
.orderByDesc("id","name");
List< Object> objects= userMapper.selectObjs(wrapper);
objects.forEach(System.out::println);
}
}
6_3 代码生成器(根据数据库直接生成java代码)
你已经是个成熟的框架了,是时候学会自己写代码了
6_3_1创建一个数据库并连接数据库
创建项目的数据库
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)
);
DELETE FROM user;
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');
6_3_2 导入依赖
<dependencies>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
6_3_3 使用代码生成器生成基本代码
能根据你数据库的内容生成java文件包和代码
public class junCode {
public static void main(String[] args) {
AutoGenerator mpg=new AutoGenerator();
GlobalConfig globalConfig = new GlobalConfig();
String projectPath=System.getProperty("user.dir");
globalConfig
.setOutputDir(projectPath+"/src/main/java")
.setAuthor("君哥")
.setOpen(false)
.setFileOverride(true)
.setServiceName("%sService")
.setIdType(IdType.ID_WORKER)
.setDateType(DateType.ONLY_DATE)
.setSwagger2(true);
mpg.setGlobalConfig(globalConfig);
DataSourceConfig dsc = new DataSourceConfig();
dsc
.setUrl("jdbc:mysql://localhost:3306/mybatisPlus?useSSl=true&useUnicode=true&characterEncoding=utf-8&serverTimezeno=GMT%2B8")
.setDriverName("com.mysql.cj.jdbc.Driver")
.setUsername("root")
.setPassword("3333")
.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
PackageConfig pc = new PackageConfig();
pc
.setParent("com.mybatisplus_test_02")
.setModuleName("blog")
.setEntity("entity")
.setMapper("mapper")
.setService("service")
.setController("controler");
mpg.setPackageInfo(pc);
StrategyConfig sc = new StrategyConfig();
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT);
ArrayList<TableFill> tableFills=new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
sc
.setInclude("user")
.setNaming(NamingStrategy.underline_to_camel)
.setColumnNaming(NamingStrategy.underline_to_camel)
.setSuperEntityClass("")
.setEntityLombokModel(true)
.setLogicDeleteFieldName("deleted")
.setTableFillList(tableFills)
.setVersionFieldName("version")
.setRestControllerStyle(true);
mpg.setStrategy(sc);
mpg.execute();
}
}
6_3_4 在java文件下得到一个文件夹
??
|