【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结

目录

1.测试自定义功能

2.通用Service

创建Service接口和实现类

 测试查询数据库中有多少条记录

 测试批量添加操作(通过单个批量增加循环实现)

3.常用注解(@TableName)

解决方法:

4.常用注解(@TableId)

5.常用注解(@TableField)

 6.常用注解(@TableLogic)

7.总结 

8.代码整理:


1.测试自定义功能

先创建一个mybatis-mapper的模板文件,然后将下面的代码放入其中保存。这样我们就可以创建一个自定义的xml文件了。

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第1张图片








在UserMapper中自己写一个方法用来补充继承的BaseMapper中没有的方法。

package com.atzeren.mybatis_plus.mapper;

import com.atzeren.mybatis_plus.pojo.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import java.util.Map;

public interface UserMapper extends BaseMapper {

    /**
     * 根据id查询用户id为map集合
     * @param id
     * @return
     */
    Map selectMapById(Long id);

}

然后将对应的SQL语句写到映射文件中








    

接下来进行测试:

@Test
    public void testSelectMapById(){
        Map map =userMapper.selectMapById(4L);
        System.out.println(map);
    }

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第2张图片

 与SelectById比较,我们发现他们的功能一样,这里我们只是重新写了一个和SelectById方法一样的方法,设说明我们仍然可以自定义功能在mybatisplus中,mybatisplus只对mybatis进行增强而不会改变。

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

2.通用Service

  • 通用 Service CRUD 封装IService接口,进一步封装 CRUD采用 get 查询单行 remove 删 除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混淆
  • 泛型 T 为任意实体对象
  • 建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承 Mybatis-Plus 提供的基类
  • MyBatis-Plus中有一个接口 IService和其实现类 ServiceImpl,封装了常见的业务层逻辑

创建Service接口和实现类

//接口
package com.atzeren.mybatis_plus.service;
import com.atzeren.mybatis_plus.pojo.User;
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * @Program:mybaties_plus
 * @description:service
 * @author: jaingzeren
 * @create: 2022-11-11 15
 **/
public interface UserService extends IService {
}

//实现类
package com.atzeren.mybatis_plus.service.imp;

import com.atzeren.mybatis_plus.mapper.UserMapper;
import com.atzeren.mybatis_plus.pojo.User;
import com.atzeren.mybatis_plus.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * @Program:mybaties_plus
 * @description:imp
 * @author: jiangzeren
 * @create: 2022-11-11 16
 **/
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {

}

 测试查询数据库中有多少条记录

package com.atzeren.mybatis_plus;

import com.atzeren.mybatis_plus.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @Program:mybaties_plus
 * @description:test
 * @author: jiangzeren
 * @create: 2022-11-11 16
 **/
@SpringBootTest
public class MybatisPlusServiceTest {
    @Autowired
    private UserService userService;
    @Test
    public void testGetCount(){
        //查询总记录数
        long count = userService.count();
        System.out.println("总记录数:" + count);
    }

}

 测试批量添加操作(通过单个批量增加循环实现)

@Test
    public void testInsertMore(){
        //实现批量添加操作
        //INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? )
        List list = new ArrayList<>();
        for (int i = 0;i<20;i++){
            User user = new User();
            user.setName("zrj"+i);
            user.setAge(20+i);
            list.add(user);
        }
        boolean b = userService.saveBatch(list);
        System.out.println(b);
    }

结果:

JDBC Connection [HikariProxyConnection@549049813 wrapping com.mysql.cj.jdbc.ConnectionImpl@671d1157] will be managed by Spring
==>  Preparing: INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? )
==> Parameters: 1591043875382792193(Long), zrj0(String), 20(Integer)
==> Parameters: 1591043875546370050(Long), zrj1(String), 21(Integer)
==> Parameters: 1591043875546370051(Long), zrj2(String), 22(Integer)
==> Parameters: 1591043875546370052(Long), zrj3(String), 23(Integer)
==> Parameters: 1591043875546370053(Long), zrj4(String), 24(Integer)
==> Parameters: 1591043875546370054(Long), zrj5(String), 25(Integer)
==> Parameters: 1591043875546370055(Long), zrj6(String), 26(Integer)
==> Parameters: 1591043875546370056(Long), zrj7(String), 27(Integer)
==> Parameters: 1591043875546370057(Long), zrj8(String), 28(Integer)
==> Parameters: 1591043875546370058(Long), zrj9(String), 29(Integer)
==> Parameters: 1591043875546370059(Long), zrj10(String), 30(Integer)
==> Parameters: 1591043875546370060(Long), zrj11(String), 31(Integer)
==> Parameters: 1591043875546370061(Long), zrj12(String), 32(Integer)
==> Parameters: 1591043875546370062(Long), zrj13(String), 33(Integer)
==> Parameters: 1591043875617673217(Long), zrj14(String), 34(Integer)
==> Parameters: 1591043875617673218(Long), zrj15(String), 35(Integer)
==> Parameters: 1591043875617673219(Long), zrj16(String), 36(Integer)
==> Parameters: 1591043875617673220(Long), zrj17(String), 37(Integer)
==> Parameters: 1591043875617673221(Long), zrj18(String), 38(Integer)
==> Parameters: 1591043875617673222(Long), zrj19(String), 39(Integer)
true

