5-5 使用Springboot版mybatis逆向生成工具
将数据库中的表反向生成pojo,数据库中的实体类,另外还要生成mybatis的相关配置文件。
首先查看开源的mirrors / abel533 / mybatis-spring-boot
参考文件,镜像地址链接
MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。
MyBatis是一个基于Java的持久层框架。MyBatis提供的持久层框架包括SQL Maps和Data Access Objects(DAO),它消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version><!--$NO-MVN-MAN-VER$-->
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<!--mapper-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>1.2.4</version>
</dependency>
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
在使用 DevTools 时,通用Mapper经常会出现 class x.x.A cannot be cast to x.x.A。
同一个类如果使用了不同的类加载器,就会产生这样的错误,所以解决方案就是让通用Mapper和实体类使用相同的类加载器即可。
DevTools 默认会对 IDE 中引入的所有项目使用 restart 类加载器,对于引入的 jar 包使用 base 类加载器,因此只要保证通用Mapper的jar包使用 restart
类加载器即可。
在 src/main/resources
中创建 META-INF 目录,在此目录下添加 spring-devtools.properties
配置,内容如下:
restart.include.mapper=/mapper-[\\w-\\.]+jar
restart.include.pagehelper=/pagehelper-[\\w-\\.]+jar
############################################################
#
# 配置数据源相关 使用阿里巴巴的 druid 数据源
#
############################################################
spring.datasource.url=jdbc:mysql://localhost:3306/springbootjpa?useSSL=false&serverTimezone=UTC&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.initial-size=1
spring.datasource.druid.min-idle=1
spring.datasource.druid.max-active=20
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.stat-view-servlet.allow=true
#mybatis
mybatis.type-aliases-package=tk.mybatis.springboot.model
mybatis.mapper-locations=classpath:mapper/*.xml
#mapper
#mappers 多个接口时逗号隔开
mapper.mappers=tk.mybatis.springboot.util.MyMapper
mapper.not-empty=false
mapper.identity=MYSQL
#pagehelper
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql
<?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="MysqlContext" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<plugin type="tk.mybatis.mapper.generator.MapperPlugin">
<property name="mappers" value="com.imooc.utils.MyMapper"/>
</plugin>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/springbootjpa?useSSL=false&serverTimezone=UTC&characterEncoding=utf-8"
userId="root"
password="123456">
</jdbcConnection>
<!-- 对于生成的pojo所在包 -->
<javaModelGenerator targetPackage="com.imooc.pojo" targetProject="src/main/java"/>
<!-- 对于生成的mapper所在目录 -->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>
<!-- 配置mapper对应的java映射 -->
<javaClientGenerator targetPackage="com.imooc.mapper" targetProject="src/main/java"
type="XMLMAPPER"/>
<table tableName="sys_user"></table>
</context>
</generatorConfiguration>
package com.imooc.utils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
public class GeneratorDisplay {
public void generator() throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
//指定 逆向工程配置文件
File configFile = new File("generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
callback, warnings);
myBatisGenerator.generate(null);
}
public static void main(String[] args) throws Exception {
try {
GeneratorDisplay generatorSqlmap = new GeneratorDisplay();
generatorSqlmap.generator();
} catch (Exception e) {
e.printStackTrace();
}
}
}
报错显示connectionURL="jdbc:mysql://localhost:3306/springbootjpa?useSSL=false&serverTimezone=UTC&characterEncoding=utf-8"
处需要修改为
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/springbootjpa?useSSL=false&serverTimezone=UTC"
userId="root"
password="123456">
</jdbcConnection>
因为在 xml 中 &符号是作为实体字符形式存在的,这个符号必须这么写,是因为 HTML4.01中规定的特殊符号表达。
修改后进行运行,不知道为什么控制台没有任何信息输出,但是刷新后,新增了以下三个文件。表示在数据库中的student_table表可以进行反向生成mapper以及pojo。
需要让Spring Boot这个容器去加载这些mapper类,需要扫描 mybatis mapper 包路径
//扫描 mybatis mapper 包路径
@MapperScan(basePackages = "com.imooc.mapper")
UserService接口代码如下:包括保存用户、更新用户、删除用户、根据用户ID查询用户、根据条件查询用户列表:
package com.imooc.service;
import java.util.List;
import com.imooc.pojo.SysUser;
public interface UserService {
public void saveUser(SysUser user) throws Exception;
public void updateUser(SysUser user);
public void deleteUser(String userId);
public SysUser queryUserById(String userId);
public List<SysUser> queryUserList(SysUser user);
public List<SysUser> queryUserListPaged(SysUser user, Integer page, Integer pageSize);
public SysUser queryUserByIdCustom(String userId);
public void saveUserTransactional(SysUser user);
}
UserServiceImpl接口实现类代码如下:实现UserService接口的功能
package com.imooc.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.StringUtils;
import com.github.pagehelper.PageHelper;
import com.imooc.mapper.SysUserMapper;
import com.imooc.mapper.SysUserMapperCustom;
import com.imooc.pojo.SysUser;
import com.imooc.service.UserService;
import tk.mybatis.mapper.entity.Example;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private SysUserMapper userMapper;
@Autowired
private SysUserMapperCustom userMapperCustom;
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void saveUser(SysUser user) throws Exception {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
userMapper.insert(user);
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void updateUser(SysUser user) {
// userMapper.updateByPrimaryKeySelective(user);
userMapper.updateByPrimaryKey(user);
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void deleteUser(String userId) {
userMapper.deleteByPrimaryKey(userId);
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public SysUser queryUserById(String userId) {
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return userMapper.selectByPrimaryKey(userId);
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public List<SysUser> queryUserList(SysUser user) {
try {
Thread.sleep(11000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Example example = new Example(SysUser.class);
Example.Criteria criteria = example.createCriteria();
if (!StringUtils.isEmptyOrWhitespace(user.getUsername())) {
// criteria.andEqualTo("username", user.getUsername());
criteria.andLike("username", "%" + user.getUsername() + "%");
}
if (!StringUtils.isEmptyOrWhitespace(user.getNickname())) {
criteria.andLike("nickname", "%" + user.getNickname() + "%");
}
List<SysUser> userList = userMapper.selectByExample(example);
return userList;
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public List<SysUser> queryUserListPaged(SysUser user, Integer page, Integer pageSize) {
// 开始分页
PageHelper.startPage(page, pageSize);
Example example = new Example(SysUser.class);
Example.Criteria criteria = example.createCriteria();
if (!StringUtils.isEmptyOrWhitespace(user.getNickname())) {
criteria.andLike("nickname", "%" + user.getNickname() + "%");
}
example.orderBy("registTime").desc();
List<SysUser> userList = userMapper.selectByExample(example);
return userList;
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public SysUser queryUserByIdCustom(String userId) {
List<SysUser> userList = userMapperCustom.queryUserSimplyInfoById(userId);
if (userList != null && !userList.isEmpty()) {
return (SysUser)userList.get(0);
}
return null;
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void saveUserTransactional(SysUser user) {
userMapper.insert(user);
int a = 1 / 0;
user.setIsDelete(1);
userMapper.updateByPrimaryKeySelective(user);
}
}
package com.imooc.controller;
import java.util.Date;
import java.util.List;
import org.n3r.idworker.Sid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.imooc.pojo.IMoocJSONResult;
import com.imooc.pojo.SysUser;
import com.imooc.service.UserService;
@RestController
@RequestMapping("mybatis")
public class MyBatisCRUDController {
@Autowired
private UserService userService;
@Autowired
private Sid sid;
@RequestMapping("/saveUser")
public IMoocJSONResult saveUser() throws Exception {
String userId = sid.nextShort();
SysUser user = new SysUser();
user.setId(userId);
user.setUsername("imooc" + new Date());
user.setNickname("imooc" + new Date());
user.setPassword("abc123");
user.setIsDelete(0);
user.setRegistTime(new Date());
userService.saveUser(user);
return IMoocJSONResult.ok("保存成功");
}
@RequestMapping("/updateUser")
public IMoocJSONResult updateUser() {
SysUser user = new SysUser();
user.setId("10011001");
user.setUsername("10011001-updated" + new Date());
user.setNickname("10011001-updated" + new Date());
user.setPassword("10011001-updated");
user.setIsDelete(0);
user.setRegistTime(new Date());
userService.updateUser(user);
return IMoocJSONResult.ok("保存成功");
}
@RequestMapping("/deleteUser")
public IMoocJSONResult deleteUser(String userId) {
userService.deleteUser(userId);
return IMoocJSONResult.ok("删除成功");
}
@RequestMapping("/queryUserById")
public IMoocJSONResult queryUserById(String userId) {
return IMoocJSONResult.ok(userService.queryUserById(userId));
}
@RequestMapping("/queryUserList")
public IMoocJSONResult queryUserList() {
SysUser user = new SysUser();
user.setUsername("imooc");
user.setNickname("lee");
List<SysUser> userList = userService.queryUserList(user);
return IMoocJSONResult.ok(userList);
}
@RequestMapping("/queryUserListPaged")
public IMoocJSONResult queryUserListPaged(Integer page) {
if (page == null) {
page = 1;
}
int pageSize = 10;
SysUser user = new SysUser();
// user.setNickname("lee");
List<SysUser> userList = userService.queryUserListPaged(user, page, pageSize);
return IMoocJSONResult.ok(userList);
}
@RequestMapping("/queryUserByIdCustom")
public IMoocJSONResult queryUserByIdCustom(String userId) {
return IMoocJSONResult.ok(userService.queryUserByIdCustom(userId));
}
@RequestMapping("/saveUserTransactional")
public IMoocJSONResult saveUserTransactional() {
String userId = sid.nextShort();
SysUser user = new SysUser();
user.setId(userId);
user.setUsername("lee" + new Date());
user.setNickname("lee" + new Date());
user.setPassword("abc123");
user.setIsDelete(0);
user.setRegistTime(new Date());
userService.saveUserTransactional(user);
return IMoocJSONResult.ok("保存成功");
}
}
注意: 这里需要使用以下代码进行新增用户信息时,
@Autowired
private Sid sid;
需要新引入以下三个包:
并且需要在ImoocApplication.java文件中新增组件扫描代码,这样才可以将里面的类以注入的形式直接使用:
//扫描 所有需要的包, 包含一些自用的工具类包 所在的路径
@ComponentScan(basePackages= {
"com.imooc", "org.n3r.idworker"})
1、新增用户信息:
2、保存用户信息:
@RequestMapping("/queryUserListPaged")
public IMoocJSONResult queryUserListPaged(Integer page) {
if (page == null) {
page = 1;
}
int pageSize = 10;
SysUser user = new SysUser();
// user.setNickname("lee");
List<SysUser> userList = userService.queryUserListPaged(user, page, pageSize);
return IMoocJSONResult.ok(userList);
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public List<SysUser> queryUserListPaged(SysUser user, Integer page, Integer pageSize) {
// 开始分页
PageHelper.startPage(page, pageSize);
Example example = new Example(SysUser.class);
Example.Criteria criteria = example.createCriteria();
if (!StringUtils.isEmptyOrWhitespace(user.getNickname())) {
criteria.andLike("nickname", "%" + user.getNickname() + "%");
}
example.orderBy("registTime").desc();//对时间排序
List<SysUser> userList = userMapper.selectByExample(example);
return userList;
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.imooc.mapper.SysUserMapperCustom" >
<!-- 查询简单的用户信息 -->
<select id="queryUserSimplyInfoById" resultType="com.imooc.pojo.SysUser"
parameterType="java.lang.String" >
select
*
from
sys_user
where
id = #{
id,jdbcType=VARCHAR}
</select>
</mapper>
package com.imooc.mapper;
import java.util.List;
import com.imooc.pojo.SysUser;
public interface SysUserMapperCustom {
List<SysUser> queryUserSimplyInfoById(String id);
}
@Autowired
private SysUserMapperCustom userMapperCustom;
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public SysUser queryUserByIdCustom(String userId) {
List<SysUser> userList = userMapperCustom.queryUserSimplyInfoById(userId);
if (userList != null && !userList.isEmpty()) {
return (SysUser)userList.get(0);
}
return null;
}
@RequestMapping("/queryUserByIdCustom")
public IMoocJSONResult queryUserByIdCustom(String userId) {
return IMoocJSONResult.ok(userService.queryUserByIdCustom(userId));
}
SpringBoot整合持久层事务:
1、事务的隔离级别 DEFAULT
READ_UNCOMMITTED
READ_COMMITTED
REPEATABLE_READ
SERIALIZABLE
2、事务的传播行为 REQUIRED
SUPPORTS
MANDATORY
REQUIRES_NEW
NOT_SUPPORTED
NEVER
NESTED
使用Springboot版mybatis逆向生成工具生成mapper以及pojo实体类,和mybatis相关配置文件。
下图所示的是导入的一个工具工程,箭头所指的就是最后逆向生成的文件所存储的位置:
注意: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="MysqlContext" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<plugin type="tk.mybatis.mapper.generator.MapperPlugin">
<property name="mappers" value="com.imooc.utils.MyMapper"/>
</plugin>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/enhypen-video-dev?useSSL=false&serverTimezone=UTC"
userId="root"
password="123456">
</jdbcConnection>
<!-- 对应生成的pojo所在包 -->
<javaModelGenerator targetPackage="com.imooc.pojo" targetProject="src/main/java"/>
<!-- 对应生成的mapper所在目录 -->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>
<!-- 配置mapper对应的java映射 -->
<javaClientGenerator targetPackage="com.imooc.mapper" targetProject="src/main/java"
type="XMLMAPPER"/>
<!-- 需要生成数据库表 -->
<table tableName="bgm"></table>
<table tableName="comments"></table>
<table tableName="search_records"></table>
<table tableName="users"></table>
<table tableName="users_fans"></table>
<table tableName="users_like_videos"></table>
<table tableName="users_report"></table>
<table tableName="videos"></table>
</context>
</generatorConfiguration>
需要运行这个工具工程时,直接右键下面这个GeneratorDisplay.java,再RUN AS即可:
等待一会之后(此时控制台没有任何信息输出),右键点击刷新,可以看到逆向生成了许多类。
5)进行安装
在网上查到的解决方法,才发现我不该手贱把下图中的内容删掉了呜呜呜