MyBatisPlus的学习

这里是知识名字


这个知识重要吗?有什么用?


MyBatis-plus 简介

简介

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

支持数据库

任何能使用MyBatis进行 CRUD, 并且支持标准 SQL 的数据库,具体支持情况如下

框架结构

在这里插入图片描述

代码及文档地址

  • 官方地址:http://mp.baomidou.com
  • 代码发布地址:
    Github: https://github.com/baomidou/mybatis-plus
    Gitee: https://gitee.com/baomidou/mybatis-plus
  • 文档发布地址:https://baomidou.com/pages/24112f

使用MyBatis-Plus

1、开发环境

	IDE:idea 2019.2
	JDK:JDK8+
	构建工具:maven 3.5.4
	MySQL版本:MySQL 5.7
	Spring5.3.1
	MyBatis-Plus3.4.3.4

2、创建数据库及表

CREATE DATABASE `mybatis_plus` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
use `mybatis_plus`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL COMMENT '主键ID',
`name` varchar(30) DEFAULT NULL COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

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');

3、创建 Maven 工程

(1)打包方式:jar

(2)导入依赖

 <properties>
        <spring.version>5.3.1</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <!-- junit测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.27</version>
        </dependency>
        <!-- 日志 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- lombok用来简化实体类 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
        <!--MyBatis-Plus的核心依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.4.3.4</version>
        </dependency>
    </dependencies>

在这里插入图片描述

4、Spring 整合 MyBatis

(1)创建对应的实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

(2)在resources下创建 mybatis-comfig.xml

(3)创建 Mapper 接口以及对应的 映射文件。

(4)在resources下创建创建数据库连接配置文件 database.properties

(5)创建 Spring 配置文件,在resources下创建applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 引入jdbc.properties -->
    <context:property-placeholder location="classpath:database.properties" />
    
    
    <!-- 配置Druid数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    
    
    <!-- 配置用于创建SqlSessionFactory的工厂bean -->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 设置MyBatis配置文件的路径(可以不设置) -->
        <property name="configLocation" value="classpath:mybatis-config.xml">
        </property>
        <!-- 设置数据源 -->
        <property name="dataSource" ref="dataSource"></property>
        <!-- 设置类型别名所对应的包 -->
        <property name="typeAliasesPackage" value="com.wuqiyong.pojo">
        </property>
        <!--
        设置映射文件的路径
        若映射文件所在路径和mapper接口所在路径一致,则不需要设置
        -->
        <!--
        <property name="mapperLocations" value="classpath:mapper/*.xml">
        </property>
        -->
    </bean>
    

    <!--
    配置mapper接口的扫描配置
    由mybatis-spring提供,可以将指定包下所有的mapper接口创建动态代理
    并将这些动态代理作为IOC容器的bean管理
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.wuqiyong.mapper"></property>
    </bean>
    
</beans>

(6)添加日志功能,在resources下创建logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!--定义日志文件的存储地址 logs为当前项目的logs目录 还可以设置为../logs -->
    <property name="LOG_HOME" value="logs" />
    <!--控制台日志, 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符
            宽度,%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}
                - %msg%n</pattern>
        </encoder>
    </appender>
    <!--myibatis log configure-->
    <logger name="com.apache.ibatis" level="TRACE"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
    <!-- 日志输出级别 -->
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

此时 mybatis 的环境就搭建成功了

(7)进行测试

1.IOC容器进行测试

public class UserMapperTest {

    @Test
    public void getUserList() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper bean = context.getBean(UserMapper.class);
        for (User user : bean.getUserList()) {
            System.out.println(user);
        }
    }
}

2.使用注解方式加载配置文件进行测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserMapperTest {

    @Autowired
    private UserMapper mapper;

    @Test
    public void getUserList() {
        for (User user : mapper.getUserList()) {
            System.out.println(user);
        }
    }
}
  • @RunWith(SpringJUnit4ClassRunner.class) 在 Spring 的环境中进行测试
  • @ContextConfiguration("classpath:applicationContext.xml") 指定配置文件

5、使用 MyBatis-Plus

(1)修改 applicationContext.xml

