mybatis-plus的入门学习

环境

  • IDEA
  • springboot
  • maven
  • mysql5.7

开始

1.首先需要准备一张表user

CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);
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');

2.创建一个springboot初始化工程
在这里插入图片描述
在这里插入图片描述
根据需要选择
在这里插入图片描述
完整pom.xml:(大家可以根据需要添加坐标)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.king</groupId>
    <artifactId>mybatis_plus</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatis_plus</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
    	<dependency>
    	<groupId>com.baomidou</groupId>
    	<artifactId>mybatis-plus-boot-starter</artifactId>
   		 <version>3.3.1.tmp</version>
		</dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.在application.yml中配置mysql数据源

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC

4.编写表对应的实体类User

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Long Id;
    private String name;
    private Integer age;
    private String email;
}

5.编写操作实体类的 Mapper 类,直接继承 BaseMapper,这是 mybatis-plus 封装好的类。
在这里插入图片描述
6.先得在启动类里扫描 Mapper 类,即添加 @MapperScan 注解

@SpringBootApplication
//mapper类所在的目录路径
@MapperScan("com.king.mybatis_plus.mapper")
public class MybatisPlusApplication {

    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusApplication.class, args);
    }

}

7.编写测试类

@SpringBootTest
class MybatisPlusApplicationTests {
    @Autowired(required = false)
    private UserMapper userMapper;

    /**
     * 查询
     */
    @Test
    public void testSelect(){
        /*查询所有的数据UserMapper
        中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper,
        所以不填写就是无任何条件*/
        List<User> list=userMapper.selectList(null);
        for (User user:list){
            System.out.println(user);
        }

        //根据主键查询
        System.out.println("记录:");
        System.out.println(userMapper.selectById(1));
    }

    /**
     * 添加
     */
    @Test
    public void testInsert(){
        //主键会自动生成
        User user=new User();
        user.setName("king");
        user.setAge(20);
        user.setEmail("123456@qq.com");
        System.out.println("插入结果:"+userMapper.insert(user));
    }
    /**
     * 删除
     */
    @Test
    public void testDelete(){
        System.out.println("删除结果:"+userMapper.deleteById(1));
    }

    /**
     * 修改
     */
    @Test
    public void testUpdate(){
        User user=new User();
        user.setId(2L);
        user.setName("ting");
        user.setAge(30);
        user.setEmail("2345@qq.com");
        System.out.println("修改结果:"+userMapper.updateById(user));
    }
}

好的,到这里简单的CRUD就好了


注解

下面来看一下mybatis-plus的一些注解吧
@TableName
描述:表名注解

属性类型必须指定默认值描述
valueString“”表名
schemaString“”schema
keepGlobalPrefixbooleanfalse是否保持使用全局的 tablePrefix 的值(如果设置了全局 tablePrefix 且自行设置了 value 的值)
resultMapString“”xml 中 resultMap 的 id
autoResultMapbooleanfalse是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入)

关于autoResultMap的说明:

mp会自动构建一个ResultMap并注入到mybatis里(一般用不上).下面讲两句: 因为mp底层是mybatis,所以一些mybatis的常识你要知道,mp只是帮你注入了常用crud到mybatis里 注入之前可以说是动态的(根据你entity的字段以及注解变化而变化),但是注入之后是静态的(等于你写在xml的东西) 而对于直接指定typeHandler,mybatis只支持你写在2个地方:

  1. 定义在resultMap里,只作用于select查询的返回结果封装
  2. 定义在insertupdatesql的#{property}里的property后面(例:#{property,typehandler=xxx.xxx.xxx}),只作用于设置值 而除了这两种直接指定typeHandler,mybatis有一个全局的扫描你自己的typeHandler包的配置,这是根据你的property的类型去找typeHandler并使用.

@TableId

  • 描述:主键注解
属性类型必须指定默认值描述
valueString“”主键字段名
typeEnumIdType.NONE主键类型
#IdType
描述
AUTO数据库ID自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert前自行set主键值
ASSIGN_ID分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)
ID_WORKER分布式全局唯一ID 长整型类型(please use ASSIGN_ID)
UUID32位UUID字符串(please use ASSIGN_UUID)
ID_WORKER_STR分布式全局唯一ID 字符串类型(please use ASSIGN_ID)

