Data Access 之 MyBatis Plus(一)- BaseMapper CRUD(Part B)

简介: Data Access 之 MyBatis Plus(一)- BaseMapper CRUD(Part B)

二、MyBatis Plus 的 CRUD

2.5 MP 的 update 相关方法

//根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
//根据 whereEntity 条件,更新记录
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
复制代码

在TeslaMapperTest中增加测试方法updateById

@Test
public void updateById(){
    Tesla updateTesla = new Tesla();
    updateTesla.setId(5);
    updateTesla.setVehicleName("Model 3P");
    int count = teslaMapper.updateById(updateTesla);
    System.out.println("更新的行数为:" + count);
}
复制代码

执行测试方法

image.png

id为5的数据成功修改,UPDATE语句中只出现了代码中设置了属性值的属性,修改属性时会进行非空判断,只修改非空的属性值。

2.6 MP 的 select 相关方法

基本查询

/**
 * 根据 ID 查询
 *
 * @param id 主键ID
 */
T selectById(Serializable id);
/**
 * 查询(根据ID 批量查询)
 *
 * @param idList 主键ID列表(不能为 null 以及 empty)
 */
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
/**
 * 查询(根据 columnMap 条件)
 *
 * @param columnMap 表字段 map 对象
 */
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
复制代码

在TeslaMapperTest中分别新增selectBatchIds、selectByMap 两个测试方法

@Test
public void selectBatchIds(){
    Collection<Integer> batchIds = new HashSet<>();
    // 构造查询的id的集合
    for (int i = 0; i < 5; i++) {
        batchIds.add(i);
    }
    List<Tesla> teslaList = teslaMapper.selectBatchIds(batchIds);
    // 遍历查询到的数据
    for (Tesla tesla : teslaList) {
        System.out.println("查询到的内容为:" + tesla);
    }
}
@Test
public void selectByMap(){
    Map<String, Object> conditionMap = new HashMap<>();
    // 构造查询条件,key为查询条件,value为查询条件的值
    conditionMap.put("factory","Fremont Gigafactory");
    conditionMap.put("name","Model S");
    List<Tesla> teslaList = teslaMapper.selectByMap(conditionMap);
    for (Tesla tesla : teslaList) {
        System.out.println("selectByMap方法查询到的数据:" + tesla);
    }
}
复制代码

image.png

再增加一个name条件

conditionMap.put("name","Model S");
复制代码

image.png

SQL语句中自动添加了AND关键字

Map条件查询所使用的Key是数据库中的字段名,不是实体类的属性名。

分页查询

/**
 * 根据 entity 条件,查询全部记录(并翻页)
 *
 * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
 * @param queryWrapper 实体对象封装操作类(可以为 null)
 */
<P extends IPage<T>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
 * 根据 Wrapper 条件,查询全部记录(并翻页)
 *
 * @param page         分页查询条件
 * @param queryWrapper 实体对象封装操作类
 */
<P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
复制代码

MyBatis Plus提供了两个分页查询的方法,两个方法中都有一个Wrapper <T> 参数,Warpper是MP中的条件构造器,在 Data Access 之 MyBatis Plus(二)-  Wrapper 条件构造器 会提到,这里先设置为null

selectPage方法入参中另外一个参数是一个IPage的实现类;可以使用IPage的实现类Page作为分页查询的页面配置

image.png

Page提供了几个构造函数以及一些获取当前页、判断是否有上一页或下一页以及总页数总记录数等方法

image.png

在TeslaMapperTest中增加分页测试方法

@Test
public void selectPage(){
    Page<Tesla> teslaPage = new Page<>(2,4);
    Page<Tesla> page = teslaMapper.selectPage(teslaPage, null);
    System.out.println("--------------------");
    System.out.println("查询当前页面的数据:" + page.getRecords());
    System.out.println("--------------------");
}
复制代码

执行测试

image.png

根据控制台输出的SQL语句可以看出并没有执行分页查询,这是因为缺少MyBatis Plus的分页插件导致的。

MyBatis Plus分页插件配置

在application.xml中新增分页插件配置

<!--配置分页插件-->
<bean id="paginationInnerInterceptor" class="com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor">
    <property name="dbType" value="MYSQL"></property>
</bean>
<!--配置拦截器-->
<bean id="mybatisPlusInterceptor" class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
    <property name="interceptors" ref="paginationInnerInterceptor"></property>
</bean>
复制代码

然后在MyBatis Plus的MybatisSqlSessionFactoryBean中添加配置的拦截器

<bean id="mybatisSqlSessionFactoryBean" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    <!--其他配置保持不变-->
    <!--设置使用分页插件,否则分页会失效-->
    <property name="plugins" ref="mybatisPlusInterceptor"></property>
</bean>
复制代码

再次执行selectPage测试方法

image.png

根据控制台的输出的SQL语句及数据可以确定,MyBatis Plus分页生效

selectMapsPage

在TeslaMapperTest测试类中增加测试方法selectMapsPage

