Spring Boot整合mybatis-puls(用爱发电版)
第一部分:介绍一下mybatis-plus以及她的一些优点
- mybatis-plus官网强烈建议学习的时候可以去官网查,官网讲的也比较仔细
- 这里是我的理解:之前用过jpa也用过mybatis,jpa的特点就是普通的单表操作超级简单,但是多表操作就非常复杂,很难理解,操作的是实体对象,针对的是一个数据表,所以每次返回的都是你操作这个数据库表的实体对象。mybatis的特点就是多表操作比较方便,但是对应的简单curd都需要写sql语句,mapper,就显得比较臃肿,mybatis-plus就像是综合了他们的优点。对于简单的单表操作,自己封装了一套方法,对于多表操作也是和mybatis一样,
- 所以官网这样介绍mybatis-plus:MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。是最受欢迎的后端框架的第二名
因为这是一篇用爱发电的文章,所以就不多介绍他的特点,官网都可以看到,下面就直接讲怎么用吧
第一步:pom文件映入依赖
<dependency>
<!--开源项目名字叫baomidou(苞米豆)挺可爱的--><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.1.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>
第二步:application.yml配置文件
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=CTTusername: rootpassword: 123456
#输出日志
logging:level:root: warnmp.dao: tracepattern:console: "%p%m%n"mybatis-plus:# 在classpath前添加星号可以使项目热加载成功mapper-locations: classpath*:mybatis/**/*Mapper.xml
configuration:map-underscore-to-camel-case: truecache-enabled: false# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
配置文件里的都可以去官网查到具体干嘛的,当然还有很多其他的配置,总之mybatis-plus这么受欢迎是有原因的。
第三步:emmmm,没有第三步下面就可以直接查啦
- 通用 CRUD
先放一个user实体类
package mp.entity;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.util.Date;@Data//之前的博客有讲这个注解
@TableName("user")//指定特定的数据库表,但只要不是差别很大,不用指定也可以
public class User {//主键@TableId("id")//用来标识实体类的主键,以便插件在生成主键雪花Id的时候找到哪个是主键。private String userid;//因为指定了id所所以这名字可以任取,不与数据库id名一样private String name;@TableField("role")//当取名不一样可以用这个注解private String role;private Date retime;private Integer age;/*** mp排除非表字段的三种方式* 1:Transient声明的成员变量不参与序列化过程: private Transient String remark;* 2:如果有序列化要求;设置为静态变量 private static String remark;(但要写getset方法)* 3: @TableField(exist=false)*///数据库中没有这一条字段,这里只是暂时后台调用这条数据 ,// private String remark;
}
这个实体类解释的够详细吧
假设我们已存在一张 User 表,且已有对应的实体类 User,实现 User 表的 CRUD 操作我们需要做什么呢?
/** User 对应的 Mapper 接口 */
public interface UserMapper extends BaseMapper<User> { }
对没错,你只需要写一个接口集成BaseMapper这个通用的mapper
// 初始化 User 对象
User user = new User();// 插入 User (插入成功会自动回写主键到实体类)
user.setName("demo");
result = userMapper.insert(user);// 更新 User
user.setAge(18);
result = userMapper.updateById(user);// 查询 User
User exampleUser = userMapper.selectById(user.getId());// 查询姓名为‘demo’的所有用户记录
List<User> userList = userMapper.selectList(new EntityWrapper<User>().eq("hero", "demo")
);// 删除 User
result = userMapper.deleteById(user.getId());
是不是出现了一些新的东西了感觉?什么是eq这就需要你们去官网查了,这是mybatis-plus的条件构造器AbstractWrapper,定义了很多的方法,用到什么去看一看就好了
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
上面的这三种都是mybatis-plus的新特性,lambda调用后面会讲到,支持自动主键生成很强了,有基于facebook的雪花算法也有其他的id类型,这需要你在上面的配置里卖弄配置你想要的id算法,默认好像就是雪花算法,也可以自己设置id。AR模式的话,简单试着用了下,感觉方便还是方便,不过就是一种新的思路理解了。
简单讲一下AR模式吧:
你甚至上面讲的统用mapper都不用实现只需要实体类继承extends Model<>就可以了
package mp.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;@Data
@TableName("test")//指定特定的数据库表,但只要不是差别很大,不用指定也可以
public class Test extends Model<Test> {//主键@TableId(type= IdType.UUID)//用来标识实体类的主键,以便插件在生成主键雪花Id的时候找到哪个是主键。//String类型的idprivate String id;//因为指定了id所所以这名字可以任取,不与数据库id名一样private String name;private Integer age;
}
用测试方法写了curd
package mp;import mp.entity.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@SpringBootTest
@RunWith(SpringRunner.class)
public class ARtest {//这里类名和test注解重名了所以加test 注解的时候需要详细一点@org.junit.Testpublic void arinsert() {Test test = new Test();test.setName("埃及和奶");test.setAge(90);boolean flag = test.insert();//AR模式下的curdSystem.out.println(flag);}@org.junit.Testpublic void selectByid() {Test test = new Test();Test newTest = test.selectById(123);//返回的是一个新对象}@org.junit.Testpublic void selectByid2() {Test test = new Test();test.setId("123");Test newTest = test.selectById();//返回的是一个新对象}@org.junit.Testpublic void updateByid() {Test test = new Test();test.setId("123");test.setName("sdfsdsdf");test.updateById();//返回的是一个boolean}@org.junit.Testpublic void deleteByid() {Test test = new Test();test.setId("123");test.deleteById();//返回的是一个boolean}}
实体类都有了,下面就在代码里面讲Lambda和其他条件数据库操作吧,耐心吧下面的代码看完,你就知道mybatis-plus是怎么操作数据库的了,代码注释很多,你会看懂的
@Autowiredprivate UserMapper userMapper;@Testpublic void insert(){User user = new User();user.setUserid("00");//可以不设置id,会自动生成user.setName("向不i哦啊的");user.setRole("dsa12q d");user.setRetime(new Date());int rows = userMapper.insert(user);//返回成功数量}
private UserMapper userMapper;查询多个id,返回对象集合public void selectids(){List<String> idsList = Arrays.asList("0","5","9");List<User> userList = userMapper.selectBatchIds(idsList);userList.forEach(System.out::println);
}//根据多个条件,查询返回符合条件的所有对象,list集合//map中的键(key)是数据库中的列名不是实体中的属性名public void selectByMap(){//map.put("name","顺丰大概");//map.put("role","dsa12q d");//这样就类似于where name = "顺丰大概" and role = "dsa12q d"Map<String,Object> columnMap = new HashMap<>();columnMap.put("name","顺丰大概");columnMap.put("role","dsa12q d");List<User> userList = userMapper.selectByMap(columnMap);userList.forEach(System.out::println);}/*** 条件构造器:*名字中含有三,且角色是员工的* name like ‘%三%’ and age < 40* queryWrapper.select("id","name")like("name","三").lt("age",40);//这里返回的是这个对象的固定两个字段,返回的还是对象*/@Testpublic void selectByWrapper(){QueryWrapper<User> queryWrapper = new QueryWrapper<User>();//QueryWrapper继承了AbstraptWrapper// QueryWrapper<User> query = Wrappers.<User>query();和上面一样。queryWrapper.like("name","三").lt("age",40);//lt()//默认条件是小于List<User> userList =userMapper.selectList(queryWrapper);userList.forEach(System.out::println);/**名字中含有三,且年龄在20和40之间,角色是不为空的* name like ‘%三%’ and age between 20 and 40 and role is not null* queryWrapper.like("name","三").between(“age”,20,40).isNotNull(“role”)** 名字为张姓或者年龄大于等于25,按照年龄降序排序,年龄相同按照id升序排列* name like “张%” or age >=25 order by age desc,id asc;//默认是and如果是or需要.or();* queryWrapper.likeRight("name","张").or().ge("age",25).orderByDesc("age").orderByAsc("id");** 创建日期是2019年2月11日并且直属上级为名字为王性* dete_format(create_time,'%y-%m-%d')and manager_id in(select id from user where name like "王%")//子查询就是inSql* queryWrapper.apply("dete_format(create_time,'%y-%m-%d')={0}","2019-02-11").inSql("manager_id","select id from user where name like "王%"")//* 上面查时间也有一个 参数的方法,但有可能sql注入的问题(就是sql语句中不小心写了其他(or true or true)查询结果就不对,产生风险)** 名字为王性并且(年龄小于40或邮箱不为空) wq->wq是lomoda表达式* queryWrapper.likeRight("name","王").and(wq->wq.lt("age",40).or().isNotNull("email"));** 名字为王性或者(年龄小于40并且年龄大于20并且邮箱不为空)* name like '王%' or (age< 40 and age >20 and email is not null)* queryWrapper.likeRight("name","王").or(wq->wq.lt("age",40).gt("age".20).isNotNull("email"))** (年龄小于40或者邮箱不为空)并且名字为王性//括号和没有括号不一样。or的优先级小于and的优先级* (age <40 or email is not null)and name like '王%'* queryWrapper.nested(wq->wq.ly("age",40).or().isNotNull(email)).likeRight("name","王")** 年龄是31,30,35* age in (31,30,35)* queryWrapper.in(“age”,Arrays.asList(31,30,35))** 返回满足条件的一条语句,而不是返回所有满足的结果* limit 1* queryWrapper.in(“age”,Arrays.asList(31,30,35)).last("limit 1")** 条件构造器中condition的使用* 就是当前端传来两个变量要查询的时候,前端可以只输入一个变量也可以查询,condition作为一个条件,如果true就表示这个语句静茹查询条件* name like ‘%三%’ and age < 40 //以前是先写个判断语句在查询,现在只用一行,就可以是实现* queryWrapper.like(StringUtils.isNotEmpty(name),"name","name").like(StringUtils.isNotEmpty(email),"email","email");/*queryWrapper.like(condition,"name","name")//condition来控制where语句加不加入到sql语句中** //实体作为条件构造器构造方法的参数,这样会将user1对象中的所有非空的属性加入sql语句查询,也可以再继续加条件,是互不干扰了,但不要重了* //当controller中用实体接受前台页面传过来的数据,这样就可以全部或者部分不用写条件,之间对象查找* QueryWrapper<User> queryWrapper = new QueryWrapper<User>(user1);//QueryWrapper继承了AbstraptWrapper* List<User> userList =userMapper.selectList(queryWrapper);*/}@Test//lambda条件构造器,防止写错数据库中字段名public void selectLambda() {LambdaQueryWrapper<User> lambda = new QueryWrapper<User>().lambda();//QueryWrapper继承了AbstraptWrapper// QueryWrapper<User> query = Wrappers.<User>query();和上面一样。lambda.like(User::getName, "三").lt(User::getAge, 40);//lt()//默认条件是小于List<User> userList = userMapper.selectList(lambda);userList.forEach(System.out::println);}//分页查询@Testpublic void selectByPage() {QueryWrapper<User> queryWrapper = new QueryWrapper<User>();//QueryWrapper继承了AbstraptWrapperqueryWrapper.like("name","三");Page<User> page = new Page<User>(1,2);
// IPage<User> ipage = userMapper.selectPage(page,queryWrapper);//返回实体IPage<Map<String,Object>> ipage = userMapper.selectMapsPage(page,queryWrapper);//返回mapSystem.out.println("总页数:"+ipage.getPages());System.out.println("总记录数:"+ipage.getTotal());List<Map<String,Object>> userList = ipage.getRecords();userList.forEach(System.out::println);}public void selectAll() {LambdaQueryWrapper<User> lambda = new QueryWrapper<User>().lambda();//QueryWrapper继承了AbstraptWrapperlambda.like(User::getName, "三").lt(User::getAge, 40);List<User> userList =userMapper.selectAll(lambda);userList.forEach(System.out::println);public void selectById(){User user = userMapper.selectById(9);System.out.println(user);}@Testpublic void deleteById(){int rows = userMapper.deleteById("0");System.out.println(rows);}@Test//符合条件都都将会删除public void deleteByMap(){Map<String,Object> columnMap = new HashMap<>();columnMap.put("name","顺丰大概");columnMap.put("role","dsa12q d");int rows = userMapper.deleteByMap(columnMap);}@Test//同时删除多个记录public void deleteByds(){int rows = userMapper.deleteBatchIds(Arrays.asList("5","9"));System.out.println(rows);}@Test//带条件构造器的删除方法public void deleteByWrapper(){LambdaQueryWrapper<User> lambdaQuery = Wrappers.<User>lambdaQuery();lambdaQuery.eq(User::getAge,33).or().gt(User::getAge,47);int rows = userMapper.delete(lambdaQuery);System.out.println(rows);}}
看到这是不是有点疑问,这怎么和mybatis的完全不一样啊,没有xml,没有配置,上面讲的就是mybatis-plus的新特性,新的查询方法,这就是他官网讲的没有改变只是提高,这就是提高的那一部分,原来mybatis的那样的操作也可以使用,就是原来一样,
以上就是博主一天的学习成果啦,看官网的文档很有帮助,还有就是看baseMapper的源码,按住ctrl点击就可以景区看源码啦,这个框架的源码相对来说还是比较简单易懂的。进阶程序员必备技能,理解源码如果感觉有帮助就点赞鼓励下吧,嘿嘿
Spring Boot整合mybatis-puls(用爱发电版)相关推荐
- Spring Boot整合MyBatis框架(XML文件版)
1.创建数据库.数据库表并插入数据 创建数据库springboot: CREATE DATABASE springboot; 创建数据库表user: CREATE TABLE `user` (`id` ...
- Spring Boot 教程(三): Spring Boot 整合Mybatis
教程简介 本项目内容为Spring Boot教程样例.目的是通过学习本系列教程,读者可以从0到1掌握spring boot的知识,并且可以运用到项目中.如您觉得该项目对您有用,欢迎点击收藏和点赞按钮, ...
- spring boot 整合mybatis 无法输出sql的问题
使用spring boot整合mybatis,测试功能的时候,遇到到了sql问题,想要从日志上看哪里错了,但是怎么都无法输出执行的sql,我使用的是log4j2,百度了一下,很多博客都说,加上下面的日 ...
- Spring boot 整合 Mybatis 实现增删改查(MyEclipse版)
1.首先搭建好一个Spring boot 程序,编写好启动类. 启动类代码如下: @SpringBootApplication public class Start {public static vo ...
- spring boot整合mybatis+通用mapper+pagehelper分页插件
spring boot整合mybatis+通用mapper+pagehelper分页插件 pom依赖 <?xml version="1.0" encoding="U ...
- spring boot整合mybatis步骤
spring boot整合mybatis步骤 官方说明:MyBatis-Spring-Boot-Starter will help you use MyBatis with Spring Boot 其 ...
- Spring Boot整合MyBatis
最近项目原因可能会继续开始使用MyBatis,已经习惯于spring-data的风格,再回头看xml的映射配置总觉得不是特别舒服,接口定义与映射离散在不同文件中,使得阅读起来并不是特别方便. Spri ...
- Spring Boot基础学习笔记06:Spring Boot整合MyBatis
文章目录 零.学习目标 1.了解Spring Boot数据访问概述 2.掌握使用注解的方式整合MyBatis 3.掌握使用配置文件的方式整合MyBatis 一.Spring Boot数据访问概述 二. ...
- Spring Boot 整合MyBatis(23)
Spring Boot 整合MyBatis Spring Boot 整合 Druid 引入依赖 配置 application.yml pring Boot 整合 tk.mybatis 引入依赖 配置 ...
最新文章
- 系统安装操作优化:chapter 3 安装windos操作系统。
- boost::hana::product用法的测试程序
- GNU __attribute 详解
- 如何开展软件架构之概念架构
- c mysql ssh_c ssh mysql数据库
- maven 打包指定依赖包_Maven打包成Jar文件时依赖包的问题
- vue2.0中vue-router使用总结
- 鸿蒙OS应用开发_基础篇_编写第一个HarmonyOs应用_体会HarmonyOs的一次开发多端部署_以及分布式任务调度_IDE安装_了解应用组件以及应用布局---HarmonyOs开发工作笔记001
- NSNumber的使用
- VNC Connect Enterprise for mac(远程桌面软件)
- 人生最大的难题是认清自己
- LaTeX中段落缩进的概念
- 【Python】解决使用 plt.savefig 保存图片时一片空白
- 一个精明主妇写的省钱过日子的好贴
- 主题 02:如何设计系统预案(Preplan)?
- Java实现字母去重
- 2022卡塔尔世界杯:跨境卖家如何用YouTube进行营销?
- 移动 网络 连mysql_中国移动MySQL数据库优化最佳实践
- valgrind详细说明
- Java选择语句练习