IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> MyBatisPlus3.x -> 正文阅读

[Java知识库]MyBatisPlus3.x

该笔记来自B站SGG-MyBatisPlus学习记录及MP官网,文章没多少干货,只是作一次学习记录

2022.10.18

架构示意

架构示意.png

依赖(基于SpringBoot+Mysql)

<dependencies>
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-test</artifactId>
    	<scope>test</scope>
    </dependency>
    <dependency>
    	<groupId>com.baomidou</groupId>
    	<artifactId>mybatis-plus-boot-starter</artifactId>
    	<version>3.5.1</version>
    </dependency>
    <dependency>
    	<groupId>org.projectlombok</groupId>
    	<artifactId>lombok</artifactId>
    	<optional>true</optional>
    </dependency>
    <dependency>
    	<groupId>mysql</groupId>
    	<artifactId>mysql-connector-java</artifactId>
    	<scope>runtime</scope>
    </dependency>
</dependencies>

数据源配置

spring:
	# 配置数据源信息
	datasource:
	# 配置数据源类型
	type: com.zaxxer.hikari.HikariDataSource
	# 配置连接数据库信息
	driver-class-name: com.mysql.cj.jdbc.Driver
	url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-
	8&useSSL=false
	username: root
	password: 123456
	
1. 关于driver-class-name驱动配置项(看SpringBoot版本)
	spring boot 2.0(内置jdbc5驱动),驱动类使用:
		driver-class-name: com.mysql.jdbc.Driver
	spring boot 2.1及以上(内置jdbc8驱动),驱动类使用:
		driver-class-name: com.mysql.cj.jdbc.Driver
		
2. 连接地址(看Mysql版本等数据库)
	MySQL5.7版本的url:
		jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
	MySQL8.0版本的url:
    	jdbc:mysql://localhost:3306/mybatis_plus?
serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false

启动类(或配置类)上配置mapper包扫描地址

@SpringBootApplication
@MapperScan("com.test.mybatisplus.mapper") // 包位置 有些将mapper放在dao下
public class MybatisplusApplication {
    public static void main(String[] args) {
    	SpringApplication.run(MybatisplusApplication.class, args);
    }
}

库表结构及数据

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

通用Mapper

通用Mapper就是在我们可以使用MyBatisPlus提供的封装好的一些单表的基本的CURD操作,直接在Mapper层(Dao层)与数据库进行交互

首先,我们需要在编写自己的Mapper(或Dao层)接口时,去继承【BaseMapper// UserMapper.java (或UserDao.java)
    public interface UserMapper extends BaseMapper<User> {
	} 
其中BaseMapper中的泛型指的是我们的实体类名(一般来说简单的表实体名和表名一致)

@Autowired
private UserMapper userMapper; // 依赖注入我们的UserMapper接口,若Idea报红可以在UserMapper接口上加上@Repository注解

1. Insert
    int insert(T entity) // 插入一个实体类为一条数据
    
    @Test
    public void testInsert(){
        User user = new User(null, "张三", 23, "zhangsan@atguigu.com");
        // INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
        int result = userMapper.insert(user);
        System.out.println("受影响行数:"+result);
    }

2. Delete
	// 根据 entity 条件,删除记录
    int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); // wrapper	实体对象封装操作类(可以为 null)

    // 删除(根据ID 批量删除)
    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // idList	主键 ID 列表(不能为 null 以及 empty)
	@Test
    public void testDeleteBatchIds(){
        //通过多个id批量删除
        //DELETE FROM user WHERE id IN ( ? , ? , ? )
        List<Long> idList = Arrays.asList(1L, 2L, 3L);
        int result = userMapper.deleteBatchIds(idList);
        System.out.println("受影响行数:"+result);
    }

    // 根据 ID 删除
    int deleteById(Serializable id); // id	主键 ID
	@Test
    public void testDeleteById(){
        //通过id删除用户信息
        //DELETE FROM user WHERE id=?
        int result = userMapper.deleteById(1475754982694199298L);
        System.out.println("受影响行数:"+result);
    }

    // 根据 columnMap 条件,删除记录
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); // columnMap	表字段 map 对象
	@Test
    public void testDeleteByMap(){
        //根据map集合中所设置的条件删除记录
        //DELETE FROM user WHERE name = ? AND age = ?
        Map<String, Object> map = new HashMap<>();
        map.put("age", 23);
        map.put("name", "张三");
        int result = userMapper.deleteByMap(map);
        System.out.println("受影响行数:"+result);
    }

