MyBatis及MyBatisPlus简单使用

在做java开发的时候,我们经常会使用Mybatis来作为我们操作数据库的工具库,今天一步步带领大家集成到Spring boot中,本篇主要实现Spring boot+mybatis+MybatisPlus的基础使用

第一步创建Spring boot项目

大家使用自己熟悉的开发工具创建Spring boot项目。例如Idea、eclipse及SpringToolSuite4等工具,这里默认大家都已成功创建Springboot项目

配置pom.xml

这里使用的是mysql,大家根据自己情况配置相关的数据源

pom.xm

`<?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.1.8.RELEASE</version> <relativePath/> <!– lookup parent from repository –> </parent> <groupId>com.zdltech.test</groupId> <artifactId>mybatis</artifactId> <version>0.0.1-SNAPSHOT</version> <name>mybatis</name> <description>mybatis的测试</description>

&lt;properties&gt;
    &lt;java.version&gt;1.8&lt;/java.version&gt;
&lt;/properties&gt;

&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-jdbc&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-thymeleaf&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.mybatis.spring.boot&lt;/groupId&gt;
        &lt;artifactId&gt;mybatis-spring-boot-starter&lt;/artifactId&gt;
        &lt;version&gt;2.1.0&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
        &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;mysql&lt;/groupId&gt;
        &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
        &lt;scope&gt;runtime&lt;/scope&gt;
    &lt;/dependency&gt;
  
  &lt;!-- 下面这个mysbatis-plus-boot-starter是配置Mybatis和MybatisPlus的依赖--&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;com.baomidou&lt;/groupId&gt;
        &lt;artifactId&gt;mybatis-plus-boot-starter&lt;/artifactId&gt;
        &lt;version&gt;3.1.0&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
        &lt;artifactId&gt;lombok&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;com.alibaba&lt;/groupId&gt;
        &lt;artifactId&gt;druid-spring-boot-starter&lt;/artifactId&gt;
        &lt;version&gt;1.1.13&lt;/version&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;

&lt;build&gt;
    &lt;plugins&gt;
        &lt;plugin&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
        &lt;/plugin&gt;
    &lt;/plugins&gt;
&lt;/build&gt;

</project> `


#### 配置properties文件 {#toc_3}