#@TableField

  • 描述:字段注解(非主键)
属性类型必须指定默认值描述
valueString“”数据库字段名
elString“”映射为原生 #{ ... } 逻辑,相当于写在 xml 里的 #{ ... } 部分
existbooleantrue是否为数据库表字段
conditionString“”字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s},参考
updateString“”字段 update set 部分注入, 例如:update="%s+1":表示更新时会set version=version+1(该属性优先级高于 el 属性)
insertStrategyEnumNDEFAULT举例:NOT_NULL: insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)
updateStrategyEnumNDEFAULT举例:IGNORED: update table_a set column=#{columnProperty}
whereStrategyEnumNDEFAULT举例:NOT_EMPTY: where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
fillEnumFieldFill.DEFAULT字段自动填充策略
selectbooleantrue是否进行 select 查询
keepGlobalFormatbooleanfalse是否保持使用全局的 format 进行处理
jdbcTypeJdbcTypeJdbcType.UNDEFINEDJDBC类型 (该默认值不代表会按照该值生效)
typeHandlerClass<? extends TypeHandler>UnknownTypeHandler.class类型处理器 (该默认值不代表会按照该值生效)
numericScaleString“”指定小数点后保留的位数

关于jdbcTypetypeHandler以及numericScale的说明:

numericScale只生效于 update 的sql. jdbcTypetypeHandler如果不配合@TableName#autoResultMap = true一起使用,也只生效于 update 的sql. 对于typeHandler如果你的字段类型和set进去的类型为equals关系,则只需要让你的typeHandler让Mybatis加载到即可,不需要使用注解

FieldStrategy
描述
IGNORED忽略判断
NOT_NULL非NULL判断
NOT_EMPTY非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断)
DEFAULT追随全局配置
FieldFill
描述
DEFAULT默认不处理
INSERT插入时填充字段
UPDATE更新时填充字段
INSERT_UPDATE插入和更新时填充字段

更多注解可以看官方文档:https://baomidou.com/guide/annotation.html

代码生成器

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。与 mybatis 中的 mybatis-generator-core 类似。

1、创建一个新的springboot工程:
目录结构:
在这里插入图片描述

2、完整的pom依赖:
【大家可以使用我的pom,我在这里碰到了好多坑啊,因为依赖版本的问题,搞了我很久】

      <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.king</groupId>
    <artifactId>mybatis_plus_generator</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatis_plus_generator</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

     
        <!-- mybatisPlus 核心库 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>

        <!--  mybatis plus 代码生成器 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.0.6</version>
        </dependency>

        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.20</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>

    </build>

</project>

3、运行配置文件

配置文件(大家根据自己的工程进行修改相应的东西):


/**
 * 代码生成器类
 *
 * @author king
 * @version 1.0
 * @date 2020/10/29 15:53
 */
public class CodeGenerator {

    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        final String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("king");
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);
        // 是否打开输出目录 默认为true
        gc.setOpen(false);
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        mpg.setDataSource(dsc);

        // 包配置
        final PackageConfig pc = new PackageConfig();
        // pc.setModuleName(scanner("模块名"));
        pc.setParent("com.king");
        mpg.setPackageInfo(pc);

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templates/mapper.xml.vm";

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<FileOutConfig>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                return projectPath + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();

        // 配置自定义输出模板
        // 指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        // templateConfig.setEntity("templates/entity2.java");
        // templateConfig.setService();
        // templateConfig.setController();

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // strategy.setSuperEntityClass("com.fame.common.BaseEntity");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        // strategy.setSuperControllerClass("com.fame.common.BaseController");
        strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
        //strategy.setSuperEntityColumns("id");
        // strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix("sys");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

}

在这里插入图片描述
在这里插入图片描述
4、自动生成了这些实体类业务类控制层类xml文件等等
在这里插入图片描述
5、在启动类上需要加@MapperScanner,用来扫描mapper类

@SpringBootApplication
@MapperScan("com.king.mapper")
public class MybatisPlusGeneratorApplication {

    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusGeneratorApplication.class, args);
    }

}