3. Update
    // 根据 whereWrapper 条件,更新记录
	int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper); // updateWrapper	实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
	
	// 根据 ID 修改
	int updateById(@Param(Constants.ENTITY) T entity); // entity	实体对象 (set 条件值,可为 null)
	@Test
    public void testUpdateById(){
        User user = new User(4L, "admin", 22, null);
        //UPDATE user SET name=?, age=? WHERE id=?
        int result = userMapper.updateById(user);
        System.out.println("受影响行数:"+result);
    }

4. Select
    // 根据 ID 查询
    T selectById(Serializable id); // id	主键 ID
	@Test
    public void testSelectById(){
        //根据id查询用户信息
        //SELECT id,name,age,email FROM user WHERE id=?
        User user = userMapper.selectById(4L);
        System.out.println(user);
    }

    // 根据 entity 条件,查询一条记录
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // queryWrapper	实体对象封装操作类(可以为 null)

    // 查询(根据ID 批量查询)
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // idList	主键 ID 列表(不能为 null 以及 empty)
	@Test
    public void testSelectBatchIds(){
        //根据多个id查询多个用户信息
        //SELECT id,name,age,email FROM user WHERE id IN ( ? , ? )
        List<Long> idList = Arrays.asList(4L, 5L);
        List<User> list = userMapper.selectBatchIds(idList);
        list.forEach(System.out::println);
    }

    // 根据 entity 条件,查询全部记录
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
	@Test
    public void testSelectList(){
        //查询所有用户信息
        //SELECT id,name,age,email FROM user
        List<User> list = userMapper.selectList(null);
        list.forEach(System.out::println);
    }

    // 查询(根据 columnMap 条件)
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); // columnMap	表字段 map 对象
	@Test
    public void testSelectByMap(){
        //通过map条件查询用户信息
        //SELECT id,name,age,email FROM user WHERE name = ? AND age = ?
        Map<String, Object> map = new HashMap<>();
        map.put("age", 22);
        map.put("name", "admin");
        List<User> list = userMapper.selectByMap(map);
        list.forEach(System.out::println);
    }

    // 根据 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); // page	分页查询条件(可以为 RowBounds.DEFAULT)

    // 根据 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就是在我们可以使用MyBatisPlus提供的封装好的一些单表的基本的CURD操作,直接在Service层与数据库进行交互
    
MyBatis-Plus中有一个接口 IService和其实现类 ServiceImpl,封装了常见的业务层逻辑
一般我们都会有自己的业务Service接口,因此我们需要继承MyBatisPlusServiceImpl再实现我们自定义的Service接口
// UserService.java
// ServiceImpl实现了IService,提供了IService中基础功能的实现
// 若ServiceImpl无法满足业务需求,则可以使用自定的UserService定义方法,并在实现类中实现
    @Service
    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements
        UserService {
    } 

1. Save
    // 插入一条记录(选择字段,策略插入)
    boolean save(T entity); // entity	实体对象

    // 插入(批量)
    boolean saveBatch(Collection<T> entityList); // entityList	实体对象集合
	@Test
    public void testSaveBatch(){
        // SQL长度有限制,海量数据插入单条SQL无法实行,
        // 因此MP将批量插入放在了通用Service中实现,而不是通用Mapper
        ArrayList<User> users = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            User user = new User();
            user.setName("ybc" + i);
            user.setAge(20 + i);
            users.add(user);
        }
        //SQL:INSERT INTO t_user ( username, age ) VALUES ( ?, ? )
        userService.saveBatch(users);
    }

    // 插入(批量)
    boolean saveBatch(Collection<T> entityList, int batchSize); // batchSize	插入批次数量

