环境搭建

一、创建测试表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*创建数据库*/

/* 创建表 */
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)
);

/* 往表里面添加数据 */
INSERT INTO employee (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@lf.com'),
(2, 'Jack', 20, 'test2@lf.com'),
(3, 'Tom', 28, 'test3@lf.com'),
(4, 'Sandy', 21, 'test4@lf.com'),
(5, 'Billie', 24, 'test5@lf.com');

二、创建javaBean

1
2
3
4
5
6
7
8
9
public class Employee {
private Integer id;
private String lastName;
private String email;
private Integer gender;//使用0和1来表示性别
private Integer age;

//......对应的get和set方法
}

三、添加依赖配置

==如下配置不是MyBatis-Plus的配置,是MyBatis的配置,整合了Spring==

添加Maven依赖

在 pom.xml 中加入对 MP、Spring、连接池、Junit、Mysql 驱动等依赖

==特别说明: Mybatis 及 Mybatis-Spring 依赖请勿加入项目配置,以免引起版本冲突!!! Mybatis-Plus 会自动帮你维护!==

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.4.2</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.4</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.5</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.3.5</version>
</dependency>

</dependencies>

添加MyBatis的核心配置文件

==文件名字默认为:mybatis-config.xml,该配置文件到时候可以省略,可以将该配置文件的信息配置到Spring中==

1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>

添加Log4j.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>

添加jdbc.properties

1
2
3
4
5
jdbc.driver=com.mysql.cj.jdbc.Driver
#如果是MySQL8.0需要加上时区
jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
jdbc.username=root
jdbc.password=root

Spring的配置文件

==文件名字默认为:applicationContext.xml==

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?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" xmlns:tx="http://www.springframework.org/schema/tx"
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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<!--1、关联数据库文件,将连接数据库的信息导入进来=================================================================-->
<context:property-placeholder location="classpath:jdbc.properties"/>

<!--将druid注册到Spring中,配置数据源=================================================================-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>

<!--声明事务配置=================================================================-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<!--aop事务支持================================================================= -->
<tx:annotation-driven transaction-manager="transactionManager"/>

<!--配置SqlSessionFactoryBean,MyBatis-Plus的配置只是将配置SqlSessionFactoryBean改为了MybatisSqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.SqlSessionFactoryBean">
<!--绑定数据源-->
<property name="dataSource" ref="dataSource"/>
<!--绑定MyBatis的配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--别名处理-->
<property name="typeAliasesPackage" value="com.hngy.lf.pojo"/>
</bean>

<!-- 4.配置扫描Dao接口包,动态实现Dao接口注入到spring容器中,配置MyBatis扫描Mapper接口的路径 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 给出需要扫描Dao接口包,如果不扫描包,在Spring中是扫描不到接口的 -->
<property name="basePackage" value="com.hngy.lf.dao"/>
</bean>

</beans>

四、创建测试类,测试是否配置成功

1
2
3
4
5
6
7
8
9
10
public class TestMP {
private static final ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

@Test
public void testDataSource() throws SQLException {
DataSource dataSource = context.getBean("dataSource", DataSource.class);
//连接成功会输出地址
System.out.println(dataSource.getConnection());
}
}

五、集成MP

==Mybatis-Plus 的集成非常简单,在applicationContext.xml文件中,只需要把 Mybatis 自带的 SqlSessionFactoryBean 替换为MybatisSqlSessionFactoryBean==

1
2
3
4
5
6
7
8
9
<!--MyBatis-Plus的配置只是将配置SqlSessionFactoryBean改为了MybatisSqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.SqlSessionFactoryBean">
<!--绑定数据源-->
<property name="dataSource" ref="dataSource"/>
<!--绑定MyBatis的配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--别名处理-->
<property name="typeAliasesPackage" value="com.hngy.lf.pojo"/>
</bean>

简单使用CRUD

一、通用 CRUD

BaseMapper : 泛型指定的就是当前Mapper接口所操作的实体类类型

  • 实现方式:
    • 基于 Mybatis
      • 需要编写 EmployeeMapper 接口,并手动编写 CRUD 方法
      • 提供 EmployeeMapper.xml 映射文件,并手动编写每个方法对应的 SQL 语句.
    • 基于 MP
      • 只需要创建 EmployeeMapper 接口, 并继承 BaseMapper 接口.这就是使用 MP
      • 需要完成的所有操作,甚至不需要创建 SQL 映射文件。

二、类名与表名不一致

局部配置解决

==在JavaBean中使用使用注解来解决==

1
2
3
4
//数据库的表名为tbl_employee,此时javaBean的名为Employee,
//所以此时需要使用局部配置,使用@TableName注解来绑定表名
@TableName(value = "tbl_employee")
public class Employee { }

全局配置解决

==在ApplicationComtext.xml配置文件中配置==

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--配置mp的全局策略 配置了这个就可以省略类上的@TableName()注解和主键上的@TableId()注解-->
<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="tbl_"/>
<!--配置全局主键自增-->
<property name="idType" value="AUTO"/>
</bean>
</property>
</bean>

<!-- 配置了全局策略还需要将全局策略添加到SqlSessionFactory中 -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<!-- 将全局策略配置添加到selSessionFactoryBean中 -->
<property name="globalConfig" ref="globalConfig"/>
</bean>

三、字段名和属性名不一致

主键字段

局部配置:@TableId(value = “字段名”, type = IdType.AUTO)

==在JavaBean的属性名上加上@TableId注解 , 使用@TableId注解之后,如果字段名字和属性名字一致,系统则不会给字段起别名,如果字段名字和属性名字不一致,系统则会给字段起别名,属性的名字为字段的别名==

1
2
3
4
5
6
7
8
9
10
11
12
public class Employee {
//javaBean中建议使用包装类,不建议使用基本类型,包装类的默认值为null

/*
@TableId:
value:指定表中的主键列的列名,如果实体属性名与列名一致,可以省略不指定,
type:只当主键策略,这里指定为自增长
*/
//@TableId(value = "id", type = IdType.AUTO)
@TableField("id")
private Integer empId;
}

全局配置

==当属性名字和字段名字一致的时候可以使用全局配置来让主键字段自增长,如果不开启自增长,系统会随机赋值,这时候会报错==

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!--配置mp的全局策略 配置了这个就可以省略类上的@TableName()注解和主键上的@TableId()注解-->
<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="tbl_"/>
<!--配置全局主键自增,全局配置主键自增长仅仅满足表中的字段名字和属性名字一致的时候,
如果字段名字和属性名字不一致需要是哦也能够@TableId注解来配置-->
<property name="idType" value="AUTO"/>
</bean>
</property>
</bean>

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="globalConfig" ref="globalConfig"/>
</bean>

非主键字段

不满足驼峰命名法

==使用@TableField注解==

1
2
3
4
5
6
7
8
9
public class Employee {
//当字段为注解且字段名字和属性名字不一致的时候
@TableId(value = "id", type = IdType.AUTO)
private String lastName;

//当字段名不为主键且属性名字和字段名字不一致的时候
@TableField(value = "email")
private String emailN;
}

满足驼峰命名法

==在MyBatis-Plus的新版本中,驼峰命名法是默认开启的,所以可以不需要配置==

1
2
3
4
5
6
7
<!--这个等于Mybatis的全局配置文件,如果在MybatisSqlSessionFactoryBean里面已经配置了configLocation属性(外部加载Mybatis全局配置文件),就不能再配置configuration属性-->
<bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration">
<!--开启驼峰命名-->
<property name="mapUnderscoreToCamelCase" value="true"/>
<!--日志打印SQL语句 开启mybatis 的日志,需要配合Log4j使用-->
<property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
</bean>

四、插入操作

1
2
//插入一条记录,insert方法在插入时, 会根据实体类的每个属性进行非空判断,只有非空的属性对应的字段才会出现到SQL语句中
int insert(T entity);
  • 使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class TestMP {
    private static final ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    private static final EmployeeMapper employeeMapper = context.getBean("employeeMapper", EmployeeMapper.class);

    /**
    * 通用插入操作
    *
    * 需要设置主键策略,将主键设置为自增长
    */
    @Test
    public void testMPInsert() {
    Employee employee = new Employee();

    employee.setLastName("张三");
    employee.setEmailN("1903078434@qq.com");
    employee.setGender(1);
    employee.setAge(22);

    //插入的表的名字,默认为传入的实体类的名字
    int result = employeeMapper.insert(employee);
    System.out.println("修改的条数 = " + result);
    }
    }

五、删除操作

1
2
3
4
5
6
7
8
9
10
11
// 根据 ID 删除
int deleteById(Serializable id);

//* 根据条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

//根据 entity(条件构造器) 条件,删除记录,具体使用在后面的条件构造器中去看
int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

//删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
  1. int deleteById(Serializable id);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class TestMP {
    private static final ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    private static final EmployeeMapper employeeMapper = context.getBean("employeeMapper", EmployeeMapper.class);

    @Test
    public void testCommonDelete() {
    //(根据id删除):int deleteById(Serializable id);
    //执行的SQL:DELETE FROM tbl_employee WHERE id=?
    employeeMapper.deleteById(12);
    }
    }
  1. int deleteByMap(@Param(Constants.COLUMN_MAP) Map columnMap);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class TestMP {
    private static final ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    private static final EmployeeMapper employeeMapper = context.getBean("employeeMapper", EmployeeMapper.class);

    @Test
    public void testCommonDelete() {
    //(根据条件进行删除):int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
    //Map集合中的格式 (key:表中的字段名)(value:值)
    //执行的SQL:DELETE FROM tbl_employee WHERE last_name = ? AND email = ?
    Map<String, Object> columnMap = new HashMap<>();
    columnMap.put("last_name", "张三");
    columnMap.put("email", "1903078434@qq.com");
    int result = employeeMapper.deleteByMap(columnMap);
    System.out.println("result = " + result);
    }
    }
  1. int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class TestMP {
    private static final ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    private static final EmployeeMapper employeeMapper = context.getBean("employeeMapper", EmployeeMapper.class);

    @Test
    public void testCommonDelete() {
    //int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
    //执行的SQL:DELETE FROM tbl_employee WHERE id IN ( ? , ? )
    List<Integer> idList = new ArrayList<>();
    idList.add(13);
    idList.add(14);
    int result = employeeMapper.deleteBatchIds(idList);
    System.out.println("result = " + result);
    }
    }

六、修改操作

1
2
3
4
5
6
//根据 ID 修改:修改之前会判断传入的值是否为null,当值不为null的之后,才会将该字段加入需要修改的部分,如果传入需要修改的值为null,则不会修改该字段
int updateById(@Param(Constants.ENTITY) T entity);

//根据 whereEntity 条件,更新记录
//如果第二个参数传入的值为null,则会匹配所有的值,将所有的值都修改,第二个参数为条件构造器,具体使用在后面的条件构造器中去看
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
  1. int updateById(@Param(Constants.ENTITY) T entity);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Test
    public void testCommonUpdate() {
    //int updateById(@Param(Constants.ENTITY) T entity);
    //执行的SQL为:UPDATE tbl_employee SET last_name=?, email=?, gender=?, age=? WHERE id=?
    Employee employee = new Employee();

    employee.setLastName("马尔扎哈");
    employee.setEmailN("19030@qq.com");
    employee.setGender(0);
    employee.setAge(18);
    employee.setEmpId(15);

    int result = employeeMapper.updateById(employee);
    System.out.println("修改的条数 = " + result);
    }
  1. int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper updateWrapper);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Test
    public void testCommonUpdate() {
    //int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper)
    //执行的SQL为:UPDATE tbl_employee SET last_name=?, email=?, gender=?, age=?
    Employee employee = new Employee();

    employee.setLastName("马尔扎哈");
    employee.setEmailN("19030@qq.com");
    employee.setGender(0);
    employee.setAge(18);
    employee.setEmpId(15);

    int result = employeeMapper.updateById(employee);
    System.out.println("修改的条数 = " + result);
    }

