mysql crud操作_三、基本CRUD操作

上一节我们完成了mybatis-plus的集成,也已经在mp01中添加相关的实体类的对应的数据库表,这一节我们来实现基于mybatis-plus的CRUD操作。

首先按照上一节的操作,新建一个mp02 的 Module,可以将mp01中的内容全部复制过来,同时进行一下修改:

修改 Employee实体类:

/**

* mybatis-plus默认会使用实体类的小写类名作为表名

*/

@Data

@ToString

//@TableName(value = "tbl_employee") // ==> 全局的表前缀策略配置

public class Employee {

/**

* @TableId:

* value: 指定表中的主键的列名,如果实体属性名与列名一致,可以省略不指定

* type:指定主键策略

* 设置主键自增

*/

// @TableId(value = "id", type = IdType.AUTO) // ==> 全局表主键生成策略

private Integer id;

@TableField(value = "last_name")

private String lastName;

private String email;

private Integer gender;

private Integer age;

// 当前字段是否在数据库中存在,如果不存在则忽略该字段插入到数据库中

@TableField(exist = false)

private Double salary;

}

修改applicationContext.xml文件,添加下面的内容:

完整的xml文件如下:

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"

xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"

xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring

http://mybatis.org/schema/mybatis-spring-1.2.xsd

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

class="com.alibaba.druid.pool.DruidDataSource">

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

transaction-manager="dataSourceTransactionManager"/>

class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

value="com.mp.mapper">

在 mp02\src\main\java\com\mp\mapper\EmployeeMapper.java 路径下新建 EmployeeMapper.java mapper文件,EmployeeMapper 类需要继承 BaseMapper,代码如下:

/**

* @description: mapper接口

* 实现方式:

* 基于 Mybatis

* 需要编写 EmployeeMapper 接口,并手动编写 CRUD 方法

* 提供 EmployeeMapper.xml 映射文件,并手动编写每个方法对应的 SQL 语句.

*

* 基于 MP

* 只需要创建 EmployeeMapper 接口, 并继承 BaseMapper 接口.这就是使用 MP

* 需要完成的所有操作,甚至不需要创建 SQL 映射文件。

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

*/

public interface EmployeeMapper extends BaseMapper {

// 使用 mybatis 插入数据时获取主键值

// Integer insertEmployee(Employee employee );

// SQL...

}

修改mp02的pom.xml文件:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

mybatis-plus-in-action

com.demo.mybatis-plus

1.0-SNAPSHOT

4.0.0

mp02

com.baomidou

mybatis-plus

${mybatis.plus.version}

junit

junit

${junit.version}

log4j

log4j

${log4j.version}

com.alibaba

druid

${druid.version}

mysql

mysql-connector-java

${mysql.version}

org.springframework

spring-context

${spring.version}

org.springframework

spring-orm

${spring.version}

org.projectlombok

lombok

${lombok.version}

provided

上面的准备工作做完了,下面我们可以来进行CRUD操作了:

1、insert操作

/**

* 通用 插入操作

*/

@Test

public void testCommonInsert() {

// 初始化employee 对象

Employee employee = new Employee();

employee.setLastName("MP");

employee.setEmail("mp@github.com");

employee.setGender(1);

employee.setAge(22);

employee.setSalary(2000.0);

// 插入到数据库 insert方法在插入时, 会根据实体类的每个属性进行非空判断,只有非空的属性对应的字段才会出现到SQL语句中

int ret = employeeMapper.insert(employee);

System.out.println("result:" + ret);

// 获取当前数据在数据库中的主键值

Integer key = employee.getId();

System.out.println("key:" + key);

}

2、update操作

/**

* 通用更新操作

*/

@Test

public void testCommonUpdate() {

// 初始化employee 对象

Employee employee = new Employee();

employee.setId(19);

employee.setLastName("MP");

employee.setEmail("mybatis-plus@github.com");

employee.setGender(0);

// employee.setAge(33); // 没有传的字段不会被更新

// 单个更新

Integer result = employeeMapper.updateById(employee);

System.out.println("result:" + result);

// 批量更新, 如果 Wrapper 为空,则全部更新

result = employeeMapper.update(employee, null);

System.out.println("result:" + result);

}

3、select操作

/**

* 通用查询操作

*/

@Test

public void testCommonSelect() {

// 1、通过id查询

Employee employee = employeeMapper.selectById(14);

System.out.println(employee);

// 2、通过多个列查询 id+lastName

Employee employee1 = new Employee();

employee1.setId(13);

employee1.setLastName("White");

Wrapper employeeWrapper = new QueryWrapper(employee1);

Employee selectOne = employeeMapper.selectOne(employeeWrapper);

System.out.println(selectOne);

// 3、通过多个id进行查询

List idList = new ArrayList();

idList.add(11);

idList.add(12);

idList.add(13);

idList.add(14);

List employeeList = employeeMapper.selectBatchIds(idList);

System.out.println("employeeList:" + employeeList);

// 4、通过 selectMaps 查询

Map columnMap = new HashMap();

columnMap.put("last_name", "White");

columnMap.put("gender", 0);

List selectByMap = employeeMapper.selectByMap(columnMap);

System.out.println("selectByMap:" + selectByMap);

// 5、分页查询 selectPage 使用分页查询需要在 applicationContext.xml 中添加 分页查询插件 配置

IPage employeeIPage = employeeMapper.selectPage(new Page<>(2, 1), null);

System.out.println("employeeIPage:" + employeeIPage.getRecords());

}