<!-- 此处使用的是MybatisSqlSessionFactoryBean -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 引入jdbc.properties -->
    <context:property-placeholder location="classpath:database.properties" />
    
    
    <!-- 配置Druid数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    <!-- 此处使用的是MybatisSqlSessionFactoryBean -->
    <bean
            class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <!-- 设置MyBatis配置文件的路径(可以不设置) -->
        <property name="configLocation" value="classpath:mybatis-config.xml">
        </property>

        <!-- 设置数据源 -->
        <property name="dataSource" ref="dataSource"></property>
        <!-- 设置类型别名所对应的包 -->
        <property name="typeAliasesPackage" value="com.wuqiyong.pojo"></property>
        <!--
        设置映射文件的路径
        若映射文件所在路径和mapper接口所在路径一致,则不需要设置
        -->
        <!--
        <property name="mapperLocations" value="classpath:mapper/*.xml">
        </property>
        -->
    </bean>
</beans>
  • MybatisSqlSessionFactoryBean是在SqlSessionFactoryBean的基础上进行了增强。
  • 当映射文件的位置和 Mapper 接口的位置相同时,可以不设置映射文件的路径,当不同时,使用<property name="mapperLocations" value="classpath:mapper/*.xml"> </property>进行设置
    在这里插入图片描述
    这样我们认为是路径相同的。

(2)使用 MP 方式创建 Mapper 接口

public interface UserMapper extends BaseMapper<User> {
}

extends BaseMapper<User>BaseMapperMyBatis-Plus提供的基础mapper接口,泛型为所操作的实体类型,其中包含CRUD的各个方法,我们的mapper继承了BaseMapper之后,就可以直接使用BaseMapper所提供的各种方法,而不需要编写映射文件以及SQL语句,大大的提高了开发效率。

(3)进行测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserMapperTest {

    @Autowired
    UserMapper userMapper;

    @Test
    public void test() {
        System.out.println(userMapper.selectById(1));
    }
    
}

在Spring整合MyBatis中加入了MyBatis-Plus后,我们就可以使用MyBatis-Plus所提供的BaseMapper实现CRUD,并不需要编写映射文件以及SQL语句但是若要自定义SQL语句,仍然可以编写映射文件而不造成任何影响因为MyBatis-Plus只做增强,而不做修改。

(4)CRUD

增加
	@Test
    public void insert() {
        User user = new User(null, "阿宝", 11, "没有邮箱");
        userMapper.insert(user);
        
    }
  • 使用雪花算法 生成 ID。
  • 会自动将 ID 赋值给实体类。
    INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
删除
deleteById(通过ID删除一行)
	@Test
    public void deleteById() {
        // DELETE FROM user WHERE id=?
        userMapper.deleteById(1524547162032087041L);
    }
deleteByMap(通过条件删除一行)
	@Test
    public void deleteByMap() {
        // DELETE FROM user WHERE name = ? AND id = ?
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("id", 4);
        map.put("name", "Sandy");
        userMapper.deleteByMap(map);
    }
  • Key:字段名
  • Value:需要匹配的值
deleteBatchIds(通过ID批量删除)
	 @Test
    public void deleteBatchIds() {
        // Preparing: DELETE FROM user WHERE id IN ( ? , ? )
        List<? extends Number> list = Arrays.asList(1524547513900695554L, 5);

        userMapper.deleteBatchIds(list);
    }
  • 传入参数是 ID 的集合
修改
	@Test
    public void updateById() {
        // UPDATE user SET name=?, age=?, email=? WHERE id=?
       // UPDATE user SET name=? WHERE id=?
        User user = new User(3L, "Tomm", 28, "tom.com");

        userMapper.updateById(user);
    }
  • 当实体类属性为 null 时,不会对这一字段进行修改。
查询
	@Test
    public void select() {
        userMapper.selectById(1L);

        userMapper.selectBatchIds(Arrays.asList(1L, 2L));

        Map<String, Object> map = new HashMap<>();
        map.put("id", 1L);
        userMapper.selectByMap(map);

        userMapper.selectList(null);
    }
自定义方法

在这里插入图片描述

(5)通用 Service

mybatis-plus 还提供了通用的 Service

通用 Service CRUD 封装 IService 接口,进一步封装 CRUD

  • get 查询单行
  • remove 删除
  • list 查询集合
  • page 分页

泛型 T 为任意实体对象
建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService继承
Mybatis-Plus提供的基类。

public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T>
  • M 当前自己编写的 Mapper
  • T 当前操作的实体类对象

但是提供的方法在实际工作中是不够使用的,于是需要自定义 Service 去继承提供的 ServiceImpl
此时使用 User 进举例。