七、查询操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//根据 ID 查询 
T selectById(Serializable id);

//查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

//查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

//根据 entity 条件,查询全部记录(并翻页),具体使用在后面的条件构造器中去看,这里使用该方法会将第二个参数设置为null
<E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

//根据 Wrapper 条件,查询全部记录(并翻页)
<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

//==================================================================================================================

//根据 entity 条件,查询一条记录 ,具体使用在后面的条件构造器中去看
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

//根据 Wrapper 条件,查询总记录数 ,具体使用在后面的条件构造器中去看
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

//根据 entity 条件,查询全部记录 ,具体使用在后面的条件构造器中去看
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

//根据 Wrapper 条件,查询全部记录 ,具体使用在后面的条件构造器中去看
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

//根据 Wrapper 条件,查询全部记录 ,具体使用在后面的条件构造器中去看
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
  1. (根据 ID 查询 ):T selectById(Serializable id);

    1
    2
    3
    4
    5
    6
    @Test
    public void testCommonSelect() {
    //(根据 ID 查询 ):T selectById(Serializable id);
    //执行的SQL:SELECT id AS empId,last_name,email AS emailN,gender,age FROM tbl_employee WHERE id=?
    employeeMapper.selectById(1);
    }
  1. 查询(根据ID 批量查询)List selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Test
    public void testCommonSelect() {
    //查询(根据ID 批量查询)
    //List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
    //执行的SQL:SELECT id AS empId,last_name,email AS emailN,gender,age FROM tbl_employee WHERE id IN ( ? , ? )
    List<Integer> idList = new ArrayList<>();
    idList.add(1);
    idList.add(2);
    employeeMapper.selectBatchIds(idList);
    }
  1. 查询(根据 columnMap 条件):List selectByMap(@Param(Constants.COLUMN_MAP) Map columnMap);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Test
    public void testCommonSelect() {
    //查询(根据 columnMap 条件)
    //List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
    //执行的SQL:SELECT id AS empId,last_name,email AS emailN FROM tbl_employee WHERE last_name = ? AND email = ?
    Map<String, Object> columnMap = new HashMap<>();
    columnMap.put("last_name", "张三");
    columnMap.put("email", "1903078434@qq.com");
    employeeMapper.selectByMap(columnMap);
    }

