springboot整合mybatis-plus_文字描述springboot整合mybatis-plus过程-程序员宅基地

技术标签: spring boot  mysql  mybatis-plus  

Mybatis-plus前言:

mybatis在持久层框架中还是比较火的,一般项目都是基于ssm。

虽然mybatis可以直接在xml中通过SQL语句操作数据库,很是灵活。但正其操作都要通过SQL语句进行,就必须写大量的xml文件,很是麻烦。mybatis-plus就很好的解决了这个问题

一、mybatis-plus简介:

Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

这是官方给的定义,关于mybatis-plus的更多介绍及特性,可以参考mybatis-plus官网

那么它是怎么增强的呢?其实就是它已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,就类似于JPA

先聊聊 什么是 ORM

  • ORM映射思想说明
  • Java对象操作表

二、springboot整合mybatis-plus

正如官方所说,mybatis-plus在mybatis的基础上只做增强不做改变,因此其与spring的整合亦非常简单。

只需把mybatis的依赖换成mybatis-plus的依赖,再把sqlSessionFactory换成mybatis-plus的即可。

接下来看具体操作: 1、pom.xml: 核心依赖如下:

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
​
 <dependencies>
<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>
        <!--mp依赖包-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-extension</artifactId>
            <version>3.3.2</version>
        </dependency>
​
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
​
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
​
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
​
​
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
      </dependencies>
   <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

注意: 这些是核心依赖,本项目还用到了mysql驱动、c3p0、日志(slf4j-api,slf4j-log4j2)、lombok。

集成mybatis-plus要把mybatis、mybatis-spring去掉,避免冲突;lombok是一个工具,添加了这个依赖,开发工具再安装Lombok插件,就可以使用它了,最常用的用法就是在实体类中使用它的@Data注解,这样实体类就不用写set、get、toString等方法了。

2、yaml文件配置

spring:
  # 数据源的配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/heimaxxx?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username: root
    password: root
​
mybatis-plus:
  type-aliases-package: cn.itcast.xxx.pojo  # 实体类包路径
  configuration:
    #   sql日志显示,这里使用标准显示
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    #  数据库中如果有类似 如  user_name 等命名,会将 _后的字母大写,这里是为了和实体类对应
    map-underscore-to-camel-case: true

3、entity+sql