(1)创建 UserService 接口 继承 IService
public interface UserService extends IService<User> {
}
(2)创建 UserServiceImpl 继承 ServiceImpl 实现 UserService
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
(3)使用通用的 Service
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserServiceImplTest {

    @Autowired
    private UserService userService;

    @Test
    public void getCount() {
    // SELECT COUNT( * ) FROM user
        System.out.println(userService.count());
    }
    
	@Test
    public void testSaveBatch() {
        List<User> users = new ArrayList<>();

        for (int i = 0; i < 5; i++) {
            User user = new User();
            user.setName("阿宝" + i);
            user.setAge(20 + i);
            users.add(user);
        }

        userService.saveBatch(users);
    }
}
  • 批量添加使用一条语句不现实,于是 MP 将批量添加放在通用 Service 中。
  • userService.saveOrUpdate() 根据实体类 ID 判断是增加还是修改,有 ID 修改,没有 ID 新增

常用注解

使用MyBatis-Plus实现基本的CRUD时,没有指定要操作的表,只是在Mapper接口继承BaseMapper时,设置了泛型User,而操作的表为user表。

由此得出结论,MyBatis-Plus 操作的表由BaseMapper的泛型决定,即实体类型决定,即 默认操作的表名和实体类型的类名一致

当实体类名和表名不一致时,可以使用如下方法进行解决。

@TableName(解决实体类名和数据库表名不一致)

@TableName 是用来解决实体类名和表名不一致的情况,设置实体类对应的表名。
此时的表名为 t_user

@TableName("t_user")
public class User {}

GlobalConfig(解决实体类名和数据库表名不一致)

在 Srping 配置文件中添加以下配置文件
是将数据库表名前缀 t_ 去除,然后再进行映射。

<bean class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="configLocation" value="classpath:mybatis-config.xml">
        </property>
        <property name="dataSource" ref="dataSource"></property>
        <property name="typeAliasesPackage" value="自己的实体类包路径名"></property>
        <!-- 设置MyBatis-Plus的全局配置 -->
        <property name="globalConfig" ref="globalConfig"></property>
    </bean>
    <bean id="globalConfig"
          class="com.baomidou.mybatisplus.core.config.GlobalConfig">
        <property name="dbConfig">
            <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
                <!-- 设置实体类所对应的表的前缀 -->
                <property name="tablePrefix" value="t_"></property>
            </bean>
        </property>
    </bean>
  • MybatisSqlSessionFactoryBean 如果以及定义了这个 Bean 那么在当前 Bean 中添加 property name="globalConfig" ref="globalConfig"></property> 再定义 globalConfig 即可。

  • 因为定义了两个Bean class 都是MybatisSqlSessionFactoryBean 导致错误。

  • 要学会看错误信息。

@TableId

MyBatis-Plus在实现CRUD时,会默认将id作为主键列,并在插入数据时,默认基于雪花算法的策略生成 id。

当数据库表主键名不是 ID 时,可以使用 @TableId 将它标识为主键。

  • Value 若实体类中主键对应的属性为 id,而表中表示主键的字段为 uid,可以使用 @TableId(value = "uid") 标识,进行映射。
  • type type属性用来定义主键策略。
    • IdType.ASSIGN_ID (默认) 基于雪花算法生成 ID ,与数据库ID是否自增无关。
    • IdType.AUTO 使用数据库的自增策略,注意,该类型请确保数据库设置了id自增,否则无效。
配置全局
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
	<property name="dbConfig">
	<bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
		<!-- 设置实体类所对应的表的前缀 -->
		<property name="tablePrefix" value="t_"></property>
		<!-- 设置全局主键策略 -->
		<property name="idType" value="AUTO"></property>
	</bean>
	</property>
</bean>

雪花算法

背景

需要选择合适的方案去应对数据规模的增长,以应对逐渐增长的访问压力和数据量。

数据库的扩展方式主要包括:业务分库、主从复制,数据库分表。

数据库分表

将不同业务数据分散存储到不同的数据库服务器,能够支撑百万甚至千万用户规模的业务,但如果业务
继续发展,同一业务的单表数据也会达到单台数据库服务器的处理瓶颈。例如,淘宝的几亿用户数据,
如果全部存放在一台数据库服务器的一张表中,肯定是无法满足性能要求的,此时就需要对单表数据进
行拆分。

单表数据拆分有两种方式:垂直分表和水平分表。示意图如下:

在这里插入图片描述

垂直分表

垂直分表适合将表中某些不常用且占了大量空间的列拆分出去。