mybatis-plus注解

常用注解:@TableName、@TableId、@TableField、@Version(配合乐观锁使用)、@TableLogic

条件构造器QueryWrapper

==还有其他的条件构造器,具体有哪些和使用方法上网去查找==

一、条件构造器中的方法

==具体使用可以去官网查询==

条件构造器

二、删除操作

1
2
//根据 entity(条件构造器) 条件,删除记录,具体使用在后面的条件构造器中去看
int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper)
  • int delete(@Param(Constants.WRAPPER) Wrapper queryWrapper)

    1
    2
    3
    4
    5
    @Test
    public void testCommonDelete() {
    //执行的SQL:DELETE FROM tbl_employee WHERE (last_name = ? AND age BETWEEN ? AND ?)
    employeeMapper.delete(new QueryWrapper<Employee>().eq("last_name","张三").between("age",17,20));
    }

三、修改操作

1
2
3
//根据 whereEntity 条件,更新记录
//如果第二个参数传入的值为null,则会匹配所有的值,将所有的值都修改
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
  • (根据条件修改数据库的信息:)int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper updateWrapper);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Test
    public void updateWrapperTest() {
    Employee employee = new Employee();
    employee.setLastName("王五");
    employee.setEmailN("2297");

    //执行的SQL:UPDATE tbl_employee SET last_name=?, email=? WHERE (last_name LIKE ? AND age BETWEEN ? AND ?)
    employeeMapper.update(employee,new QueryWrapper<Employee>().like("last_name","马尔").between("age",18,20));
    }