注意:

        由于SQL长度有限制,在海量数据添加中添加单挑SQL数据是无法进行的。

        因此,Mapper中将批量添加放在了通用的Service中实现,而不是使用Mapper进行操作。

3.常用注解(@TableName

首先明白在实现mybatis-plus的过程中,我们仅仅是在UserMapper中设置了一个泛型User,所以我们所操作的表是由我们的实体类来实现的。那么当出现数据库中的表和我们声明的user不同时,我们的添加是无法完成的,我们将表user更名为t_user,测试查询功能 程序抛出异常,Table 'mybatis_plus.user' doesn't exist,因为现在的表名为t_user,而默认操作的表名和实体类型的类名一致。

解决方法:

 ①:在实体类开头添加@TableName("t_user")注解

@Data
@TableName("t_user")
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
==>  Preparing: SELECT id,name,age,email FROM t_user WHERE id=?
==> Parameters: 4(Long)
<==    Columns: id, name, age, email
<==        Row: 4, 张三, 21, [email protected]
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@61af1510]
User(id=4, name=张三, age=21, [email protected])

②:在yml中配置全局变量 global-config:    db-config:      table-prefix: t_(注意如果报错的话可能是存在中文的原因,要么进行setting设置修改,要么将yml中的中文删去,我们这里选择删去中文注释)。

在开发的过程中,我们经常遇到以上的问题,即实体类所对应的表都有固定的前缀,例如t_或tbl_ 此时,可以使用MyBatis-Plus提供的全局配置,为实体类所对应的表名设置默认的前缀,那么就 不需要在每个实体类上通过@TableName标识实体类对应的表

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
    username: root
    password: abc123
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      table-prefix: t_

