技术联盟

MyBatis及MyBatisPlus简单使用

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>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </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.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
      
      <!-- 下面这个mysbatis-plus-boot-starter是配置Mybatis和MybatisPlus的依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.13</version>
        </dependency>
    </dependencies>

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

</project>

配置properties文件

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日志文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
    <contextName>logback</contextName>
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <property name="LOG_HOME" value="log" />
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>
    <!-- 按照每天生成日志文件 -->
    <appender name="FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/mybatis.%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <!--<MaxHistory>30</MaxHistory>-->
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>


    <!--myibatis log configure-->
    <logger name="com.apache.ibatis" level="TRACE"/>
    <!--<logger name="org.mybatis" level="DEBUG"/>-->
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
    <!--这里根据自己的数据库映射Mapper配置-->
    <logger name="com.zdltech.test.mybatis.mapper" level="DEBUG"/>

    <!-- 日志输出级别 -->
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
    <!--日志异步到数据库 -->
    <!--<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">-->
    <!--<!–日志异步到数据库 –>-->
    <!--<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">-->
    <!--<!–连接池 –>-->
    <!--<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">-->
    <!--<driverClass>com.mysql.jdbc.Driver</driverClass>-->
    <!--<url>jdbc:mysql://127.0.0.1:3306/databaseName</url>-->
    <!--<user>root</user>-->
    <!--<password>root</password>-->
    <!--</dataSource>-->
    <!--</connectionSource>-->
    <!--</appender>-->
</configuration>

第二步配置Mybatis

配置MyBatisConfig

创建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表示映射的数据库的表的名称–注意要是mybatisplus下的注解哦

@TableId是数据库表中主键对应的注解

@TableField是数据库中标字段

大伙可能看到 我有的添加@TableField有的没有添加,是因为默认情况下 字段的名称和数据一样的时候可以不用写

但是默认情况下你如果没有添加@TableField的时候 你写成nickName 对应数据库字段为 nick_name

其他需求例如某个字段不想作为数据库字段的时候(https://mybatis.plus/guide/annotation.html#tablefield) 更多 请参考mybatisplus官网https://mp.baomidou.com/

https://mybatis.plus

配置Mapper

这里更简单 只要创建接口继承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<UserEntity> {
}

不要忘记添加@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<UserEntity> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);
        Assert.assertEquals(5,5);
        Wrapper<UserEntity> wrapper = new QueryWrapper();

    }

}

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

配置Mybatis

实际上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)

generator帮助我们快速生成对应的Mapper的XMl文件

配置pom.xml中的build下的plugins

<plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.3.7</version>
    <configuration>
        <configurationFile>
            mybatis-generator/generatorConfig.xml
        </configurationFile>
        <overwrite>true</overwrite>
        <verbose>true</verbose>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
    </dependencies>
</plugin>

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" />
      
        <property name="autoDelimitKeywords" value="true"/>
        <!--可以使用``包括字段名,避免字段名与sql保留字冲突报错-->
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>

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

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

        <!--数据库连接信息-->
        <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"/>

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

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

/*
   <columnOverride column="ids" javaType="java.lang.Integer[]" typeHandler="JsonIntegerArrayTypeHandler"/>
 */
public class JsonIntegerArrayTypeHandler extends BaseTypeHandler<Integer[]> {
    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

配置完上面之后,需要我们执行mybatis的maven插件了

执行mybatis-generator:generate等待相关数据生成

Share this:

码字很辛苦,转载请注明来自技术联盟《MyBatis及MyBatisPlus简单使用》

评论