四、查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//根据 entity 条件,查询一条记录 ,具体使用在后面的条件构造器中去看
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

//根据 Wrapper 条件,查询总记录数 ,具体使用在后面的条件构造器中去看
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

//根据 entity 条件,查询全部记录 ,具体使用在后面的条件构造器中去看
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

//根据 Wrapper 条件,查询全部记录 ,具体使用在后面的条件构造器中去看
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

//根据 Wrapper 条件,查询全部记录 ,具体使用在后面的条件构造器中去看
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
  • (根据条件查询一条数据:)T selectOne(@Param(Constants.WRAPPER) Wrapper queryWrapper);

    1
    2
    3
    4
    5
    @Test
    public void queryWrapperTest() {
    //执行的SQL:SELECT id AS empId,last_name FROM tbl_employee WHERE (last_name LIKE ?)
    employeeMapper.selectOne(new QueryWrapper<Employee>().like("last_name", "李四"));
    }
  • (根据条件查询总数:)Integer selectCount(@Param(Constants.WRAPPER) Wrapper queryWrapper);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Test
    public void queryWrapperTest() {

    //执行的SQL:SELECT COUNT( * ) FROM tbl_employee WHERE (last_name LIKE ? OR last_name = ? AND age = ?)
    System.out.println("count = " + employeeMapper.selectCount(
    new QueryWrapper<Employee>()
    .like("last_name", "马尔")
    .or()
    .eq("last_name", "马尔扎哈")
    .eq("age", "18")));
    }
  • (根据条件查询全部的数据返回一个集合:)List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper);

    1
    2
    3
    4
    5
    @Test
    public void queryWrapperTest() {
    //执行的SQL:SELECT id AS empId,last_name,email FROM tbl_employee WHERE (last_name LIKE ? AND age BETWEEN ? AND ?)
    employeeMapper.selectList(new QueryWrapper<Employee>().like("last_name", "马尔").between("age", 17, 20));
    }
  • (根据条件查询全部的数据返回一个类型为Map集合的List集合:)List> selectMaps(@Param(Constants.WRAPPER) Wrapper queryWrapper);

    1
    2
    3
    4
    5
    @Test
    public void queryWrapperTest() {
    //执行的SQL:SELECT id AS empId,last_name,email FROM tbl_employee WHERE (last_name = ?)
    employeeMapper.selectMaps(new QueryWrapper<Employee>().eq("last_name","马尔扎哈"));
    }
  • (根据条件查询全部数据返回一个存着每一列数据的第一个值的集合:)List selectObjs(@Param(Constants.WRAPPER) Wrapper queryWrapper);

    1
    2
    3
    4
    5
    @Test
    public void queryWrapperTest() {
    //执行的SQL:SELECT id AS empId,last_name,email AS emailN,gender,age FROM tbl_employee WHERE (last_name = ?)
    employeeMapper.selectObjs(new QueryWrapper<Employee>().eq("last_name","马尔扎哈")).forEach(System.out::println);
    }

    ActiveRecord(活动记录)

    Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的 一个表,而模型类的一个实例对应表中的一行记录。

    ActiveRecord 一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言, 对于 ActiveRecord 往往只能感叹其优雅,所以 MP 也在 AR 道路上进行了一定的探索

    ==MybatisPlus会默认使用实体类的类名到数据中找对应的表.==

    一、 如何使用 AR 模式

    写一个JavaBean来继承 com.baomidou.mybatisplus.extension.activerecord.Model; 这个类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package com.hngy.lf.pojo;
    import com.baomidou.mybatisplus.extension.activerecord.Model;

    public class Employee extends Model<Employee> {
    private Integer id;
    private String lastName;
    private String email;
    private Integer gender;//使用0和1来表示性别
    private Integer age;
    // .........
    }

    二、AR 基本 CRUD

    1、查询操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    //查询所有
    List<T> selectAll() ;

    //根据 ID 查询
    T selectById(Serializable id);

    //根据主键查询
    T selectById() ;

    //查询总记录数
    List<T> selectList(Wrapper<T> queryWrapper);

    //查询一条记录
    public T selectOne(Wrapper<T> queryWrapper);

    //查询总数
    Integer selectCount(Wrapper<T> queryWrapper);

    2、查询使用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    @Test
    public void testModelSelect() {
    Employee employee = new Employee();
    //查询所有:List<T> selectAll ();
    //执行的SQL:SELECT id,last_name,email,gender,age FROM tbl_employee
    employee.selectAll();

    //根据 ID 查询:T selectById (Serializable id);
    //执行的SQL:SELECT id,last_name,email,gender,age FROM tbl_employee WHERE id=?
    employee.selectById(1);

    //根据主键查询:T selectById ();
    //执行的SQL:
    employee.selectById();

    //查询总记录数:List<T> selectList (Wrapper < T > queryWrapper);
    //执行的SQL:SELECT id,last_name,email,gender,age FROM tbl_employee WHERE (last_name = ?)
    employee.selectList(new QueryWrapper<Employee>().eq("last_name","张三"));

    //查询一条记录:public T selectOne (Wrapper < T > queryWrapper);
    //执行的SQL:SELECT id,last_name,email,gender,age FROM tbl_employee WHERE (id = ?)
    employee.selectOne(new QueryWrapper<Employee>().eq("id",1));

    //查询总数:Integer selectCount (Wrapper < T > queryWrapper);
    //执行的SQL:SELECT COUNT( * ) FROM tbl_employee
    employee.selectCount(null);

    }

    3、插入操作

    1
    2
    3
    4
    5
    //插入(字段选择插入)
    boolean insert();

    //插入 OR 更新
    boolean insertOrUpdate();

    4、插入使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Test
    public void testModelInsert() {
    //插入(字段选择插入)
    //执行的SQL:INSERT INTO tbl_employee ( last_name, email, gender, age ) VALUES ( ?, ?, ?, ? )
    Employee employee = new Employee(null, "韩信", "19030894343@qq.com", 1, 19);
    employee.insert();

    //插入 OR 更新
    //当有该数据时执行的SQL:UPDATE tbl_employee SET last_name=?, email=?, gender=?, age=? WHERE id=?
    //没有该数据时执行的SQL:INSERT INTO tbl_employee ( last_name, email, gender, age ) VALUES ( ?, ?, ?, ? )
    Employee employee2 = new Employee(22, "李白", "2297@qq.com", 0, 20);
    employee2.insertOrUpdate();

    }

    5、修改操作

    1
    2
    3
    4
    5
    6
    7
    8
    //更新(字段选择更新) 
    boolean updateById();

    //执行 SQL 更新
    boolean update(Wrapper<T> updateWrapper);

    //插入 OR 更新
    boolean insertOrUpdate();

    6、修改使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @Test
    public void testModelUpdate() {

    //更新(字段选择更新)
    //执行的SQL:UPDATE tbl_employee SET last_name=?, email=?, gender=?, age=? WHERE id=?
    Employee employee = new Employee(19, "hanXing", "2297@qq.com", 0, 20);
    employee.updateById();

    //执行 SQL 更新
    //执行的SQL:UPDATE tbl_employee SET last_name=?, email=?, gender=?, age=? WHERE (last_name = ?)
    Employee employee2 = new Employee(null, "韩信", "1111@qq.com", 1, 11);
    employee2.update(new QueryWrapper<Employee>().eq("last_name","马尔扎哈"));

    //插入 OR 更新
    //当有该数据时执行的SQL:UPDATE tbl_employee SET last_name=?, email=?, gender=?, age=? WHERE id=?
    //没有该数据时执行的SQL:INSERT INTO tbl_employee ( last_name, email, gender, age ) VALUES ( ?, ?, ?, ? )
    Employee employee3 = new Employee(22, "李白", "2297@qq.com", 0, 20);
    employee3.insertOrUpdate();
    }

    7、删除操作

    1
    2
    3
    4
    5
    6
    7
    //根据 ID 删除 
    boolean deleteById(Serializable id);
    //根据主键删除
    boolean deleteById();

    //删除记录
    boolean delete(Wrapper<T> queryWrapper);

    8、删除使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    @Test
    public void testModelDel() {
    Employee employee = new Employee();
    //根据 ID 删除
    //执行的SQL:DELETE FROM tbl_employee WHERE id=?
    employee.setId(20);
    employee.deleteById();

    //根据主键删除
    //执行的SQL:DELETE FROM tbl_employee WHERE id=?
    employee.setId(19);
    employee.deleteById();

    //删除记录
    //执行的SQL:DELETE FROM tbl_employee WHERE (last_name = ? OR gender = ? AND last_name = ?)
    employee.delete(new QueryWrapper<Employee>()
    .eq("last_name", "李四")
    .or().eq("gender", 1)
    .eq("last_name", "hanXing"));
    }

    三、AR 小结

    • AR 模式提供了一种更加便捷的方式实现 CRUD 操作,其本质还是调用的 Mybatis 对 应的方法,类似于语法糖 语法糖是指计算机语言中添加的某种语法,这种语法对原本语言的功能并没有影响. 可以更方便开发者使用,可以避免出错的机会,让程序可读性更好.

    • 到此,简单领略了 Mybatis-Plus 的魅力与高效率,值得注意的一点是:MP提供 了强大的代码生成器,可以快速生成各类代码,真正的做到了即开即用

    代码生成器

    ==如下只是生成了一部分配置,如果还想生成其他的配置,可以去官网查询==

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    @Test
    public void codeGenerator () {
    //1. 全局配置
    GlobalConfig config = new GlobalConfig();

    String projectPath = System.getProperty("user.dir");

    config.setActiveRecord(true) // 是否支持AR模式
    .setAuthor("LF") // 作者
    .setOutputDir(projectPath + "/src/main/java") // 生成路径
    .setFileOverride(true) // 文件覆盖
    .setIdType(IdType.AUTO) // 主键策略
    .setBaseResultMap(true)
    .setServiceName("%sService")//如果不写成这样,Service类前面会有一个 I
    .setBaseColumnList(true);

    //2. 数据源配置
    DataSourceConfig dsConfig = new DataSourceConfig();
    dsConfig.setDbType(DbType.MYSQL) // 设置数据库类型
    .setDriverName("com.mysql.cj.jdbc.Driver")
    .setUrl("jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC")
    .setUsername("root")
    .setPassword("root");
    //3. 策略配置
    StrategyConfig stConfig = new StrategyConfig();
    stConfig.setCapitalMode(true) //全局大写命名
    .setNaming(NamingStrategy.underline_to_camel) // 数据库表映射到实体的命名策略
    .setTablePrefix("tbl_")//设置数据库表的前缀
    //此处填写数据库的表,可以填写多个,填写了之后会自动生成对应的表的JavaBean、service、controller、mapper文件
    .setInclude("tbl_employee","student"); // 生成的表

    //4. 包名策略配置
    PackageConfig pkConfig = new PackageConfig();
    pkConfig.setParent("com.hngy.lf")
    .setMapper("dao")
    .setService("service")
    .setController("controller")
    .setEntity("pojo")
    .setXml("dao");

    //5. 整合配置
    AutoGenerator ag = new AutoGenerator();

    ag.setGlobalConfig(config)
    .setDataSource(dsConfig)
    .setStrategy(stConfig)
    .setPackageInfo(pkConfig);

    //6. 执行
    ag.execute();
    }

    插件

    ==这里只展示分页插件、其他插件想要了解,可以去官网查询==

    一、分页插件

    ==除了这个分页插件,还可以使用PageHelper插件,需要导包==

    • Spring注册分页插件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
      <!-- 其他属性 略 -->
      <property name="configuration" ref="configuration"/>
      <property name="plugins">
      <array>
      <ref bean="mybatisPlusInterceptor"/>
      </array>
      </property>
      </bean>

      <!-- 该配置相当于mybatis的核心配置文件 -->
      <bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration">
      <!-- 需配置该值为false,避免1或2级缓存可能出现问题,该属性会在旧插件移除后一同移除 -->
      <property name="useDeprecatedExecutor" value="false"/>
      </bean>

      <bean id="mybatisPlusInterceptor" class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
      <property name="interceptors">
      <list>
      <ref bean="paginationInnerInterceptor"/>
      </list>
      </property>
      </bean>

      <bean id="paginationInnerInterceptor"
      class="com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor">
      <!-- 对于单一数据库类型来说,都建议配置该值,避免每次分页都去抓取数据库类型 -->
      <constructor-arg name="dbType" value="H2"/>
      </bean>
    • 在MyBatis的核心配置文件中注册

      1
      2
      3
      4
      5
      6
      <plugins>
      <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
      <property name="@page" value="com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor"/>
      <property name="page:dbType" value="h2"/>
      </plugin>
      </plugins>

    二、PageHelper分页

    • 导入

      1
      2
      3
      4
      5
      6
      <!-- pageHelper分页插件 -->
      <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.2.0</version>
      </dependency>
    • 使用:(一下列举了两种实现方式)

      • PageHelper.offsetPage(参数1,参数2 )==(参数一:从第几条数据开始查询,参数二:每页查询多少条数据)==

        • 接口

          1
          2
          @Select("select *from user")
          List<User> selectAll();
        - 测试
    
            
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Test
    public void test1() {
    //参数一:从第几条数据查询 ----- 参数二:每页显示的数量
    //执行的SQL:select *from user LIMIT ?, ?
    Page<User> page = PageHelper.offsetPage(2, 4);

    userMapper.selectAll();

    System.out.println(page);

    }
    - PageHelper.startPage(参数一, 参数二);==**(参数一:从第几页开始查询。参数二:每页显示多少条数据)**== > **这里只介绍了两种方法的使用,其他方法的使用可以去PageHelper官网查询使用**

    MP-Spring整合配置

    mybatis-plus-逻辑删除

    第一步:在配置文件中配置

    1
    2
    3
    4
    5
    6
    mybatis-plus:
    global-config:
    db-config:
    logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
    logic-delete-value: 1 # 逻辑已删除值(默认为 1)
    logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

    第二步:实体类用于判断是否删除的字段上加上@TableLogic注解

    1
    2
    @TableLogic
    private Integer deleted;
    MyBatisPlus
    https://www.naste.top:1024/posts/134766740.html
    作者
    XiaoFei🥝
    发布于
    2022-06-12
    更新于
    2024-04-26
    许可协议
    CC BY-NC-SA 4.0

    评论