6、yml文件配置

server:
  port: 8089
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    username: root
    password: 123456


# mybatis-plus相关配置
mybatis-plus:
  # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
  mapper-locations: classpath:mapper/*.xml
  # 以下配置均有默认值,可以不设置
  global-config:
    db-config:
      #主键类型 AUTO:"数据库ID自增" INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
      id-type: ID_WORKER
      #字段策略 IGNORED:"忽略判断"  NOT_NULL:"非 NULL 判断")  NOT_EMPTY:"非空判断"
      field-strategy: IGNORED
      #数据库类型
      db-type: MYSQL

  # 指定实体类的包
  type-aliases-package: com.king.entity
  configuration:
    # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
    map-underscore-to-camel-case: true
    # 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段
    call-setters-on-nulls: true
    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

7、写测试类

 @Autowired
    private IUserService iUserService;
    @Autowired(required = false)
    private UserMapper userMapper;

    /**
     * 查询
     */
    @Test
    public void testSelect(){
        //查询所有
        System.out.println(userMapper.selectList(null));
        System.out.println(iUserService.list());
        //查询单个
        System.out.println(userMapper.selectById(2));
        System.out.println(iUserService.getById(2));
    }

    /**
     * 添加数据
     */
    @Test
    public void insert(){
        User user=new User();
        user.setAge(20);
        user.setName("ting");
        user.setEmail("234242@qq.com");

        User user2=new User();
        user2.setAge(22);
        user2.setName("ting2");
        user2.setEmail("234242@qq.com");
        //单条添加
        //System.out.println("添加结果:"+userMapper.insert(user));
        //System.out.println("添加结果:"+iUserService.save(user2));

        //批量添加
        List<User> list=new ArrayList<>();
        list.add(user);
        list.add(user2);
        System.out.println("批量添加结果:"+iUserService.saveBatch(list));
    }

    /**
     * 删除
     */
    @Test
    public void delete(){
        //通过id删除
        System.out.println("删除结果:"+userMapper.deleteById(2));
        System.out.println("删除结果:"+iUserService.removeById(3));

        //批量删除
        List<Integer> list1=new ArrayList<>();
        List<Long> list2=new ArrayList<>();
        list1.add(1);
        list1.add(5);
        list2.add(1321747562349043714L);
        list2.add(1321747562349043715L);
        System.out.println("批量删除1:"+userMapper.deleteBatchIds(list1));
        boolean flag=iUserService.removeByIds(list2);
        System.out.println("批量删除2:"+flag);
    }

    /**
     * 修改
     */
    @Test
    public void update(){
        User user1=new User(1321972874844389378L,"aa",10,"2929292@qq.com");
        User user2=new User(1321973036350185473L,"bb",20,"34242342@qq.com");
        List<User> list=new ArrayList<>();
        list.add(user1);
        list.add(user2);
        //单条修改
        System.out.println("修改结果2:"+userMapper.updateById(user1));
        System.out.println("修改结果2:"+iUserService.updateById(user2));
        //批量修改
        System.out.println("修改结果3:"+iUserService.updateBatchById(list));
    }

用代码生成器生成的实体类、业务类、控制层就测试完了

源码

既然他这么方便,那么我们需要知道他是怎么实现的,来看看源码吧

1)mapper
他继承了BaseMapper

public interface UserMapper extends BaseMapper<User> {

}

BaseMapper:
可以发现他实现了很多功能

public interface BaseMapper<T> {
    int insert(T var1);

    int deleteById(Serializable var1);

    int deleteByMap(@Param("cm") Map<String, Object> var1);

    int delete(@Param("ew") Wrapper<T> var1);

    int deleteBatchIds(@Param("coll") Collection<? extends Serializable> var1);

    int updateById(@Param("et") T var1);

    int update(@Param("et") T var1, @Param("ew") Wrapper<T> var2);

    T selectById(Serializable var1);