注意:

1、columnMap中使用的是数据库中的字段名,而不是实体类的字段名

2、分页查询操作需要在 applicationContext.xml 中添加分页插件,完整代码可以看前面的完整配置:

4、delet操作

/**

* 通用删除操作

*/

@Test

public void testCommonDelete() {

// 1、根据id删除

Integer result = employeeMapper.deleteById(15);

System.out.println("result:" + result);

// 2、根据 deleteByMap 条件删除

Map columnMap = new HashMap<>();

columnMap.put("last_name","MP");

columnMap.put("email","mybatis-plus@github.com");

Integer ret = employeeMapper.deleteByMap(columnMap);

System.out.println("ret:" + ret);

// 3、批量删除

List idList = new ArrayList();

idList.add(18);

idList.add(19);

Integer deleteResult = employeeMapper.deleteBatchIds(idList);

System.out.println("deleteResult:" + deleteResult);

}

注意:columnMap中使用的是数据库中的字段名,而不是实体类的字段名

5、完整测试代码

public class TestMp {

private ApplicationContext ioc = new

ClassPathXmlApplicationContext("applicationContext.xml");

private EmployeeMapper employeeMapper = ioc.getBean("employeeMapper", EmployeeMapper.class);

/**

* 通用删除操作

*/

@Test

public void testCommonDelete() {

// 1、根据id删除

Integer result = employeeMapper.deleteById(15);

System.out.println("result:" + result);

// 2、根据 deleteByMap 条件删除

Map columnMap = new HashMap<>();

columnMap.put("last_name","MP");

columnMap.put("email","mybatis-plus@github.com");

Integer ret = employeeMapper.deleteByMap(columnMap);

System.out.println("ret:" + ret);

// 3、批量删除

List idList = new ArrayList();

idList.add(18);

idList.add(19);

Integer deleteResult = employeeMapper.deleteBatchIds(idList);

System.out.println("deleteResult:" + deleteResult);

}

/**

* 通用查询操作

*/

@Test

public void testCommonSelect() {

// 1、通过id查询

Employee employee = employeeMapper.selectById(14);

System.out.println(employee);

// 2、通过多个列查询 id+lastName

Employee employee1 = new Employee();

employee1.setId(13);

employee1.setLastName("White");

Wrapper employeeWrapper = new QueryWrapper(employee1);

Employee selectOne = employeeMapper.selectOne(employeeWrapper);

System.out.println(selectOne);

// 3、通过多个id进行查询

List idList = new ArrayList();

idList.add(11);

idList.add(12);

idList.add(13);

idList.add(14);

List employeeList = employeeMapper.selectBatchIds(idList);

System.out.println("employeeList:" + employeeList);

// 4、通过 selectMaps 查询

Map columnMap = new HashMap();

columnMap.put("last_name", "White");

columnMap.put("gender", 0);

List selectByMap = employeeMapper.selectByMap(columnMap);

System.out.println("selectByMap:" + selectByMap);

// 5、分页查询 selectPage 使用分页查询需要在 applicationContext.xml 中添加 分页查询插件 配置

IPage employeeIPage = employeeMapper.selectPage(new Page<>(2, 1), null);

System.out.println("employeeIPage:" + employeeIPage.getRecords());

}

/**

* 通用更新操作

*/

@Test

public void testCommonUpdate() {

// 初始化employee 对象

Employee employee = new Employee();

employee.setId(19);

employee.setLastName("MP");

employee.setEmail("mybatis-plus@github.com");

employee.setGender(0);

// employee.setAge(33);

// 单个更新

Integer result = employeeMapper.updateById(employee);

System.out.println("result:" + result);

// 批量更新, 如果 Wrapper 为空,则全部更新

result = employeeMapper.update(employee, null);

System.out.println("result:" + result);

}

/**

* 通用 插入操作

*/

@Test

public void testCommonInsert() {

// 初始化employee 对象

Employee employee = new Employee();

employee.setLastName("MP");

employee.setEmail("mp@github.com");

employee.setGender(1);

employee.setAge(22);

employee.setSalary(2000.0);

// 插入到数据库 insert方法在插入时, 会根据实体类的每个属性进行非空判断,只有非空的属性对应的字段才会出现到SQL语句中

int ret = employeeMapper.insert(employee);

System.out.println("result:" + ret);

// 获取当前数据在数据库中的主键值

Integer key = employee.getId();

System.out.println("key:" + key);

}

@Test

public void testEnvironment() throws Exception {

DataSource ds = ioc.getBean("dataSource", DataSource.class);

Connection conn = ds.getConnection();

System.out.println(conn);

}

}