@Data
@TableName(value = "tb_employee")//指定表名
public class Employee {
    //value与数据库主键列名一致,若实体类属性名与表主键列名一致可省略value
    @TableId(value = "id",type = IdType.AUTO)//指定自增策略
    private Integer id;
    //若没有开启驼峰命名,或者表中列名不符合驼峰规则,可通过该注解指定数据库表中的列名,exist标明数据表中有没有对应列
    @TableField(value = "last_name",exist = true)
    private String lastName;
    private String email;
    private Integer gender;
    private Integer age;
}
​
​
/*
Navicat MySQL Data Transfer
​
Source Server         : keep_health
Source Server Version : 50622
Source Host           : localhost:3306
Source Database       : lucky08
​
Target Server Type    : MYSQL
Target Server Version : 50622
File Encoding         : 65001
​
Date: 2020-08-13 15:42:49
*/
​
SET FOREIGN_KEY_CHECKS=0;
​
-- ----------------------------
-- Table structure for tb_employee
-- ----------------------------
DROP TABLE IF EXISTS `tb_employee`;
CREATE TABLE `tb_employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `lastname` varchar(20) DEFAULT NULL,
  `gender` varchar(10) DEFAULT NULL,
  `email` varchar(30) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `version` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
​
-- ----------------------------
-- Records of tb_employee
-- ----------------------------
INSERT INTO `tb_employee` VALUES ('2', '郭富城', '男性', '[email protected]', '48', null);
INSERT INTO `tb_employee` VALUES ('3', 'tom', null, null, null, null);
INSERT INTO `tb_employee` VALUES ('4', 'marry', null, null, null, null);
INSERT INTO `tb_employee` VALUES ('5', 'jerry', null, null, null, null);
​

4、mapper:

public interface EmplopyeeMapper extends BaseMapper<Employee> {
}

这样就完成了mybatis-plus与spring的整合。首先是把mybatis和mybatis-spring依赖换成mybatis-plus的依赖,然后把sqlsessionfactory换成mybatis-plus的,然后实体类中添加@TableName@TableId等注解,最后mapper继承BaseMapper即可。

5、测试:

@SpringBootTest
@RunWith(SpringRunner.class)
public class BankApplicationTests {
    
        @Autowired
    private  EmplopyeeMapper EmplopyeeMapper;
    
}

三、mp的通用crud:

需求: 存在一张 tb_employee 表,且已有对应的实体类 Employee,实现tb_employee 表的 CRUD 操作我们需要做什么呢? 基于 Mybatis: 需要编写 EmployeeMapper 接口,并在 EmployeeMapper.xml 映射文件中手动编写 CRUD 方法对应的sql语句。 基于 MP: 只需要创建 EmployeeMapper 接口, 并继承 BaseMapper 接口。 我们已经有了Employee、tb_employee了,并且EmployeeDao也继承了BaseMapper了,接下来就使用crud方法。

1、insert操作:

​
    @Autowired
    private EmplopyeeDao emplopyeeDao;
    @Test
    public void testInsert(){
        Employee employee = new Employee();
        employee.setLastName("东方不败");
        employee.setEmail("[email protected]");
        employee.setGender(1);
        employee.setAge(20);
        emplopyeeDao.insert(employee);
        //mybatisplus会自动把当前插入对象在数据库中的id写回到该实体中
        System.out.println(employee.getId());
    }
​

执行添加操作,直接调用insert方法传入实体即可。

2、update操作:

@Test
public void testUpdate(){
        Employee employee = new Employee();
        employee.setId(1);
        employee.setLastName("更新测试");
        //emplopyeeDao.updateById(employee);//根据id进行更新,没有传值的属性就不会更新
        emplopyeeDao.updateAllColumnById(employee);//根据id进行更新,没传值的属性就更新为null
}

注: 注意这两个update操作的区别,updateById方法,没有传值的字段不会进行更新,比如只传入了lastName,那么age、gender等属性就会保留原来的值;updateAllColumnById方法,顾名思义,会更新所有的列,没有传值的列会更新为null。

3、select操作:

(1)、 根据id查询:

Employee employee = emplopyeeDao.selectById(1);

(2)、 根据条件查询一条数据:

Employee employeeCondition = new Employee();
employeeCondition.setId(1);
employeeCondition.setLastName("更新测试");
//若是数据库中符合传入的条件的记录有多条,那就不能用这个方法,会报错
Employee employee = emplopyeeDao.selectOne(employeeCondition);

注: 这个方法的sql语句就是where id = 1 and last_name = 更新测试,若是符合这个条件的记录不止一条,那么就会报错。

(3)、 根据查询条件返回多条数据: 当符合指定条件的记录数有多条时,上面那个方法就会报错,就应该用这个方法。

Map<String,Object> columnMap = new HashMap<>();
columnMap.put("last_name","东方不败");//写表中的列名
columnMap.put("gender","1");
List<Employee> employees = emplopyeeDao.selectByMap(columnMap);
System.out.println(employees.size());

注: 查询条件用map集合封装,columnMap,写的是数据表中的列名,而非实体类的属性名。比如属性名为lastName,数据表中字段为last_name,这里应该写的是last_name。selectByMap方法返回值用list集合接收。

(4)、 通过id批量查询:

注: 把需要查询的id都add到list集合中,然后调用selectBatchIds方法,传入该list集合即可,该方法返回的是对应id的所有记录,所有返回值也是用list接收。

(5)、分页查询

List<Employee> employees = emplopyeeDao.selectPage(new Page<Employee>(1,2),null);
System.out.println(employees);

注: selectPage方法就是分页查询,在page中传入分页信息,后者为null的分页条件,这里先让其为null,讲了条件构造器再说其用法。

这个分页其实并不是物理分页,而是查询表中所有数据。也就是说,实际查询的时候并没有limit语句

需要自己编写一个 配置类 : 把分页插件配置一下即可

确保springboot的启动类要可以扫描到该配置类即可

@EnableTransactionManagement
@Configuration
@MapperScan("com.itheima.mapper") //  mapper接口包
public class MybatisPlusConfig {
​
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        System.out.println("===============mybaitsplus==========pagination===============");
        return new PaginationInterceptor();
    }
​
}

4、delete操作:

(1)、 根据id删除:

emplopyeeDao.deleteById(1);

(2)、 根据条件删除:

Map<String,Object> columnMap = new HashMap<>();
columnMap.put("gender",0);
columnMap.put("age",18);
emplopyeeDao.deleteByMap(columnMap);

注: 该方法与selectByMap类似,将条件封装在columnMap中,然后调用deleteByMap方法,传入columnMap即可,返回值是Integer类型,表示影响的行数。

(3)、 根据id批量删除:

 List<Integer> idList = new ArrayList<>();
 idList.add(1);
 idList.add(2);
 emplopyeeDao.deleteBatchIds(idList);

注: 该方法和selectBatchIds类似,把需要删除的记录的id装进idList,然后调用deleteBatchIds,传入idList即可。

通过上面的小案例我们可以发现,实体类需要加@TableName注解指定数据库表名,通过@TableId注解指定id的增长策略。实体类少倒也无所谓,实体类一多的话也麻烦。所以可以在spring-dao.xml的文件中进行全局策略配置。

<!-- 5、mybatisplus的全局策略配置 -->
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
        <!-- 2.3版本后,驼峰命名默认值就是true,所以可不配置 -->
        <!--<property name="dbColumnUnderline" value="true"/>-->
        <!-- 全局主键自增策略,0表示auto -->
        <property name="idType" value="0"/>
        <!-- 全局表前缀配置 -->
        <property name="tablePrefix" value="tb_"/>
</bean>

这里配置了还没用,还需要在sqlSessionFactory中注入配置才会生效。如下:

<!-- 3、配置mybatisplus的sqlSessionFactory -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="typeAliasesPackage" value="com.zhu.mybatisplus.entity"/>
        <!-- 注入全局配置 -->
        <property name="globalConfig" ref="globalConfiguration"/>
</bean>

如此一来,实体类中的@TableName注解和@TableId注解就可以去掉了。

四、条件构造器(EntityWrapper):

以上基本的 CRUD 操作,我们仅仅需要继承一个 BaseMapper 即可实现大部分单表 CRUD 操作。BaseMapper 提供了多达 17 个方法供使用, 可以极其方便的实现单一、批量、分页等操作,极大的减少开发负担。但是mybatis-plus的强大不限于此,请看如下需求该如何处理: 需求: 我们需要分页查询 tb_employee 表中,年龄在 18~50 之间性别为男且姓名为 xx 的所有用户,这时候我们该如何实现上述需求呢? 使用MyBatis : 需要在 SQL 映射文件中编写带条件查询的 SQL,并用PageHelper 插件完成分页. 实现以上一个简单的需求,往往需要我们做很多重复单调的工作。 使用MP: 依旧不用编写 SQL 语句,MP 提供了功能强大的条件构造器 ------ EntityWrapper。

接下来就直接看几个案例体会EntityWrapper的使用。

1、分页查询年龄在18 - 50且gender为0、姓名为tom的用户:

List<Employee> employees = emplopyeeDao.selectPage(new Page<Employee>(1,3),
     new EntityWrapper<Employee>()
        .between("age",18,50)
        .eq("gender",0)
        .eq("last_name","tom")
);

注: 由此案例可知,分页查询和之前一样,new 一个page对象传入分页信息即可。至于分页条件,new 一个EntityWrapper对象,调用该对象的相关方法即可。between方法三个参数,分别是column、value1、value2,该方法表示column的值要在value1和value2之间;eq是equals的简写,该方法两个参数,column和value,表示column的值和value要相等。注意column是数据表对应的字段,而非实体类属性字段。

2、查询gender为0且名字中带有老师、或者邮箱中带有a的用户:

List<Employee> employees = emplopyeeDao.selectList(
                new EntityWrapper<Employee>()
               .eq("gender",0)
               .like("last_name","老师")
                //.or()//和or new 区别不大
               .orNew()
               .like("email","a")
);

注: 未说分页查询,所以用selectList即可,用EntityWrapper的like方法进行模糊查询,like方法就是指column的值包含value值,此处like方法就是查询last_name中包含“老师”字样的记录;“或者”用or或者orNew方法表示,这两个方法区别不大,用哪个都可以,可以通过控制台的sql语句自行感受其区别。

3、查询gender为0,根据age排序,简单分页:

List<Employee> employees = emplopyeeDao.selectList(
                new EntityWrapper<Employee>()
                .eq("gender",0)
                .orderBy("age")//直接orderby 是升序,asc
                .last("desc limit 1,3")//在sql语句后面追加last里面的内容(改为降序,同时分页)
);

注: 简单分页是指不用page对象进行分页。orderBy方法就是根据传入的column进行升序排序,若要降序,可以使用orderByDesc方法,也可以如案例中所示用last方法;last方法就是将last方法里面的value值追加到sql语句的后面,在该案例中,最后的sql语句就变为select ······ order by desc limit 1, 3,追加了desc limit 1,3所以可以进行降序排序和分页。

4、分页查询年龄在18 - 50且gender为0、姓名为tom的用户: 条件构造器除了EntityWrapper,还有Condition。用Condition来处理一下这个需求:

 List<Employee> employees = emplopyeeDao.selectPage(
                new Page<Employee>(1,2),
                Condition.create()
                        .between("age",18,50)
                        .eq("gender","0")
 );

注: Condition和EntityWrapper的区别就是,创建条件构造器时,EntityWrapper是new出来的,而Condition是调create方法创建出来。

5、根据条件更新:

@Test
public void testEntityWrapperUpdate(){
        Employee employee = new Employee();
        employee.setLastName("苍老师");
        employee.setEmail("[email protected]");
        employee.setGender(0);
        emplopyeeDao.update(employee,
                new EntityWrapper<Employee>()
                .eq("last_name","tom")
                .eq("age",25)
        );
}

注: 该案例表示把last_name为tom,age为25的所有用户的信息更新为employee中设置的信息。

6、根据条件删除:

emplopyeeDao.delete(
        new EntityWrapper<Employee>()
        .eq("last_name","tom")
        .eq("age",16)
);

注: 该案例表示把last_name为tom、age为16的所有用户删除。

总结:

上述mybatis-plus介绍了其

    • mybatis-plus与spring整合
    • 通用crud的使用
    • 全局策略的配置
    • 条件构造器的使用
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/bangyanya/article/details/129119099

智能推荐

浅测贝锐蒲公英A20-1226千兆AP(单台家用)_贝锐蒲公英 r3000a 功耗-程序员宅基地

文章浏览阅读340次。测试了2个位置,一个连接到了5G,另一个连接到了2.4G且只有286Mbps,2.4G和5G信号强度同样均比蒲公英X3A和红米AC2100要弱,尤其是5G,差别的原因可能与是否为承重墙有关。5G信号可穿普通墙,但穿不了承重墙。p.oray.com页面左侧设备管理下的AP管理页面提供批量管理页面,可添加设备(右侧蓝色按钮,支持批量导入),添加群组,查看AP设备信息和网络信息,并可以批量对AP进行导入配置(需先创建模板)、重启、升级等操作。802.11kvr漫游,更为稳定,不易掉线,无配对切换AP,未测试。_贝锐蒲公英 r3000a 功耗

穷举法求解鸡兔同笼问题_鸡兔同笼python穷举法-程序员宅基地

文章浏览阅读5.5k次,点赞2次,收藏4次。#include#includeusing namespace std;int main(){ //int heads = 23, feet = 60; int heads, feet; cout << "输入头,足的数量" << endl; cin >> heads >> feet; for(int i=0;i<35;i++) for (int j = 0;j<35; j_鸡兔同笼python穷举法

graphpad如何检测方差齐_方差分析中两两多重比较方法的含义及如何正确选择-程序员宅基地

文章浏览阅读4.5k次。欢迎订阅SPSS训练营微信号以SPSS方差分析为例,十多种多重比较方法可选,上图为英文视图,下图为中文翻译视图,请对照学习。简单介绍一下常用的方法它们的含义,以及如何正确恰当选择使用这些方法。LSDLSD:最小显著差异法,实际上是 t 检验的改进,检验统计量为T,在变异和自由度的计算上利用了整个样本信息,而不仅仅是比较两组的信息。它的敏感度最高,在比较时仍然存在放大α水准(一类错误)的问..._graphpad多重比较

Android 音频源码分析——音频设备切换(插入耳机)_usbalsadevice-程序员宅基地

文章浏览阅读5k次,点赞6次,收藏56次。源码分析基于android9.0通常带线耳机分类模拟耳机平时常用的3.5mm或6.3mm接口耳机,接收模拟信号(音频数据需要先处理,转码成pcm格式)Android中模拟耳机由WiredAccessoryManager获取上报的事件,调用AudioService.setWiredDeviceConnectionState传递信息给AudioService,更新设备信息。数字耳机例如USB Type-c耳机,接收数字信号(音频数据不需要解码成pcm,由耳机进行转换)Android中由UsbAl_usbalsadevice

Java知识体系最强总结(2021版)-程序员宅基地

文章浏览阅读2.8k次,点赞6次,收藏55次。学习Java请关注B站 【黑马程序员】Java知识体系主要包括基础知识,工具,并发编程,数据结构与算法,数据库,JVM,架构设计,应用框架,中间件,微服务架构,分布式架构,程序员的一些思考,团队与项目管理,运维,权限,推荐书籍,云计算,区块链等,包含了作为一个Java工程师在开发工作学习中需要用到或者可能用到的绝大部分知识。千里之行始于足下,希望大家根据自己的薄弱点,查缺补漏,根据自己感兴趣的方面多学习,学的精通一点,从现在开始行动起来。路漫漫其修远兮,吾将上下而求索,不管编程开发的路有多么难走,多么艰辛_java知识体系

CEPH -S集群报错汇总_ceph集群health_warn-程序员宅基地

文章浏览阅读2.2k次。问题一:ceph -shealth HEALTH_WARN too many PGs per OSD (320 > max 300)查询当前每个osd下最大的pg报警值:[root@k8s-master01 ~]# ceph --show-config | grep mon_pg_warn_max_per_osdmon_pg_warn_max_pe..._ceph集群health_warn

随便推点

深度学习硬件指南(号称最全)_深度学习 硬件选择-程序员宅基地

文章浏览阅读1.7k次。from 机器之心 : http://www.almosthuman.cn/2016/02/04/bqrzz/深度学习计算密集,所以你需要一个快速多核CPU,对吧?还是说买一个快速CPU可能是种浪费?搭建一个深度学习系统时,最糟糕的事情之一就是把钱浪费在并非必需的硬件上。本文中,我将一步步带你了解一个高性能经济系统所需的硬件。研究并行化深度学习过程中,我搭建了一个GPU集群,为此_深度学习 硬件选择

斐波那契数列前20项_短线交易的秘诀——斐波那契数列,数学界的“完美”公式!...-程序员宅基地

文章浏览阅读940次。斐波拉契数列一直被认为是大自然中的神奇异数。它的相邻两项之商趋近黄金分割0.618,与之相关的0.191、0.382和0.500等数字,构成了股市中市场时间和空间计算的重要节点。金融市场的时间和价格服从斐波拉契数列,有时准确率达到十分惊人的程度。斐波拉契数列在股市中的应用:“炒股者都懂数学”,这是华尔街操盘手的一句名言。在许多人眼里,周期是一种玄乎的东西,特别是股市中的一些“神棍”例如李大霄的拙劣...

服务器网站被cc攻击,网站被CC攻击怎么办?宝塔防火墙防CC设置详解-程序员宅基地

文章浏览阅读2k次。网站被cc攻击怎么办?如果是安装了BT宝塔面板的话,可以利用其防火墙进行防CC攻击设置,至少能有效抵挡一波。接下来小编就分享一下BT宝塔防火墙防CC设置详解图文教程。之前也介绍了BT宝塔面板的安全设置等文章,如下:一、防御CC的简介首先要在BT宝塔后台安装Nginx防火墙,企业插件里的Nginx防火墙,进行安装还没安装BT宝塔面板?宝塔服务器面板,一键全能部署及管理,送你3188元礼包,然后进行防..._cc防御设置值

matlab 拉普拉斯锐化函数_DIP第三章图像增强高斯拉普拉斯算子零交叉点-程序员宅基地

文章浏览阅读602次。Welcome​zqsiat.github.io写在前面的老师在布置这道作业题的时候说“这次作业非常简单,比上次第二章的作业简单,不会花太长时间就可以完成。”当时我还真信了,但是,并不简单。吐槽一下,我们老师讲课对我们学生的水平太过自信,有些细节的东西不讲,其中滋味请大家自行脑补。作业内容鉴于LoG算法在历史中的地位,进行较深入的实验研究探讨不同σ对LoG 算法的影响。图像Chapter3_1.p..._matlab有关于图像增强laplaca算子的函数

Linux MTD子系统(二)——mtdblock驱动分析-程序员宅基地

文章浏览阅读3k次,点赞3次,收藏14次。mtdX 和 mtdblockX实际上是同一个设备,mtdX是字符设备,mtdblockX是块设备mtdblockX存在的目的主要是为了挂载存在Flash里面的文件系统(例如yaffs2,jffs2)_mtdblock

NB-IoT使用CoAP协议接入华为IoT平台(NB-IoT项目实战专栏—8)_nbiotcoap-程序员宅基地

文章浏览阅读2.7k次,点赞2次,收藏26次。版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 ..._nbiotcoap