即将经常查询的属性使用一张表,查询时效率更快。

水平分表

水平分表适合表行数特别大的表,有的公司要求单表行数超过 5000 万就必须进行分表,这个数字可以
作为参考,但并不是绝对标准,关键还是要看表的访问性能。对于一些比较复杂的表,可能超过 1000
万就要分表了;而对于一些简单的表,即使存储数据超过 1 亿行,也可以不分表。

但不管怎样,当看到表的数据量达到千万级别时,作为架构师就要警觉起来,因为这很可能是架构的性
能瓶颈或者隐患。

水平分表相比垂直分表,会引入更多的复杂性,例如要求全局唯一的数据id该如何处理

  • 主键自增
    (1)以最常见的用户 ID 为例,可以按照 1000000 的范围大小进行分段,1 ~ 999999 放到表 1中,
    1000000 ~ 1999999 放到表2中,以此类推。

    (2)复杂点:分段大小的选取。分段太小会导致切分后子表数量过多,增加维护复杂度;分段太大可能会
    导致单表依然存在性能问题,一般建议分段大小在 100 万至 2000 万之间,具体需要根据业务选取合适
    的分段大小。

    (3)优点:可以随着数据的增加平滑地扩充新的表。例如,现在的用户是 100 万,如果增加到 1000 万,
    只需要增加新的表就可以了,原有的数据不需要动。

    (4)缺点:分布不均匀。假如按照 1000 万来进行分表,有可能某个分段实际存储的数据量只有 1 条,而另外一个分段实际存储的数据量有 1000 万条。

  • 取模
    (1)同样以用户 ID 为例,假如我们一开始就规划了 10 个数据库表,可以简单地用 user_id % 10 的值来
    表示数据所属的数据库表编号,ID 为 985 的用户放到编号为 5 的子表中,ID 为 10086 的用户放到编号
    为 6 的子表中。

    (2)复杂点:初始表数量的确定。表数量太多维护比较麻烦,表数量太少又可能导致单表性能存在问题。

    (3)优点:表分布比较均匀。

    (4)缺点:扩充新的表很麻烦,所有数据都要重分布。

雪花算法的思想

雪花算法是由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性。

(1)核心思想:
长度共64bit(一个long型)。

首先是一个符号位,1bit标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负
数是1,所以id一般是正数,最高位是0。

41bit时间截(毫秒级),存储的是时间截的差值(当前时间截 - 开始时间截),结果约等于69.73年。

10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID,可以部署在1024个节点)。

12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID)。

(2)优点:整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞,并且效率较高。

在这里插入图片描述

@TableField (解决属性名和字段名不同的问题)

MyBatis-Plus 中有默认配置将驼峰命名规则映射到数据库命名规则。

当实体类属性名和字段名不相同并且也不满足驼峰→下划线的规则。

就使用 @TableField 指定属性对应的字段名,从而解决属性名和字段名不能进行映射的情况。

@TableLogic (逻辑删除)

  • 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据

  • 逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为被删除状态,之后在数据库
    中仍旧能看到此条数据记录。

  • 使用场景:可以进行数据恢复。

  • 使用了 @TableLogic 那么查询会自动判断是否已经逻辑删除。

(1)实体类以及数据库中添加表示删除的属性/字段
(2)实体类属性上使用 @TableLogic 标识

此时就实现了逻辑删除,再次执行删除操作时就进行的是逻辑删除会将 is_deleted = 1,此时再进行查询时,是查询不到已经逻辑删除的数据的。


wapper介绍

在这里插入图片描述

Wrapper : 条件构造抽象类,最顶端父类

  • AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
  • QueryWrapper : 查询条件封装
    • UpdateWrapper : Update 条件封装
    • AbstractLambdaWrapper : 使用Lambda 语法
      • LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
      • LambdaUpdateWrapper : Lambda 更新封装Wrapper

使用QueryWrapper

QueryWrapper查询

QueryWrapper 添加查询条件
    @Test
    public void test1() {
//  查询用户名包含a,年龄在20到30之间,并且邮箱不为null的用户信息
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//      SELECT id,name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (name LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)
//       Parameters: %a%(String), 20(Integer), 30(Integer)
        queryWrapper.like("name", "a").between("age", 20, 30).isNotNull("email");

        for (User user : userMapper.selectList(queryWrapper)) {
            System.out.println(user);
        }
    }
  • column 是数据库中字段名。
  • like 会自动添加 %