4.常用注解(@TableId

经过测试,mybatis-plus会默认将id作为主键列,并在插入数据时,默认基于雪花算法的策略生成id(MySQL中的组件框架中不能够识别)。

若实体类和表中表示主键的不是id,而是其他字段,例如uid,MyBatis-Plus不会自动识别uid为主键列。

解决方法:

通过@TableId解决问题 在实体类中uid属性上通过@TableId将其标识为主键,即可成功执行SQL语句。

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第3张图片

 上面的@TableId解决方法也可以使用其属性value指定,这样运行得到的结果一样。此时需要通过@TableId注解的value属性,指定表中的主键字段,@TableId("uid")或 @TableId(value="uid"),这里的value如果只写了一个的话value可以省略。

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第4张图片

如何实现不使用雪花算法实现id自增  

如果只是修改数据库中的id自增,IDEA中还是会默认私用雪花算法生成id,只不过是使用雪花算法生成的id进行自增

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第5张图片

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第6张图片

@Data
//设置实体类对应的表名
//@TableName("t_user")
public class User {
    @TableId(value ="uid" ,type = IdType.AUTO)//(IdType.AUTO数据库中必须要设置了自增才有效)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

这个时候需要使用的是我们TableId中的另外一个属性----Type。

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第7张图片

 这里需要特别注意,如果这个时候我们继续在原来的基础上进行添加,无论我们原来的表是不是有顺序的,还是无序的,我们得到的结果仍然还可能是用雪花算法得到的id,我们此时需要对表进行截断。(t_user--->更多表操作--->截/断表)这里是在SQLyog中进行的操作。

在yml中进行全局属性配置进行自增(实现在最大id基础上进行递增)

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      table-prefix: t_
      id-type: auto

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第8张图片

 此时我们的数据中原来id为10的基础上进行了增加。

5.常用注解(@TableField)

经过以上的测试,我们可以发现,MyBatis-Plus在执行SQL语句时,要保证实体类中的属性名和 表中的字段名一致 如果实体类中的属性名和字段名不一致的情况,会出现什么问题呢?

  • 情况1 若实体类中的属性使用的是驼峰命名风格,而表中的字段使用的是下划线命名风格 例如实体类属性userName,表中字段user_name 此时MyBatis-Plus会自动将下划线命名风格转化为驼峰命名风格 相当于在MyBatis中配置

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第9张图片

  • 情况2 若实体类中的属性和表中的字段不满足情况1 例如实体类属性name,表中字段username 此时需要在实体类属性上使用@TableField("username")设置属性所对应的字段名

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第10张图片

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第11张图片 声明:这部分来自尚硅谷mybatis-plus(springboot版本资料)

 6.常用注解(@TableLogic)

  • 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据
  • 逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库 中仍旧能看到此条数据记录
  • 使用场景:可以进行数据恢复

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第12张图片

package com.atzeren.mybatis_plus.pojo;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;

/**
 * @Program:mybatis_plus
 * @description:pojo
 * @author: jiangzeren
 * @create: 2022-11-02 09
 **/
@Data
//设置实体类对应的表名
//@TableName("t_user")
public class User {
//    @TableId(value ="uid" ,type = IdType.AUTO)//(IdType.AUTO数据库中必须要设置了自增才有效)
    @TableId(value ="uid")
    private Long id;

    @TableField("user_name")
    private String name;

    private Integer age;

    private String email;

    @TableLogic
    private Integer isDeleted;

}

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第13张图片

 【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第14张图片

 这里的删除只是逻辑上的删除,我们在查询中是无法查找到的。【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第15张图片

这里的逻辑删除的意义在于我们的用户可以进行恢复数据,而不是进行删除后无法恢复,相当于我们的撤销操作。

7.总结 

【Mybatisplus】创建Spring Boot工程实现用户自定义功能Service接口和常用注解总结_第16张图片

8.代码整理:

  • mybatisplusTest
package com.atzeren.mybatis_plus;

import com.atzeren.mybatis_plus.mapper.UserMapper;
import com.atzeren.mybatis_plus.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Program:mybatis_plus
 * @description test
 * @author: jiangzeren
 * @create: 2022-11-02 09
 **/
@SpringBootTest
public class mybatisplusTest {

    @Autowired
    private UserMapper userMapper;


    @Test
    void testSelectList(){
        List list = userMapper.selectList(null);
        list.forEach(System.out::println);
    }

    @Test
    public void testInsert(){
        //实现新增用户信息
        //INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
        User user = new User();
        user.setName("大仙");
        user.setAge(34);
        user.setEmail("[email protected]");
        int result = userMapper.insert(user);
        System.out.println("result:"+result);
        System.out.println("id:"+user.getId());
    }

    @Test
    public void testDelete(){
//        通过Id删除用户信息
//        DELETE FROM user WHERE id=?
//        userMapper.deleteById(1590888429762240514L);
//        userMapper.deleteById(1590892685902761985L);
//        userMapper.deleteById(1590894027761336322L);
//        userMapper.deleteById(1590894230195191809L);
//        userMapper.deleteById(1590898437178601474L);


//        根据map集合中设置的条件删除用户信息(map集合中的信息必须全部匹配才能删除成功)
//        DELETE FROM user WHERE name = ? AND age = ?
//        Map map = new HashMap<>();
//        map.put("name","大仙");
//        map.put("age",34);
//        int result = userMapper.deleteByMap(map);
//        System.out.println("result:"+result);


//        通过多个id实现批量删除
//        DELETE FROM user WHERE id IN ( ? , ? , ? )
        List list = Arrays.asList(1L, 2L, 3L);
        int result = userMapper.deleteBatchIds(list);
        System.out.println("result:"+result);
    }

    @Test
    public void testUpdateById(){
        //UPDATE user SET name=?, age=? WHERE id=?
        User user = new User();
        user.setId(4L);
        user.setName("李四");
        user.setEmail("[email protected]");
        int result = userMapper.updateById(user);
        System.out.println("受影响行数:"+result);
    }

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

    @Test
    public void testSelectBatchIds(){
        //根据多个id查询多个用户信息
        //SELECT id,name,age,email FROM user WHERE id IN ( ? , ? )
        List idList = Arrays.asList(1L, 2L,3L,5L);
        List list = userMapper.selectBatchIds(idList);
        list.forEach(System.out::println);
    }


    @Test
    public void testSelectMapById(){
        Map map =userMapper.selectMapById(4L);
        System.out.println(map);
    }


}
  • MybatisPlusServiceTest
package com.atzeren.mybatis_plus;

import com.atzeren.mybatis_plus.pojo.User;
import com.atzeren.mybatis_plus.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

/**
 * @Program:mybaties_plus
 * @description:test
 * @author: jiangzeren
 * @create: 2022-11-11 16
 **/
@SpringBootTest
public class MybatisPlusServiceTest {
    @Autowired
    private UserService userService;
    @Test
    public void testGetCount(){
        //查询总记录数
        long count = userService.count();
        System.out.println("总记录数:" + count);
    }

    @Test
    public void testInsertMore(){
        List list = new ArrayList<>();
        for (int i = 0;i<5;i++){
            User user = new User();
            user.setName("zrj"+i);
            user.setAge(20+i);
            list.add(user);
        }
        boolean b = userService.saveBatch(list);
        System.out.println(b);
    }

}
  •  application.yml
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
    username: root
    password: abc123
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      table-prefix: t_
      id-type: auto

你可能感兴趣的:(MyBaties-plus学习,mybatis)