> ```
`server.port=18899
server.servlet.context-path=/
mybatis-plus.mapper-locations=classpath:/mapper/*Mapper.xml

spring.datasource.druid.url=jdbc:mysql://xxxxx:3306/xxxx?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true&verifyServerCertificate=false&useSSL=false
spring.datasource.druid.username=root
spring.datasource.druid.password=root
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.initial-size=10
spring.datasource.druid.max-active=50
spring.datasource.druid.min-idle=10
spring.datasource.druid.max-wait=60000
spring.datasource.druid.pool-prepared-statements=true
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
spring.datasource.druid.validation-query= select 1 from dual
spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false
spring.datasource.druid.test-while-idle=false
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.filters=stat,wall

# mybatis日志配置
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
logging.level.com.zdltech.test.mybatis.mapper=debug
`

配置logback日志文件

``


### 第二步配置Mybatis {#toc_5}

#### 配置MyBatisConfig {#toc_6}

> 创建MybatisPlus的配置文件
> 
> ```
`import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("这里是你的Mapper对应的包名")
public class MyBatisConfig {//实际上里面什么都不需要配置就可以,这里主要配置MapperScan
}
`

创建业务实体Entity

根据自己的业务需求创建业务实体(程序员都知道,就是普通 的JavaBean,但是里面要有MybatisPlus的关于表的注解)

`

import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data;

import java.util.Date;

@Data @TableName(“sys_user”) public class UserEntity { @TableId(value = “id”) private Long userId; @TableField(“username”) private String userName; @TableField(“nickname”) private String nickName; @TableField(“password”) private String password; private String salt; private Long deptId; private String picture; private String sex; private String email; private String phone; private String remark; private Date createDate; private Date updateDate; private int status; }

`

> 
> @Data是为了省去写javabean中get和set方法
> 
> @TableName表示映射的数据库的表的名称&#8211;注意要是mybatisplus下的注解哦
> 
> @TableId是数据库表中主键对应的注解
> 
> @TableField是数据库中标字段
> 
> 大伙可能看到 我有的添加@TableField有的没有添加,是因为默认情况下 字段的名称和数据一样的时候可以不用写
> 
> 但是默认情况下你如果没有添加@TableField的时候 你写成nickName 对应数据库字段为 nick_name
> 
> 其他需求例如某个字段不想作为数据库字段的时候(<https://mybatis.plus/guide/annotation.html#tablefield>) 更多 请参考mybatisplus官网<https://mp.baomidou.com/> 
> 
> [https://mybatis.plus][1]

#### 配置Mapper {#toc_8}

> 这里更简单 只要创建接口继承BaseMapper 就实现 了相关数据库的 增删改查等功能
> 
> ```
`import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zdltech.test.mybatis.domain.UserEntity;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;

@Component
public interface UserMapper extends BaseMapper&lt;UserEntity&gt; {
}
`

不要忘记添加@Component注解哦,让Spring管理实体对象

引入的BaseMapper要是mybatisplus包下的

测试mybatisplus是否成功配置完成

到此简单的配置MybatisPlus完成

`import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.zdltech.test.mybatis.domain.UserEntity; import com.zdltech.test.mybatis.mapper.UserMapper; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class) @SpringBootTest public class MybatisApplicationTests { @Autowired private UserMapper userMapper;

@Test
public void contextLoads() {
}

@Test
public void testSelect(){
    System.out.println("-----------Select All Data-----------");
    List&lt;UserEntity&gt; userList = userMapper.selectList(null);
    userList.forEach(System.out::println);
    Assert.assertEquals(5,5);
    Wrapper&lt;UserEntity&gt; wrapper = new QueryWrapper();

}

} `

> 
> 运行下测试类 如果能正常打印出来数据库中的数据,表示整个mybatisplus的配置正确完成

### 配置Mybatis {#toc_10}

> 实际上MybatisPlus是对Mybatis的扩展,完全兼容Mybatis的相关操作,所以我们可以通过Mybatisplus快速实现我们的增删改查的单表操作,相对复杂的已查询我们还是习惯使用Mybatis的sql语句
> 
> 下面我们配置下Mybatis
> 
> 需要在properties文件中配置
> 
>     mybatis.config-location=classpath:mybatis-config.xml
>     mybatis.type-aliases-package=对应的实体包
>     mybatis.mapper-locations=classpath:mybatis/*.xml
>     

#### 配置mybatis-gennerator(mybatis-generator-maven-plugin) {#toc_11}

> generator帮助我们快速生成对应的Mapper的XMl文件
> 
> 配置pom.xml中的build下的plugins
> 
> ```
`&lt;plugin&gt;
    &lt;groupId&gt;org.mybatis.generator&lt;/groupId&gt;
    &lt;artifactId&gt;mybatis-generator-maven-plugin&lt;/artifactId&gt;
    &lt;version&gt;1.3.7&lt;/version&gt;
    &lt;configuration&gt;
        &lt;configurationFile&gt;
            mybatis-generator/generatorConfig.xml
        &lt;/configurationFile&gt;
        &lt;overwrite&gt;true&lt;/overwrite&gt;
        &lt;verbose&gt;true&lt;/verbose&gt;
    &lt;/configuration&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;mysql&lt;/groupId&gt;
            &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
            &lt;version&gt;5.1.46&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/plugin&gt;
`

generatorCofig.xml 配置,通过Maven插件生成Mapper xml

`<?xml version=“1.0” encoding=“UTF-8”?> <!DOCTYPE generatorConfiguration PUBLIC “-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN” “http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration> <!–导入属性配置,前面我们写的一个配置文件,你也可以直接使用mybatis的jdbc的配置文件 –> <!–<properties resource=“application.properties”></properties>–> <!– 数据库驱动,注意,这里必须要修改成你的数据库的驱动地址, 如果在plugin中添加依赖的话不需要设置这个–> <!–<classPathEntry location=“C:\Users\Administrator.m2\repository\mysql\mysql-connector-java\8.0.15\mysql-connector-java-8.0.15.jar”/>–> <context id=“mysqlgenerator” targetRuntime=“MyBatis3”> <!–覆盖生成XML文件–> <plugin type=“org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin” />

    &lt;property name="autoDelimitKeywords" value="true"/&gt;
    &lt;!--可以使用``包括字段名,避免字段名与sql保留字冲突报错--&gt;
    &lt;property name="beginningDelimiter" value="`"/&gt;
    &lt;property name="endingDelimiter" value="`"/&gt;

    &lt;!-- 自动生成toString方法 --&gt;
    &lt;plugin type="org.mybatis.generator.plugins.ToStringPlugin"/&gt;
    &lt;!-- 自动生成equals方法和hashcode方法 --&gt;
    &lt;plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/&gt;

    &lt;!-- 非官方插件 https://github.com/itfsw/mybatis-generator-plugin --&gt;
    &lt;!-- 查询单条数据插件 --&gt;
    &lt;plugin type="com.itfsw.mybatis.generator.plugins.SelectOneByExamplePlugin"/&gt;
    &lt;!-- 查询结果选择性返回插件 --&gt;
    &lt;plugin type="com.itfsw.mybatis.generator.plugins.SelectSelectivePlugin"/&gt;
    &lt;!-- Example Criteria 增强插件 --&gt;
    &lt;plugin type="com.itfsw.mybatis.generator.plugins.ExampleEnhancedPlugin"/&gt;
    &lt;!-- 数据Model属性对应Column获取插件 --&gt;
    &lt;plugin type="com.itfsw.mybatis.generator.plugins.ModelColumnPlugin"/&gt;
    &lt;!-- 逻辑删除插件 --&gt;
    &lt;plugin type="com.itfsw.mybatis.generator.plugins.LogicalDeletePlugin"&gt;
        &lt;!-- 这里配置的是全局逻辑删除列和逻辑删除值,当然在table中配置的值会覆盖该全局配置 --&gt;
        &lt;!-- 逻辑删除列类型只能为数字、字符串或者布尔类型 --&gt;
        &lt;property name="logicalDeleteColumn" value="deleted"/&gt;
        &lt;!-- 逻辑删除-已删除值 --&gt;
        &lt;property name="logicalDeleteValue" value="1"/&gt;
        &lt;!-- 逻辑删除-未删除值 --&gt;
        &lt;property name="logicalUnDeleteValue" value="0"/&gt;
    &lt;/plugin&gt;
  &lt;!--代码上面的注释规则--&gt;
    &lt;commentGenerator&gt;
       &lt;!--false时打开时间标志,true时关闭.--&gt;
        &lt;property name="suppressDate" value="true"/&gt;
        &lt;!-- 是否去除自动生成的注释 true:是 : false:否 --&gt;
        &lt;!--&lt;property name="suppressAllComments" value="true"/&gt;--&gt;
    &lt;/commentGenerator&gt;

    &lt;!--数据库连接信息--&gt;
    &lt;jdbcConnection driverClass="com.mysql.jdbc.Driver"
                    connectionURL="jdbc:mysql://127.0.0.1:3306/xxxxx?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC&amp;verifyServerCertificate=false&amp;useSSL=false"
                    userId="root"
                    password="root"/&gt;

    &lt;!-- 在javaTypeResolver结点中加入属性useJSR310Types,当useJSR310Types为true时,就会jdbc对应的日期类型会转成java8中的LocateDateTime类型,如果useJSR310Types为false,则还是转成java.util.Date类型 --&gt;
    &lt;javaTypeResolver&gt;
        &lt;property name="useJSR310Types" value="false"/&gt;
      &lt;!--  true生成之后的实体中number类型转换成JAVA类型还是会被转换为BigDecimal类型。 --&gt;
      &lt;!-- &lt;property name="forceBigDecimals" value="false"/&gt;--&gt;
    &lt;/javaTypeResolver&gt;

      &lt;javaModelGenerator targetPackage="实体包名位置" targetProject="src/main/java"&gt;
        &lt;!-- enableSubPackages:是否让schema作为包的后缀 --&gt;
            &lt;property name="enableSubPackages" value="true"/&gt;
        &lt;!-- 从数据库返回的值被清理前后的空格 --&gt;
        &lt;property name="trimStrings" value="true"/&gt;
      &lt;/javaModelGenerator&gt;
    &lt;sqlMapGenerator targetPackage="mapper对应目录" targetProject="src/main/resources"&gt;
          &lt;!-- enableSubPackages:是否让schema作为包的后缀 --&gt;
            &lt;property name="enableSubPackages" value="true"/&gt;
    &lt;/sqlMapGenerator&gt;
    &lt;javaClientGenerator type="XMLMAPPER" targetPackage="Mapper对应的包名"
                         targetProject="src/main/java"&gt;
            &lt;!-- enableSubPackages:是否让schema作为包的后缀 --&gt;
            &lt;property name="enableSubPackages" value="true"/&gt;
     &lt;/javaClientGenerator&gt;
      &lt;!---表名 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名,这里举例,只配置了一个table,你可以配置多个--&gt;
    &lt;table tableName="litemall_ad"&gt;
        &lt;generatedKey column="id" sqlStatement="MySql" identity="true"/&gt;
    &lt;/table&gt;
    &lt;table tableName="litemall_admin"&gt;
        &lt;generatedKey column="id" sqlStatement="MySql" identity="true"/&gt;
        &lt;columnOverride column="role_ids" javaType="java.lang.Integer[]"
                        typeHandler="org.linlinjava.litemall.db.mybatis.JsonIntegerArrayTypeHandler"/&gt;
    &lt;/table&gt;
    &lt;!--        &lt;table tableName="tb_apr_count" enableCountByExample="false"
           enableUpdateByExample="false"
           enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/&gt;--&gt;
&lt;/context&gt;

</generatorConfiguration> `

> 
> ```
`JsonIntegerArrayTypeHandler

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/*
   &lt;columnOverride column="ids" javaType="java.lang.Integer[]" typeHandler="JsonIntegerArrayTypeHandler"/&gt;
 */