2. SaveOrUpdate
    // TableId 注解存在更新记录,否插入一条记录
    boolean saveOrUpdate(T entity); // entity	实体对象	

    // 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
    boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper); // updateWrapper	实体对象封装操作类 UpdateWrapper

    // 批量修改插入
    boolean saveOrUpdateBatch(Collection<T> entityList); // entityList	实体对象集合

    // 批量修改插入
    boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize); // batchSize	插入批次数量

3. Remove
	// 根据 entity 条件,删除记录
    boolean remove(Wrapper<T> queryWrapper); // queryWrapper	实体包装类 QueryWrapper

    // 根据 ID 删除
    boolean removeById(Serializable id); // id	主键 ID

    // 根据 columnMap 条件,删除记录
    boolean removeByMap(Map<String, Object> columnMap); // columnMap	表字段 map 对象

    // 删除(根据ID 批量删除)
    boolean removeByIds(Collection<? extends Serializable> idList); // idList	主键 ID 列表

4. Update
    // 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
    boolean update(Wrapper<T> updateWrapper); // updateWrapper	实体对象封装操作类 UpdateWrapper

    // 根据 whereWrapper 条件,更新记录
    boolean update(T updateEntity, Wrapper<T> whereWrapper);

    // 根据 ID 选择修改
    boolean updateById(T entity); // entity	实体对象

    // 根据ID 批量更新
    boolean updateBatchById(Collection<T> entityList); // entityList	实体对象集合

    // 根据ID 批量更新
    boolean updateBatchById(Collection<T> entityList, int batchSize); // batchSize	更新批次数量

5. Get
    // 根据 ID 查询
    T getById(Serializable id);

    // 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
    T getOne(Wrapper<T> queryWrapper);

    // 根据 Wrapper,查询一条记录
    T getOne(Wrapper<T> queryWrapper, boolean throwEx); // throwEx	有多个 result 是否抛出异常

    // 根据 Wrapper,查询一条记录
    Map<String, Object> getMap(Wrapper<T> queryWrapper);

    // 根据 Wrapper,查询一条记录
    <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper); // mapper	转换函数

6. List
    // 查询所有
    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);

7. Page
    // 无条件分页查询
    IPage<T> page(IPage<T> page); // page	翻页对象

    // 条件分页查询
    IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);

    // 无条件分页查询
    IPage<Map<String, Object>> pageMaps(IPage<T> page);

    // 条件分页查询
    IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

8. Count
    // 查询总记录数
    int count();

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

9. Chain
    chain-query
    	// 链式查询 普通
        QueryChainWrapper<T> query();
        // 链式查询 lambda 式。注意:不支持 Kotlin
        LambdaQueryChainWrapper<T> lambdaQuery();

        // 示例:
        query().eq("column", value).one();
        lambdaQuery().eq(Entity::getId, value).list();

	chain-update
        // 链式更改 普通
        UpdateChainWrapper<T> update();
        // 链式更改 lambda 式。注意:不支持 Kotlin
        LambdaUpdateChainWrapper<T> lambdaUpdate();

        // 示例:
        update().eq("column", value).remove();
        lambdaUpdate().eq(Entity::getId, value).update(entity);


常用注解

1. @TableName
使用MyBatis-Plus实现基本的CRUD时,我们并没有指定要操作的表,只是在Mapper接口继承BaseMapper时,设置了泛型User,而操作的表为user表,因此MyBatis-Plus在确定操作的表时,由BaseMapper的泛型决定,即实体类型决定,且默认操作的表名和实体类型的类名一致
    1.1 若操作的实体与表名不一致时,我们可以使用@TableName来修正
    若表名为【t_user】则对应的实体类标识
    @TableName("t_user")
    public class User{
        // ...
    }
	1.2 若团队规定了使用统一方式建表,如t_tablename,则可以通过全局配置解决
     mybatis-plus:
        configuration:
        	global-config:
        		db-config:
        			# 配置MyBatis-Plus操作表的默认前缀
        			table-prefix: t_ // 就不需要额外再在每个实体上使用@TableName

