Springboot整合(2)——MyBatis整合
Springboot整合(2)——MyBatis整合
1. 配置
1. 1 在pom文件中添加依赖
<!-- mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Mybatis 包-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<!-- Mybatis代码自动生成-->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
1.2 在application.yml文件中增加数据库和mybatis的配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/knowledgeisland?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
mybatis:
##配置mapper.xml扫描路径
mapper-locations: classpath:mapper/*Mapper.xml,classpath:mapper/auto/*Mapper.xml
##配置实体类所在的包
type-aliases-package: tect.luoyu.ki.entity
1.3 在启动类Application里配置mapper接口的扫描路径
@MapperScan("tech.luoyu.ki.mapper")
2. 使用mybatis-generator生成代码
mybatis官方提供的代码生成工具可以为我们自动生成entity,mapper接口类以及mapper.xml。 本节将使用基类产生相应的代码。
2.1 创建表并插入一条数据
CREATE TABLE `sys_user` (
`id` varchar(36) NOT NULL COMMENT '主键uuid',
`userName` varchar(30) NOT NULL COMMENT '用户名',
`mobilephone` varchar(11) DEFAULT NULL COMMENT '联系电话',
`loginName` varchar(30) NOT NULL COMMENT '登录账号',
`loginPassword` varchar(50) NOT NULL COMMENT '登录密码',
`creater` varchar(36) NOT NULL COMMENT '创建人',
`createTime` datetime NOT NULL,
`updater` varchar(36) NOT NULL COMMENT '更新人',
`updateTime` datetime NOT NULL,
`dataStatus` tinyint(4) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `sys_user` VALUES ('1', '风木羽', '18666666666', 'admin', 'admin', '1', '2018-01-01 10:52:00', '1', '2018-01-01 10:52:00', '1');
2.2 创建基类,基类包含以下6个基本属性(具体情况按需)。
private String id;
private String creater;
private Date createTime;
private String updater;
private Date updateTime;
private Byte dataStatus;
...getter,setter,toString,equals,hashCode...
注:创建基类的目的在于可以为所有的entity对象添加一些通用方法,如preInsert(插入前做预插入工作:生成ID,设置creater,设置createTime),preUpdate(更新前做预更新工作:生成ID,设置updater,设置updateTime)
publicvoid preInsert() {
setId(UUID.randomUUID().toString());
this.updater = "1";
this.creater = "1";
this.updateTime = new Date();
this.createTime = this.updateTime;
bytedataStatus = 1;
setDataStatus(dataStatus);
}
publicvoid preUpdate() {
this.updater = "1";
this.updateTime = new Date();
}
2.3 创建generatorConfig.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>
<!-- 指定生成一组对象的环境 -->
<context id="mysql" targetRuntime="MyBatis3">
<!-- 自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表;
一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖
-->
<property name="autoDelimitKeywords" value="false"/>
<!-- 生成的Java文件的编码 -->
<property name="javaFileEncoding" value="UTF-8"/>
<!-- 格式化java代码 -->
<property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
<!-- 格式化XML代码 -->
<property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>
<!-- beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,比如ORACLE就是双引号,MYSQL默认是`反引号; -->
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<!-- 这个plugin是手写的一个用于生成hibernate校验注释的插件,会在下文说明其效果 -->
<plugin type="tech.luoyu.ki.generator.JSR303Plugin"></plugin>
<!-- generate entity时,生成serialVersionUID -->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"></plugin>
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"></plugin>
<plugin type="org.mybatis.generator.plugins.CaseInsensitiveLikePlugin"></plugin>
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是: false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/knowledgeisland"
userId="root"
password="root">
</jdbcConnection>
<!-- 定义Java类型解析器的属性 -->
<javaTypeResolver >
<!-- 指定MyBatis发生器是否应该强迫java.math的使用。BigDecimal十进制数值字段,而不是代替积分类型 -->
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 定义属性的Java模型生成器;包生成的类将被放置的地方;指定一个目标项目生成的对象 -->
<javaModelGenerator targetPackage="tech.luoyu.ki.entity.auto" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
<property name="immutable" value="false"/>
<property name="trimStrings" value="true" />
<!-- 设置entity的基类 -->
<property name="rootClass" value="tech.luoyu.ki.entity.BaseEntity"/>
</javaModelGenerator>
<!-- 定义SQL映射生成器的属性 -->
<sqlMapGenerator targetPackage="mapper.auto" targetProject="src/main/resources"><!-- 放置生成的SQL映射文件;指定生成SQL映射的目标项目 -->
<!-- 选择MGB是否根据基于目录和内省表来生成不同的Java包 -->
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 定义 Java 客户端代码生成器的属性;放置生成的接口和实现类;指定生成接口和类的目标项目 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="tech.luoyu.ki.mapper.auto" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 选择一个table来生成相关文件。必须要有table元素;tableName(必要):要生成对象的表名-->
<table schema="" tableName="sys_%">
<property name="useActualColumnNames" value="true"/>
</table>
</context>
</generatorConfiguration>
注:红色字体为重点和需要按实际分包修改的内容,注意包名需要与1.2和1.3配置的内容一致,本章末尾会给出当前已分包的结构目录截图
附:JSR303Plugin类的代码
package tech.luoyu.ki.generator;
import java.sql.Types;
import java.util.List;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.TopLevelClass;
publicclass JSR303Plugin extends PluginAdapter {
@Override
publicboolean validate(List<String> warnings) {
returntrue;
}
@Override
publicboolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
IntrospectedTable introspectedTable, ModelClassType modelClassType) {
if (true == introspectedColumn.isStringColumn()) {
if (false == introspectedColumn.isNullable()) {
topLevelClass.addImportedType("org.hibernate.validator.constraints.NotBlank");
field.addAnnotation("@NotBlank");
}
topLevelClass.addImportedType("javax.validation.constraints.Size");
field.addAnnotation(
"@Size(min = 0, max = " + introspectedColumn.getLength() + " , message = \"长度必须在{min}和{max}之间\")");
}
if (introspectedColumn.getJdbcType() == Types.INTEGER) {
if (false == introspectedColumn.isNullable()) {
topLevelClass.addImportedType("javax.validation.constraints.NotNull");
field.addAnnotation("@NotNull");
}
topLevelClass.addImportedType("javax.validation.constraints.Max");
field.addAnnotation("@Max(value=2147483647,message=\"最大值不能高于{value}\")");
topLevelClass.addImportedType("javax.validation.constraints.Min");
field.addAnnotation("@Min(value=-2147483648,message=\"最小值不能低于{value}\")");
}
returnsuper.modelFieldGenerated(field, topLevelClass, introspectedColumn, introspectedTable, modelClassType);
}
}
2.4 编写生成代码类:Generator.java,该类里用到一个FileTool工具类,就是一个删除文件夹和删除文件的功能,此处就不贴出代码了
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package tech.luoyu.ki.generator;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;
import tech.luoyu.ki.util.FileTool;
public class Generator {
public static void main(String[] args) {
generate();
}
@SuppressWarnings(value = "all")
private static void generate() {
String singleFileName = null;// single
// singleFileName = "SysUserMapper.xml";
// 1. 删除已经存在的mapper.xml
File file = new File(Generator.class.getResource("/").getFile());
File parentFile = file.getParentFile().getParentFile();
String autoMapperRelativePath = "src\\main\\resources\\mapper\\auto";
File autoMapperFile = new File(parentFile.getAbsolutePath() + File.separator + autoMapperRelativePath);
System.out.println(autoMapperFile.getAbsolutePath());
System.out.println(autoMapperFile.exists());
if (singleFileName == null) {
if (autoMapperFile.exists()) {
FileTool.delDir(autoMapperFile.getAbsolutePath(), true);
}
autoMapperFile.mkdirs();
} else {
autoMapperFile = new File(parentFile.getAbsolutePath() + File.separator + autoMapperRelativePath
+ File.separator + singleFileName);
if (autoMapperFile.exists()) {
FileTool.delFile(autoMapperFile.getAbsolutePath());
}
}
// 2. 重新生成mapper.xml
try {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
ConfigurationParser cp = new ConfigurationParser(warnings);
InputStream stream = Generator.class.getClassLoader().getResourceAsStream("generatorConfig.xml");
Configuration config = cp.parseConfiguration(stream);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
} catch (IOException ex) {
Logger.getLogger(Generator.class.getName()).log(Level.SEVERE, null, ex);
} catch (XMLParserException ex) {
Logger.getLogger(Generator.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidConfigurationException ex) {
Logger.getLogger(Generator.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Generator.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(Generator.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("代码生成完毕");
}
}
2.5 运行generator类,可以看到entity(且为每个entity生成了example),mapper接口,mapper.xml都已经生成
生成的entity里红框内容就是上文中提到的JSR303Plugin插件产生的内容,JSR303Plugin插件内的内容可以自己定制,本文的代码只对String和int做了处理
3. 测试
3.1 在controller里注入mapper,并添加映射方法,这里只是简单测试,就省略service层,直接在controller里调用mapper了
@Resource
SysUserMapper userMapper;
@RequestMapping(value = "user/list")
public ModelAndView showUsers() {
Map<String, Object> model = new HashMap<String, Object>();
model.put("user", userMapper.selectByPrimaryKey("1"));
returnnew ModelAndView("user/list", model);
}
3.2 编写user/list.jsp
<body>
${user.userName }
${user.mobilePhone }
</body>
3.3 运行测试,正常