    List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> var1);

    List<T> selectByMap(@Param("cm") Map<String, Object> var1);

    T selectOne(@Param("ew") Wrapper<T> var1);

    Integer selectCount(@Param("ew") Wrapper<T> var1);

    List<T> selectList(@Param("ew") Wrapper<T> var1);

    List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> var1);

    List<Object> selectObjs(@Param("ew") Wrapper<T> var1);

    IPage<T> selectPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);

    IPage<Map<String, Object>> selectMapsPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
}

业务类:

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

}

ServiceImpl源码:
他实现的功能更加多

public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
    @Autowired
    protected M baseMapper;

    public ServiceImpl() {
    }

    protected boolean retBool(Integer result) {
        return SqlHelper.retBool(result);
    }

    protected Class<T> currentModelClass() {
        return ReflectionKit.getSuperClassGenericType(this.getClass(), 1);
    }

    protected SqlSession sqlSessionBatch() {
        return SqlHelper.sqlSessionBatch(this.currentModelClass());
    }

    protected void closeSqlSession(SqlSession sqlSession) {
        SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(this.currentModelClass()));
    }

    protected String sqlStatement(SqlMethod sqlMethod) {
        return SqlHelper.table(this.currentModelClass()).getSqlStatement(sqlMethod.getMethod());
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean save(T entity) {
        return this.retBool(this.baseMapper.insert(entity));
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean saveBatch(Collection<T> entityList, int batchSize) {
        int i = 0;
        String sqlStatement = this.sqlStatement(SqlMethod.INSERT_ONE);
        SqlSession batchSqlSession = this.sqlSessionBatch();
        Throwable var6 = null;

        try {
            for(Iterator var7 = entityList.iterator(); var7.hasNext(); ++i) {
                T anEntityList = var7.next();
                batchSqlSession.insert(sqlStatement, anEntityList);
                if (i >= 1 && i % batchSize == 0) {
                    batchSqlSession.flushStatements();
                }
            }

            batchSqlSession.flushStatements();
            return true;
        } catch (Throwable var16) {
            var6 = var16;
            throw var16;
        } finally {
            if (batchSqlSession != null) {
                if (var6 != null) {
                    try {
                        batchSqlSession.close();
                    } catch (Throwable var15) {
                        var6.addSuppressed(var15);
                    }
                } else {
                    batchSqlSession.close();
                }
            }

        }
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean saveOrUpdate(T entity) {
        if (null == entity) {
            return false;
        } else {
            Class<?> cls = entity.getClass();
            TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
            if (null != tableInfo && StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
                Object idVal = ReflectionKit.getMethodValue(cls, entity, tableInfo.getKeyProperty());
                return !StringUtils.checkValNull(idVal) && !Objects.isNull(this.getById((Serializable)idVal)) ? this.updateById(entity) : this.save(entity);
            } else {
                throw ExceptionUtils.mpe("Error:  Can not execute. Could not find @TableId.", new Object[0]);
            }
        }
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
        if (CollectionUtils.isEmpty(entityList)) {
            throw new IllegalArgumentException("Error: entityList must not be empty");
        } else {
            Class<?> cls = this.currentModelClass();
            TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
            int i = 0;
            SqlSession batchSqlSession = this.sqlSessionBatch();
            Throwable var7 = null;

            try {
                Iterator var8 = entityList.iterator();

                while(var8.hasNext()) {
                    T anEntityList = var8.next();
                    if (null == tableInfo || !StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
                        throw ExceptionUtils.mpe("Error:  Can not execute. Could not find @TableId.", new Object[0]);
                    }

                    Object idVal = ReflectionKit.getMethodValue(cls, anEntityList, tableInfo.getKeyProperty());
                    if (!StringUtils.checkValNull(idVal) && !Objects.isNull(this.getById((Serializable)idVal))) {
                        ParamMap<T> param = new ParamMap();
                        param.put("et", anEntityList);
                        batchSqlSession.update(this.sqlStatement(SqlMethod.UPDATE_BY_ID), param);
                    } else {
                        batchSqlSession.insert(this.sqlStatement(SqlMethod.INSERT_ONE), anEntityList);
                    }

                    if (i >= 1 && i % batchSize == 0) {
                        batchSqlSession.flushStatements();
                    }

                    ++i;
                    batchSqlSession.flushStatements();
                }
            } catch (Throwable var19) {
                var7 = var19;
                throw var19;
            } finally {
                if (batchSqlSession != null) {
                    if (var7 != null) {
                        try {
                            batchSqlSession.close();
                        } catch (Throwable var18) {
                            var7.addSuppressed(var18);
                        }
                    } else {
                        batchSqlSession.close();
                    }
                }

            }

            return true;
        }
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean removeById(Serializable id) {
        return SqlHelper.delBool(this.baseMapper.deleteById(id));
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean removeByMap(Map<String, Object> columnMap) {
        if (ObjectUtils.isEmpty(columnMap)) {
            throw ExceptionUtils.mpe("removeByMap columnMap is empty.", new Object[0]);
        } else {
            return SqlHelper.delBool(this.baseMapper.deleteByMap(columnMap));
        }
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean remove(Wrapper<T> wrapper) {
        return SqlHelper.delBool(this.baseMapper.delete(wrapper));
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        return SqlHelper.delBool(this.baseMapper.deleteBatchIds(idList));
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean updateById(T entity) {
        return this.retBool(this.baseMapper.updateById(entity));
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean update(T entity, Wrapper<T> updateWrapper) {
        return this.retBool(this.baseMapper.update(entity, updateWrapper));
    }

    @Transactional(
        rollbackFor = {Exception.class}
    )
    public boolean updateBatchById(Collection<T> entityList, int batchSize) {
        if (CollectionUtils.isEmpty(entityList)) {
            throw new IllegalArgumentException("Error: entityList must not be empty");
        } else {
            int i = 0;
            String sqlStatement = this.sqlStatement(SqlMethod.UPDATE_BY_ID);
            SqlSession batchSqlSession = this.sqlSessionBatch();
            Throwable var6 = null;

            try {
                for(Iterator var7 = entityList.iterator(); var7.hasNext(); ++i) {
                    T anEntityList = var7.next();
                    ParamMap<T> param = new ParamMap();
                    param.put("et", anEntityList);
                    batchSqlSession.update(sqlStatement, param);
                    if (i >= 1 && i % batchSize == 0) {
                        batchSqlSession.flushStatements();
                    }
                }

                batchSqlSession.flushStatements();
                return true;
            } catch (Throwable var17) {
                var6 = var17;
                throw var17;
            } finally {
                if (batchSqlSession != null) {
                    if (var6 != null) {
                        try {
                            batchSqlSession.close();
                        } catch (Throwable var16) {
                            var6.addSuppressed(var16);
                        }
                    } else {
                        batchSqlSession.close();
                    }
                }

            }
        }
    }

    public T getById(Serializable id) {
        return this.baseMapper.selectById(id);
    }

    public Collection<T> listByIds(Collection<? extends Serializable> idList) {
        return this.baseMapper.selectBatchIds(idList);
    }

    public Collection<T> listByMap(Map<String, Object> columnMap) {
        return this.baseMapper.selectByMap(columnMap);
    }

    public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
        return throwEx ? this.baseMapper.selectOne(queryWrapper) : SqlHelper.getObject(this.baseMapper.selectList(queryWrapper));
    }

    public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
        return (Map)SqlHelper.getObject(this.baseMapper.selectMaps(queryWrapper));
    }

    public int count(Wrapper<T> queryWrapper) {
        return SqlHelper.retCount(this.baseMapper.selectCount(queryWrapper));
    }

    public List<T> list(Wrapper<T> queryWrapper) {
        return this.baseMapper.selectList(queryWrapper);
    }

    public IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper) {
        return this.baseMapper.selectPage(page, queryWrapper);
    }

    public List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper) {
        return this.baseMapper.selectMaps(queryWrapper);
    }

    public List<Object> listObjs(Wrapper<T> queryWrapper) {
        return (List)this.baseMapper.selectObjs(queryWrapper).stream().filter(Objects::nonNull).collect(Collectors.toList());
    }

    public IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper) {
        return this.baseMapper.selectMapsPage(page, queryWrapper);
    }
}

Wrapper条件查询器

它可以实现很多复杂的查询
参考
https://www.cnblogs.com/kzyuan/p/12706600.html

   @Autowired(required = false)
    private UserMapper userMapper;
    @Autowired
    private IUserService iUserService;
    /**
     * 以前默认是叫EntityWrapper,现在叫QueryWrapper
     */

    /**
     * 根据条件查询
     */
    @Test
    public void select(){
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.isNotNull("name") //name不为空的用户
        .isNotNull("email") //邮箱不为空
        .ge("age",12); //年龄大于等于12

        List<User> list=userMapper.selectList(wrapper);
        System.out.println(list);
    }

    /**
     * 根据名字查询
     */
    @Test
    public void selectName(){
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.eq("name","ting");
        List<User> list=userMapper.selectList(wrapper);
        System.out.println(list);
    }
    /**
     *  查询 1020 岁的用户数
     */
    @Test
    public void selectByAge(){
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.between("age",10,21);

        List<User> list=userMapper.selectList(wrapper);
        System.out.println(list);


    }
    /**
     * 模糊查询
     */
    @Test
    public void selectLike(){
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper
                .notLike("name","2")
                .like("name","t")
                //右查询
                .likeRight("email","234");
        List<Map<String,Object>> users=userMapper.selectMaps(wrapper);
        System.out.println(users);

    }

    /**
     * 子查询
     */
    @Test
    public void selectLike2(){
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.inSql("id","select id from user where age<21");
        List<Object> users=userMapper.selectObjs(wrapper);
        System.out.println(users);
    }

    /**
     * 排序
     */
    @Test
    public void selectByOrder(){
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        //降序排序
        wrapper.orderByDesc("id");

        List<User> users=userMapper.selectList(wrapper);
        System.out.println(users);
    }
    /**
     * 部分字段更新
     */
    @Test
    public void update(){
        UpdateWrapper<User> wrapper=new UpdateWrapper<>();
        User user=new User();
        //更新字段
        wrapper.set("name","xyz");
        wrapper.eq("id",1321972874844389378L);
        System.out.println("更新结果:"+iUserService.update(user,wrapper));
    }

分页
需要新建一个配置类

@Configuration
@MapperScan("com.king.mapper")
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        //paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}

测试代码:

	/**
     * 分页
     */
    @Test
    public void page(){
        //当前页1,每页大小2
        IPage<User> userIPage=new Page<>(1,1);
        userIPage=userMapper.selectPage(userIPage,null);
        List<User> list=userIPage.getRecords();
        System.out.println(list);
    }

多表查询

看了一下网上说mybatis-plus不支持多表操作,这就麻烦了,不然mybatis-plus有啥用呢,虽然说网上也有方法,但是我不想用,感觉比较麻烦吧,大家可以自己选择。

现在来看看吧,我们可以用这个代码自动生成器,生成对应的代码,然后在其基础上进行修改就好了,毕竟单表的基本操作他都做好了,多表我们就自己写呗,还是省了不少事的

sql语句:

create TABLE user(
  user_id INT PRIMARY KEY AUTO_INCREMENT,
	user_name VARCHAR(100),
	sex_id Int
)


create TABLE sex(
  sex_id INT PRIMARY KEY AUTO_INCREMENT,
	sex_name VARCHAR(100)
)

insert into user(user_name,sex_id) VALUES("king",1);
insert into user(user_name,sex_id) VALUES("ting",2);
insert into user(user_name,sex_id) VALUES("aaa",1);

insert into sex(sex_name) VALUES("男");
insert into sex(sex_name) VALUES("女");
insert into sex(sex_name) VALUES("变态");

1、配置文件和自动生成代码配置器文件也和上面一样的,结构如下:
在这里插入图片描述

2、运行自动生成代码器,输入多个表名
在这里插入图片描述
4、首先需要对实体类进行修改
在这里插入图片描述
这个外键改成他对应的实体类就好了,并且上面需要加上注解,表明映射结果到哪里
在这里插入图片描述

sex类也要进行修改,如果需要的话

5、修改xml文件,映射关系改一下
在这里插入图片描述
6、就OK了,就可以使用了,如果需要自定义sql,自己在mapper中添加就是了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java后端指南

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值