2. @TableId
MyBatis-Plus在实现CRUD时,会默认将id作为主键列,并在插入数据时,默认基于雪花算法的策略生成id,若我们表、实体类中主键名称非id,即使我们在表中让主键自增,而不设置实体主键标识,同样在使用MP时不会生效;若我们的表中主键与实体主键属性不一致时,我们需要通过实体类主键属性进行标识
     1.1 实体类与表主键名称非【id】
     public class User{
         @TableId
         private Long uid;
     }    
	1.2 实体类与表主键名称不一致
     public class User{
         @TableId("uid") | @TableId(value="uid")
         private Long id;
     }
	1.3 type属性
     IdType.ASSIGN_ID(默认) 基于雪花算法的策略生成数据id,与数据库id是否设置自增无关; 
     IdType.AUTO 使用数据库的自增策略,注意,该类型请确保数据库设置了id自增,否则无效   
     @TableId(value="uid", type=IdType.AUTO)
     1.4 全局配置
     mybatis-plus:
        configuration:
        	global-config:
        		db-config:
        			# 配置MyBatis-Plus的主键策略
					id-type: auto
                        
3. @TableField
   MyBatis-Plus在执行SQL语句时,要保证【实体类中的属性名】和【表中的字段名】一致   
   1.1 驼峰转换
   一般在java实体类中我们使用驼峰命名,而表字段我们使用下划线命名,如userName【user_name】
   MyBatis-Plus会自动将下划线命名风格转化为驼峰命名风格,在MyBatis中我们得知此项可设置,而MP则自动转换
   1.2 两边不一致
   如name【user_name】,此时需要使用@TableField标识
   public class User{
       @TableField("user_name")
       private String name;
   }

4. @TableLogic
   物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据
   逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库
中仍旧能看到此条数据记录 
    
    1. 实体中增加逻辑删除标识属性
    public class User{
       @TableLogic
       private Integer hasDeleted;
    }
	2. 表中增加has_deleted字段

条件构造器

Wrapper.png

配合通用Service、通用Mapper中所提供的方法参数为Wrapper的均可使用
    
1. QueryWrapper
    // 常规使用
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.like("username", "a")
        .between("age", 20, 30)
        .isNotNull("email");
    List<User> list = userMapper.selectList(queryWrapper);
    list.forEach(System.out::println);
	
	// condition条件拼接
	String username = null;
	Integer ageBegin = 10;
	Integer ageEnd = 24;
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	queryWrapper
		.like(StringUtils.isNotBlank(username), "username", "a")
        .ge(ageBegin != null, "age", ageBegin)
		.le(ageEnd != null, "age", ageEnd);
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);

2. UpdateWrapper
    UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
    updateWrapper
        .set("age", 18)
        .set("email", "user@atguigu.com")
        .like("username", "a")
        .and(i -> i.gt("age", 20).or().isNull("email"));
	int result = userMapper.update(null, updateWrapper);
System.out.println(result);

3. LambdaQueryWrapper
    String username = "a";
	Integer ageBegin = 10;
	Integer ageEnd = 24;
	LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper
    .like(StringUtils.isNotBlank(username), User::getName, username)
    .ge(ageBegin != null, User::getAge, ageBegin)
    .le(ageEnd != null, User::getAge, ageEnd);
    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);
    
4. LambdaUpdateWrapper
    LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
    updateWrapper
    .set(User::getAge, 18)
    .set(User::getEmail, "user@atguigu.com")
    .like(User::getName, "a")
    .and(i -> i.lt(User::getAge, 24).or().isNull(User::getEmail));
    User user = new User();
    int result = userMapper.update(user, updateWrapper);
    System.out.println("受影响的行数:" + result);

);
List users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);

  1. LambdaUpdateWrapper
    LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
    updateWrapper
    .set(User::getAge, 18)
    .set(User::getEmail, “user@atguigu.com”)
    .like(User::getName, “a”)
    .and(i -> i.lt(User::getAge, 24).or().isNull(User::getEmail));
    User user = new User();
    int result = userMapper.update(user, updateWrapper);
    System.out.println(“受影响的行数:” + result);

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:01:38  更:2022-10-22 21:05:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 22:53:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码