Mybatis-Plus: 持久层数据的高效处理(新手笔记二)-常用API的测试

🤚我的博客

  • 欢迎光临我的博客:https://blog.csdn.net/qq_52434217?type=blog

🥛前言

上一章快速入门使用了MybatisX生成java代码并初次体验了mapper组件,这一章原本打算介绍一下如何编写自定义sql语句。但为了更清楚的知道MybatisX生成的代码的含义,这一章首先介绍MybatisX生成的代码。

MybatisX生成代码文件的简单解读

🔷前置准备–日志输出

为了方便观察sql语句的执行,这里需要配置一下sql日志的输出

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

运行效果如下图
在这里插入图片描述

🔷mapper层相关代码

import com.vinta.my_test.entity.Test1;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
* @author VINTA
* @description 针对表【test1】的数据库操作Mapper
* @createDate 2024-02-18 21:17:23
* @Entity com.vinta.my_test.entity.Test1
*/
public interface Test1Mapper extends BaseMapper<Test1> {

}

MybatisX生成的代码是根据数据表表名而定的,如这里的Test1Mapper对应的数据表是test1Test1Mapper继承自BaseMapper<Test1>泛型接口。该泛型接口已经实现了简单的CRUD操作,只要继承自BaseMapper接口后,无需编写 mapper.xml 文件,即可获得CRUD功能。

mapper映射关系

这个xml文件位于resource/mapper目录下,它是数据表字段与实体类属性的对应关系。暂时只要知道这个xml是数据表与实体类的映射关系即可,后面在讲解自定义mysql语句时会详细解释。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vinta.my_test.mapper.Test1Mapper">

    <resultMap id="BaseResultMap" type="com.vinta.my_test.entity.Test1">
            <id property="id" column="id" jdbcType="INTEGER"/>
            <result property="username" column="username" jdbcType="VARCHAR"/>
            <result property="password" column="password" jdbcType="VARCHAR"/>
            <result property="name" column="name" jdbcType="VARCHAR"/>
            <result property="age" column="age" jdbcType="INTEGER"/>
            <result property="gender" column="gender" jdbcType="TINYINT"/>
            <result property="phone" column="phone" jdbcType="VARCHAR"/>
            <result property="email" column="email" jdbcType="VARCHAR"/>
            <result property="avatar" column="avatar" jdbcType="VARCHAR"/>
            <result property="department" column="department" jdbcType="VARCHAR"/>
            <result property="salary" column="salary" jdbcType="DOUBLE"/>
            <result property="address" column="address" jdbcType="VARCHAR"/>
            <result property="status" column="status" jdbcType="TINYINT"/>
    </resultMap>

    <sql id="Base_Column_List">
        id,username,password,
        name,age,gender,
        phone,email,avatar,
        department,salary,address,
        status
    </sql>
</mapper>

insert方法

/**
  * 插入一条记录
  * @param entity 实体对象
  */
int insert(T entity);

delete方法

  1. wrapper是条件参数,通过wrapper可以生成对应的sql语句,具体后面专门章节细讲。
  2. idSerializable类是因为mybatis底层通过反射实现,反射依赖于接口,而所有的Number类型都是实现了Serializable接口。
  3. columnMap传入的key为列名,value为条件,具体后面专门章节细讲。
// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);

// 删除(根据ID 批量删除,这里传入的是id list,非实体类list)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

// 根据 ID 删除
int deleteById(Serializable id);

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

Update方法

// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, 
            @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);

// 根据 ID 修改  主键属性必须值
int updateById(@Param(Constants.ENTITY) T entity);

Select方法

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

// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

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

// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

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

// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

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

// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

🔷service层相关代码

service接口

import com.vinta.my_test.entity.Test1;
import com.baomidou.mybatisplus.extension.service.IService;

/**
* @author VINTA
* @description 针对表【test1】的数据库操作Service
* @createDate 2024-02-18 21:17:23
*/
public interface Test1Service extends IService<Test1> {

}

Test1Service接口继承自IService泛型接口,在IService泛型接口中实现了一半的默认方法。实现了Test1Service可以直接调用部分CRUD。IService接口除了实现了默认方法,还添加了事务回滚。因此,在后面自定义service方法时也需要添加事务回滚。

serviceImpl实现类

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vinta.my_test.entity.Test1;
import com.vinta.my_test.service.Test1Service;
import com.vinta.my_test.mapper.Test1Mapper;
import org.springframework.stereotype.Service;

/**
* @author VINTA
* @description 针对表【test1】的数据库操作Service实现
* @createDate 2024-02-18 21:17:23
*/
@Service
public class Test1ServiceImpl extends ServiceImpl<Test1Mapper, Test1>
implements Test1Service{

}

Test1ServiceImpl实现类继承自ServiceImpl泛型类,该泛型类实现了Test1Service接口的另一半的方法。

save插入接口

保存:
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);

saveOrUpdate接口

修改或者保存:
// TableId 注解存在更新记录,不存在则插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);

remove删除接口

移除:
// 根据 queryWrapper 设置的条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);