完成上面的操作后,mp02的代码结构如下所示:

5a1621006e92

mp02-01.png

6、Mybatis-Plus启动注入SQL原理分析

6.1、问题:

在我们使用 BaseMapper 提供的方法来进行CRUD操作的时候,有没有想过为什么我们能直接使用这些方法,而这些方法又是什么时候加载到容器中呢?

xxxMapper 继承了 BaseMapper, BaseMapper 中提供了通用的 CRUD 方法,这些方法来源于 BaseMapper, 有方法就必须有 SQL, 因为 MyBatis 最终还是需要通过SQL 语句操作数据。以为 Mybatis-Plus 是在MyBatis 的基础上做了增强,所以我们有必要了解一些前置知识:

MyBatis 源码中比较重要的一些对象, MyBatis 框架的执行流程 Configuration:MyBatis 的全局配置对象 MappedStatement:MappedStatement保存所有的SQL方法和执行语句 ……..

6.2、通过现象看到本质:

通过debug日志我们可以看到,在我们执行 employeeMapper.deleteById(id)方法之前,Mybatis-Plus已经帮我们把 BaseMapper 中内置的方法就加载到了MappedStatement中。

5a1621006e92

x01.png

我们在 employeeMapper.deleteById(id)方法中打下断点,可以看到

A. employeeMapper 的本质是com.baomidou.mybatisplus.core.override.MybatisMapperProxy,如果是mybatis 则看到的是 org.apache.ibatis.binding.MapperProxy

B. MapperProxy 中两个重要对象 sqlSession –>SqlSessionFactory

5a1621006e92

C. SqlSessionFacotry 中又有两个重要的对象 Configuration→ MappedStatements

5a1621006e92

x03.png

每一个 mappedStatement 都表示 Mapper 接口中的一个方法与 Mapper 映射文件中的一个 SQL。

5a1621006e92

x04.png

Mybatis-Plus 在启动就会挨个分析 xxxMapper 中的方法,并且将对应的 SQL 语句处理好,保存到 configuration 对象中的 mappedStatements 中. D. 本质: Configuration: MyBatis 或者 MP 全局配置对象

MappedStatement:一个 MappedStatement 对象对应 Mapper 配置文件中的一个select/update/insert/delete 节点,主要描述的是一条 SQL 语句 SqlMethod : 枚举对象 , MP 支持的 SQL 方法 TableInfo: 数据库表反射信息 ,可以获取到数据库表相关的信息 SqlSource: SQL 语句处理对象 MapperBuilderAssistant: 用于缓存、 SQL 参数、查询方剂结果集处理等,通过 MapperBuilderAssistant 将每一个 mappedStatement添加到 configuration 中的 mappedstatements 中 。

在下图所示的位置处打断点,可以观测到MP加载内置方法的整个过程,我们在后边自定义全局操作添加自定义方法的时候,还会碰到AbstractMethod对象和AbstractSqlInjector对象,

5a1621006e92

x05-MapperFactoryBean.png

5a1621006e92

x06-MybatisMapperRegistry.png

5a1621006e92

x07-MybatisMapperAnnotationBuilder.png

5a1621006e92

x08-AbstractSqlInjector.png

5a1621006e92

x09-AbstractMethod.png

5a1621006e92

x10-Insert.png

5a1621006e92

x11-AbstractMethod-addMappedStatement.png

5a1621006e92

x12-MapperBuilderAssistant-addMappedStatement.png

5a1621006e92

x13-MybatisConfiguration-addMappedStatement.png

Mybatis-Plus启动注入SQL的执行流程入下入所示(中间省略若干非关键步骤):

5a1621006e92

xx-01.png

5a1621006e92

xx-02.png

以上是基本的 CRUD 操作, 你所见,我们仅仅需要继承一个 BaseMapper 即可实现大部分单表 CRUD 操作。 BaseMapper 提供了多达 17 个方法给大家使用, 可以极其方便的实现单一、批量、分页等操作。 极大的减少开发负担。

综上,基于 mybatis-plus 的CRUD演示就完成了,现有一个需求,我们需要分页查询 tbl_employee 表中,年龄在 18~50 之间性别为男且姓名为 xx 的所有用户,这时候我们该如何实现上述需求呢?

MyBatis : 需要在 SQL 映射文件中编写带条件查询的 SQL,并基于 PageHelper 插件完成分页. 实现以上一个简单的需求,往往需要我们做很多重复单调的工作。 普通的 Mapper能够解决这类痛点吗? MP: 依旧不用编写 SQL 语句, MP 提供了功能强大的条件构造器 AbstractWrapper。下面我们就可以进入到下一节AbstractWrapper条件构造器了。

源代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值