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日志文件
第二步配置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/
配置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&characterEncoding=UTF-8&serverTimezone=UTC&verifyServerCertificate=false&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.htmlhttps://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等待相关数据生成