QueryWrapper 只查询指定字段
	 @Test
    public void test1() {
        // 查询用户信息的 name 和 age 字段

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("name", "age");

        for (User user : userMapper.selectList(queryWrapper)) {
            System.out.println(user);
        }
    }

QueryWrapper 实现子查询
	@Test
    public void test1() {
        // 查询 ID 小于 10 的用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        queryWrapper.inSql("id", "select id from t_user where id <= 10");

        for (User user : userMapper.selectList(queryWrapper)) {
            System.out.println(user);
        }
    }

QueryWrapper 排序

	@Test
    public void test1() {
        // 按年龄降序查询用户,如果年龄相同则按id升序排列
        // select * from t_user order by age desc, id asc;
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("age").orderByAsc("id");

        for (User user : userMapper.selectList(queryWrapper)) {
            System.out.println(user);
        }
    }

QueryWrapper 删除

	@Test
    public void test1() {
        //删除email为空的用户
        // delete from t_user where (email is null);

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNull("email");

        userMapper.delete(queryWrapper);
    }

QueryWrapper 更新,以及运算优先级问题

	@Test
    public void test1() {
        // 用法1 : 修改内容    修改条件            
        // 用法2 : 修改内容(null)   修改条件
        // 两个条件之间默认使用 and

        //将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改
        // select * from t_user where (age > 20 and name like %a%) or (email is null)

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.gt("age", 20)
                .like("name", "a")
                .or()
                .isNull("email");
        User user = new User();
        user.setName("阿宝");

        userMapper.update(user, queryWrapper);
    }
@Test
    public void test1() {
        //将用户名中包含有a 并且(年龄大于20或邮箱为null)的用户信息修改
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        // lambda 表达式内的逻辑优先运算
        // 即先运算 gt("age", 19).or().isNull("email")
        queryWrapper.like("name", "a")
                .and(x -> x.gt("age", 19).or().isNull("email"));

        User user = new User();
        user.setName("阿宝阿宝");

        userMapper.update(user, queryWrapper);
    }

userUpdateWrapper

  • updateWrapper.set() 第一个参数:要修改的字段,第二个参数:修改的值。
  • 当设置了修改字段以后,就不用再传入实体类声明修改属性了,于是第一个参数为 null
	@Test
    public void test1() {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("name", "阿宝");
        updateWrapper.set("email", "阿宝没有邮箱");

        userMapper.update(null, updateWrapper);

    }

condition 用户传入参数进行组装

(1)声明数据属性
(2)判断数据属性是否正确
(3)拼接进入 Wapper

 	@Test
    public void test1() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        String name = "";
        Integer ageBegin = 20;
        Integer ageEnd = 30;

        if (StringUtils.isNotBlank(name)) {
            queryWrapper.like("name", name);
        }

        if (ageBegin != null) {
            queryWrapper.gt("age", ageBegin);
        }
        if (ageEnd != null) {
            queryWrapper.lt("age", ageEnd);
        }

        for (User user : userMapper.selectList(queryWrapper)) {
            System.out.println(user);
        }
    }

但是代码有些繁琐。
可以使用带condition参数的重载方法构建查询条件,简化代码的编写。
condition 是一个布尔类型。
在这里插入图片描述

	 @Test
    public void test1() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        String name = "";
        Integer ageBegin = 20;
        Integer ageEnd = 30;

        queryWrapper.like(StringUtils.isNotBlank(name), "name", name)
                .gt(ageBegin != null, "age", ageBegin)
                .lt(ageEnd != null, "age", ageEnd);

        for (User user : userMapper.selectList(queryWrapper)) {
            System.out.println(user);
        }
    }

插件

(1)添加配置

<!--配置插件-->
<property name="plugins">
            <array>
                <ref bean="mybatisPlusInterceptor"></ref>
            </array>
        </property>



<!--配置MyBatis-Plus插件-->
<bean id="mybatisPlusInterceptor"
          class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
        <property name="interceptors">
            <list>
                <ref bean="paginationInnerInterceptor"></ref>
            </list>
        </property>
    </bean>


<!--配置MyBatis-Plus分页插件的bean-->
<bean id="paginationInnerInterceptor"
      class="com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor">
    <!--设置数据库类型-->
        <property name="dbType" value="MYSQL"/>
    </bean>

剩下都是基于 Stringboot 学到了再回来学

指导复习的问题


错误

  • 定义 Bean 时,创建了两个 Bean 引用一个类的情况。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值