@Test
public void selectMapsPage(){
    Page<Map<String,Object>> teslaPage = new Page<>(2,4);
    Page<Map<String, Object>> mapPage = teslaMapper.selectMapsPage(teslaPage, null);
    System.out.println("--------------------");
    System.out.println("查询当前页面的数据:" + mapPage.getRecords());
    System.out.println("--------------------");
}
复制代码

执行方法的测试

image.png

根据输出的结果可以确定,selectMapsPage方法返回的是Map类型的数据,而selectPage返回的是封装好的实体类对象。

2.7 MP 的 delete 相关方法

/**
 * 根据 ID 删除
 *
 * @param id 主键ID
 */
int deleteById(Serializable id);
/**
 * 根据实体(ID)删除
 *
 * @param entity 实体对象
 * @since 3.4.4
 */
int deleteById(T entity);
/**
 * 根据 columnMap 条件,删除记录
 *
 * @param columnMap 表字段 map 对象
 */
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
/**
 * 删除(根据ID或实体 批量删除)
 *
 * @param idList 主键ID列表或实体列表(不能为 null 以及 empty)
 */
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<?> idList);
复制代码

在TeslaMapperTest中新增四个测试方法

@Test
public void deleteByIdWithInteger(){
    int id = 1166057479;
    int count = teslaMapper.deleteById(id);
    System.out.println("根据ID删除,更新行数为:" + count);
}
@Test
public void deleteByIdWithEntity(){
    Tesla tesla = new Tesla();
    tesla.setId(1166057478);
    int count = teslaMapper.deleteById(tesla);
    System.out.println("根据Entity删除,更新行数为:" + count);
}
@Test
public void deleteByMap(){
    Map<String,Object> map = new HashMap<>();
    map.put("factory","Texas Cybertruck Gigafactory");
    int count = teslaMapper.deleteByMap(map);
    System.out.println("根据Map删除,更新行数为:" + count);
}
@Test
public void deleteByBachIds(){
    List<Integer> idList = new ArrayList<>();
    for (int i = 1166057474; i < 1166057478; i++) {
        idList.add(i);
    }
    Integer count = teslaMapper.deleteBatchIds(idList);
    System.out.println("根据idList删除,更新行数为:" + count);
}
复制代码

执行deleteByIdWithInteger方法

image.png

根据控制台的输出可以确定是根据传入的ID为条件执行删除操作

执行deleteByIdWithEntity方法

image.png

传入了设置id属性的实体类和直接传入id的效果是相同的

执行deleteByMap方法

image.png

Map中设置了SQL语句中WHERE子句后面的条件,可以根据设置的条件执行删除,这个条件的Key一定要是数据库中的字段

执行deleteByBachIds方法

image.png

成功删除idList中指定的数据

三、MyBatis Plus 启动注入 SQL 的原理

MyBatis的一大特性就是损耗小,启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作,我们可以在deleteByIdWithInteger方法的teslaMapper.deleteById(id)这一行打断点,启动Debug模式

image.png

TeslaMapper接口的本质是代理类MyBatisMapperProxy;查看MyBatisMapperProxy源码,代理类中也包含了一个sqlSession属性

image.png

TeslaMapper代理类中自然也包含了sqlSession

image.png

并且在mappedStatement中包含了方法与映射文件中的SQL,MyBatis启动就会将对应方法和SQL语句处理包,保存到configuration对象中的mappedStatements中。

MyBatis Plus中的关键对象:

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


相关文章
|
3月前
|
SQL Java Kotlin
MybatisPlus怎么拓展自定义BaseMapper
通过扩展Mybatis-Plus的`BaseMapper`,可以自定义SQL模板以满足特定业务需求。例如,当遇到唯一键冲突而不希望抛出异常时,可使用`INSERT IGNORE`语法。首先,创建`InsertIgnore`类继承`AbstractMethod`并定义`insertIgnore`方法及其SQL模板。接着,在自定义的`UltraBaseMapper`接口中声明`insertIgnore`方法,并让业务Mapper继承此接口。最后,通过`UltraSqlInjector`类将`InsertIgnore`方法注册到Mybatis-Plus插件中。
150 1
|
26天前
|
SQL Java 数据库连接
MyBatis-Plus:简化 CRUD 操作的艺术
MyBatis-Plus 是一个基于 MyBatis 的增强工具,它旨在简化 MyBatis 的使用,提高开发效率。
50 1
MyBatis-Plus:简化 CRUD 操作的艺术
|
1月前
|
SQL Java 数据库连接
Mybatis方式完成CRUD操作
Mybatis方式完成CRUD操作
39 0
|
4月前
|
Java 数据库连接 Spring
搭建 spring boot + mybatis plus 项目框架并进行调试
搭建 spring boot + mybatis plus 项目框架并进行调试
93 4
|
4月前
|
SQL Java 数据库连接
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
91 3
|
4月前
|
Java 数据库连接 数据库
mybatis plus 中增删改查及Wrapper的使用
mybatis plus 中增删改查及Wrapper的使用
216 3
|
4月前
|
算法 Java 数据库连接
mybatis plus 主键策略
mybatis plus 主键策略
56 2
|
1月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
112 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
1月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
54 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
1月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
314 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个