update更新接口

更新:
// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);

查询数量

数量: 
// 查询总记录数
int count();
// 根据 Wrapper 条件,查询总记录数
int count(Wrapper<T> queryWrapper);

get查询接口

查询:
// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

查询集合

集合:
// 查询所有
List<T> list();
// 查询列表
List<T> list(Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有列表
List<Map<String, Object>> listMaps();
// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询全部记录
List<Object> listObjs();
// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

🔷常用简单接口的测试

这里的简单接口不包含需要使用wrapper参数和page参数的接口。不论是在service层中还是在mapper层中,操作都是一样的,所以这里只做mapper层的测试。

在测试类中注入组件

import com.vinta.my_test.entity.Test1;
import com.vinta.my_test.mapper.Test1Mapper;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.*;

@SpringBootTest
class MyTestApplicationTests {

    @Resource
    private Test1Mapper test1Mapper;
}

根据实体操作

    @Test
    void insertTest() {
        Test1 test1 = new Test1();
        test1.setUsername("xiaoye111");
        test1.setPassword("123456");
        test1.setName("xiaoye");
        test1.setAge(18);
        test1.setGender(1);
        test1.setPhone("12345678901");
        test1.setEmail("123@qq.com");
        test1.setDepartment("IT");
        test1.setSalary(10000.0);
        test1.setStatus(1);
        test1.setAvatar("123.jpg");
        test1.setAddress("湖北省武汉市江夏区");
        System.out.println(test1Mapper.insert(test1));
    }
// 返回 1

该操作相当于sql语句

INSERT INTO test1 ( username , password , name , age , gender , phone , email , avatar , department , salary , address , status) VALUES("xiaoye111","123456","xiaoye",18,1,"12345678901","123@qq.com","IT",10000.0,1,"123.jpg","湖北省武汉市江夏区");

根据id操作

    @Test
    void selectTest() {
        Integer[] ids = {1, 2, 3, 4, 5, 6};
        List<Integer> list = Arrays.asList(ids);
        List<Test1> test1s = test1Mapper.selectBatchIds(list);
        test1s.forEach(System.out::println);
    }

/* Test1 [Hash = 667046708, id=1, username=zhangsan111, password=zhangsan111, name=张三, age=35, gender=1, phone=13512345678, email=13512345678@qq.com, avatar=, department=销售部, salary=15000.0, address=北京市海淀区中关村, status=1, serialVersionUID=1]
Test1 [Hash = -236926384, id=2, username=lisi111, password=lisi111, name=李四, age=28, gender=1, phone=15698765432, email=15698765432@qq.com, avatar=, department=市场营销部, salary=12000.0, address=上海市浦东新区张江, status=1, serialVersionUID=1]
Test1 [Hash = -1715870505, id=3, username=wangwu111, password=wangwu111, name=王五, age=42, gender=1, phone=13811112222, email=13811112222@qq.com, avatar=, department=研发部, salary=20000.0, address=广东省深圳市南山区科技园, status=1, serialVersionUID=1]
Test1 [Hash = 95296361, id=4, username=zhaoliu111, password=zhaoliu111, name=赵六, age=25, gender=0, phone=13933334444, email=13933334444@qq.com, avatar=, department=人力资源部, salary=10000.0, address=江苏省南京市玄武区, status=1, serialVersionUID=1]
Test1 [Hash = 1975952528, id=5, username=liuqi111, password=liuqi111, name=刘七, age=22, gender=0, phone=13655556666, email=13655556666@qq.com, avatar=, department=财务部, salary=18000.0, address=四川省成都市高新区, status=1, serialVersionUID=1]
Test1 [Hash = 1684758064, id=6, username=zhouba111, password=zhouba111, name=周八, age=33, gender=1, phone=15077778888, email=15077778888@qq.com, avatar=, department=操作部, salary=13500.0, address=天津市滨海新区, status=1, serialVersionUID=1]
*/

该操作相当于下面的sql

SELECT id,username,password,name,age,gender,phone,email,avatar,department,salary,address,status FROM test1 WHERE id IN ( 1 , 2 , 3 , 4 , 5 , 6 );

根据map查询

    @Test
    void testColumnMap(){
        Map<String,Object> map = new HashMap<>();
        map.put("name","xiaoye");
        System.out.println(test1Mapper.selectByMap(map));
    }
//[Test1 [Hash = 1585078543, id=8, username=xiaoye111, password=123456, name=xiaoye, age=18, gender=1, phone=12345678901, email=123@qq.com, avatar=123.jpg, department=IT, salary=10000.0, address=湖北省武汉市江夏区, status=1, serialVersionUID=1]]

该操作相当于下面的sql语句

SELECT id,username,password,name,age,gender,phone,email,avatar,department,salary,address,status FROM test1 WHERE name = "xiaoye";

END

至此,本章内容主要介绍了常用的API并进行了测试,下一章继续mapper层的介绍条件查询和分页查询以及service层的条件查询和lambda函数作为条件的查询语句。

公众号

欢迎关注小夜的公众号

  • 37
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值