public class JsonIntegerArrayTypeHandler extends BaseTypeHandler&lt;Integer[]&gt; {
    private static final ObjectMapper mapper = new ObjectMapper();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Integer[] parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, toJson(parameter));
    }

    @Override
    public Integer[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return this.toObject(rs.getString(columnName));
    }

    @Override
    public Integer[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return this.toObject(rs.getString(columnIndex));
    }

    @Override
    public Integer[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return this.toObject(cs.getString(columnIndex));
    }

    private String toJson(Integer[] params) {
        try {
            return mapper.writeValueAsString(params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "[]";
    }

    private Integer[] toObject(String content) {
        if (content != null && !content.isEmpty()) {
            try {
                return (Integer[]) mapper.readValue(content, Integer[].class);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            return null;
        }
    }
}
`
JsonStringArrayTypeHandler

`import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;

/* <columnOverride column=“urls” javaType=“java.lang.String[]” typeHandler=“JsonStringArrayTypeHandler”/> */ public class JsonStringArrayTypeHandler extends BaseTypeHandler<String[]> { private static final ObjectMapper mapper = new ObjectMapper();

@Override
public void setNonNullParameter(PreparedStatement ps, int i, String[] parameter, JdbcType jdbcType) throws SQLException {
    ps.setString(i, toJson(parameter));
}

@Override
public String[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
    return this.toObject(rs.getString(columnName));
}

@Override
public String[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    return this.toObject(rs.getString(columnIndex));
}

@Override
public String[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return this.toObject(cs.getString(columnIndex));
}

private String toJson(String[] params) {
    try {
        return mapper.writeValueAsString(params);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "[]";
}

private String[] toObject(String content) {
    if (content != null && !content.isEmpty()) {
        try {
            return (String[]) mapper.readValue(content, String[].class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    } else {
        return null;
    }
}

} `

> 
> 关于BaseTypeHandler还可以参数  
> <https://www.cnblogs.com/wangjuns8/p/8688815.html>
> 
> <https://www.jianshu.com/p/6172c7f6e27e>
> 
> 如果使用到了自定义的TypeHandler 需要在mybatis生成的mapper.xml文件中 resultMap中的对应字段中添加typeHandler
> 
> 例如:
> 
>     <result column="specifications" jdbcType="VARCHAR" property="specifications" typeHandler="org.linlinjava.litemall.db.mybatis.JsonStringArrayTypeHandler" />
>     

#### 执行Maven plugin下的mybatis-generaor {#toc_13}

> 配置完上面之后,需要我们执行mybatis的maven插件了
> 
> 执行mybatis-generator:generate等待相关数据生成

 [1]: https://mybatis.plus/