Spring Boot:整合MyBatis框架
综合概述
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。MyBatis 是一款半 ORM 框架,相对于 Hibernate 这样的完全 ORM 框架,MyBatis 显得更加灵活,因为可以直接控制 SQL 语句,所以使用 MyBatis 可以非常方便的实现各种复杂的查询需求。当然了,有利必有弊,也正因为太过自由,所以需要自己编写 SQL 语句,而如何编写更为简洁高效的 SQL 语句,也是一门学问。
实现案例
接下来,我们就通过实际案例来讲解 MyBatis 的整合,然后提供相关的服务来学习了解数据库的操作。
生成项目模板
为方便我们初始化项目,Spring Boot 给我们提供一个项目模板生成网站。
1. 打开浏览器,访问:https://start.spring.io/
2. 根据页面提示,选择构建工具,开发语言,项目信息等。
3. 点击 Generate the project,生成项目模板,生成之后会将压缩包下载到本地。
4. 使用 IDE 导入项目,我这里使用 Eclipse,通过导入 Maven 项目的方式导入。
创建数据库表
这里使用 MySQL 数据库,版本是 8.0.16,在项目根目录下新建 db 目录,然后在其中编写一个数据库脚本文件。
在 MySQL 数据库新建一个 springboot 数据库,然后在此数据库中执行下面的脚本创建项目用户表和用户数据。
脚本文件
SQL 脚本内容
springboot.sql
-- ---------------------------- -- Table structure for sys_user -- ---------------------------- DROP TABLE IF EXISTS `sys_user`; CREATE TABLE `sys_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', `name` varchar(50) NOT NULL COMMENT '用户名', `nick_name` varchar(150) DEFAULT NULL COMMENT '昵称', `avatar` varchar(150) DEFAULT NULL COMMENT '头像', `password` varchar(100) DEFAULT NULL COMMENT '密码', `salt` varchar(40) DEFAULT NULL COMMENT '加密盐', `email` varchar(100) DEFAULT NULL COMMENT '邮箱', `mobile` varchar(100) DEFAULT NULL COMMENT '手机号', `status` tinyint(4) DEFAULT NULL COMMENT '状态 0:禁用 1:正常', `dept_id` bigint(20) DEFAULT NULL COMMENT '机构 ID', `create_by` varchar(50) DEFAULT NULL COMMENT '创建人', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `last_update_by` varchar(50) DEFAULT NULL COMMENT '更新人', `last_update_time` datetime DEFAULT NULL COMMENT '更新时间', `del_flag` tinyint(4) DEFAULT '0' COMMENT '是否删除 -1:已删除 0:正常', PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8 COMMENT='用户管理';-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTOsys_user
VALUES ('1', 'admin', '管理员', null, 'bd1718f058d8a02468134432b8656a86', 'YzcmCZNvbXocrsz9dm8e', 'admin@qq.com','13612345678','1','4','admin','2018-08-14 11:11:11','admin','2018-08-14 11:11:11','0');
INSERT INTOsys_user
VALUES ('2', 'liubei', '刘备', null, 'fd80ebd493a655608dc893a9f897d845', 'YzcmCZNvbXocrsz9dm8e', 'test@qq.com','13889700023','1','7','admin','2018-09-23 19:43:00','admin','2019-01-10 11:41:13','0');
INSERT INTOsys_user
VALUES ('3', 'zhaoyun', '赵云', null, 'fd80ebd493a655608dc893a9f897d845', 'YzcmCZNvbXocrsz9dm8e', 'test@qq.com','13889700023','1','7','admin','2018-09-23 19:43:44','admin','2018-09-23 19:43:52','0');
INSERT INTOsys_user
VALUES ('4', 'zhugeliang', '诸葛亮', null, 'fd80ebd493a655608dc893a9f897d845', 'YzcmCZNvbXocrsz9dm8e', 'test@qq.com','13889700023','7','11','admin','2018-09-23 19:44:23','admin','2018-09-23 19:44:29','0');
INSERT INTOsys_user
VALUES ('5', 'caocao', '曹操', null, 'fd80ebd493a655608dc893a9f897d845', 'YzcmCZNvbXocrsz9dm8e', 'test@qq.com','13889700023','1','8','admin','2018-09-23 19:45:32','admin','2019-01-10 17:59:14','0');
INSERT INTOsys_user
VALUES ('6', 'dianwei', '典韦', null, 'fd80ebd493a655608dc893a9f897d845', 'YzcmCZNvbXocrsz9dm8e', 'test@qq.com','13889700023','1','10','admin','2018-09-23 19:45:48','admin','2018-09-23 19:45:57','0');
INSERT INTOsys_user
VALUES ('7', 'xiahoudun', '夏侯惇', null, 'fd80ebd493a655608dc893a9f897d845', 'YzcmCZNvbXocrsz9dm8e', 'test@qq.com','13889700023','1','8','admin','2018-09-23 19:46:09','admin','2018-09-23 19:46:17','0');
INSERT INTOsys_user
VALUES ('8', 'xunyu', '荀彧', null, 'fd80ebd493a655608dc893a9f897d845', 'YzcmCZNvbXocrsz9dm8e', 'test@qq.com','13889700023','1','10','admin','2018-09-23 19:46:38','admin','2018-11-04 15:33:17','0');
INSERT INTOsys_user
VALUES ('9', 'sunquan', '孙权', null, 'fd80ebd493a655608dc893a9f897d845', 'YzcmCZNvbXocrsz9dm8e', 'test@qq.com','13889700023','1','10','admin','2018-09-23 19:46:54','admin','2018-09-23 19:47:03','0');
INSERT INTOsys_user
VALUES ('0', 'zhouyu', '周瑜', null, 'fd80ebd493a655608dc893a9f897d845', 'YzcmCZNvbXocrsz9dm8e', 'test@qq.com','13889700023','1','11','admin','2018-09-23 19:47:28','admin','2018-09-23 19:48:04','0');
INSERT INTOsys_user
VALUES ('11', 'luxun', '陆逊', null, 'fd80ebd493a655608dc893a9f897d845', 'YzcmCZNvbXocrsz9dm8e', 'test@qq.com','13889700023','1','11','admin','2018-09-23 19:47:44','admin','2018-09-23 19:47:58','0');
INSERT INTOsys_user
VALUES ('12', 'huanggai', '黄盖', null, 'fd80ebd493a655608dc893a9f897d845', 'YzcmCZNvbXocrsz9dm8e', 'test@qq.com','13889700023','1','11','admin','2018-09-23 19:48:38','admin','2018-09-23 19:49:02','0');
添加相关依赖
添加 Maven 相关依赖,这里需要添加上 WEB 和 Swagger 和 MyBatis 的依赖,Swagger 的添加是为了方便接口测试。
WEB 依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
swagger 依赖,这里选择 2.9.2 版本。
<!-- swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>
这里使用 MySQL 数据库,所以需要 MySQL 驱动。
<!-- 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>2.0.0</version> </dependency>
添加相关配置
1. 添加 swagger 配置
添加一个 swagger 配置类,在工程下新建 config 包并添加一个 SwaggerConfig 配置类。
SwaggerConfig.java
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration
@EnableSwagger2
public class SwaggerConfig {@Bean </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Docket createRestApi(){ </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()).build(); } </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> ApiInfo apiInfo(){ </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ApiInfoBuilder() .title(</span>"SpringBoot API Doc"<span style="color: rgba(0, 0, 0, 1)">) .description(</span>"This is a restful api document of Spring Boot."<span style="color: rgba(0, 0, 0, 1)">) .version(</span>"1.0"<span style="color: rgba(0, 0, 0, 1)">) .build(); }
}
2. 添加 MyBatis 配置
添加 MyBatis 配置类,配置相关扫描路径,包括 DAO,Model,XML 映射文件的扫描。
在 config 包下新建一个 MyBatis 配置类,MybatisConfig.java。
MybatisConfig.java
package com.louis.springboot.demo.config; import javax.sql.DataSource;import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;@Configuration
@MapperScan("com.louis.springboot.**.dao") // 扫描 DAO
public class MybatisConfig {
@Autowired
private DataSource dataSource;@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage("com.louis.springboot..model"); // 扫描 Model
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sessionFactory.setMapperLocations(resolver.getResources("classpath*:/sqlmap/*.xml")); // 扫描映射文件<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sessionFactory.getObject();
}
}
3. 添加数据源配置
将 application.properties 文件改名为 application.yml ,并在其中添加 MySQL 数据源连接信息。
注意:
这里需要首先创建一个 MySQL 数据库,并输入自己的用户名和密码。这里的数据库是 springboot。
另外,如果你使用的是 MySQL 5.x 及以前版本,驱动配置driverClassName 是com.mysql.jdbc.Driver。
application.yml
server: port: 8080 spring: datasource: driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=utf-8 username: root password: 123456
生成 MyBatis 模块
由于手动编写 MyBatis 的 Model、DAO、XML 映射文件比较繁琐,通常都会通过一些生成工具来生成。MyBatis 官方也提供了生成工具(MyBaits Generator),另外还有一些基于官方基础上改进的第三方工具,比如 MyBatis Plus 就是国内提供的一款非常优秀的开源工具,网上相关教程比较多,这里就不再赘述了。
这里提供一些资料作为参考。
Mybatis Generator 官网:http://www.mybatis.org/generator/index.html
Mybatis Generator 教程:https://blog.csdn.net/testcs_dn/article/details/77881776
MyBatis Plus 官网: http://mp.baomidou.com/#/
MyBatis Plus 官网: http://mp.baomidou.com/#/quick-start
代码生成好之后,分別将 MODEL、DAO、XML 映射文件拷贝到相应的包里。
打开 Mapper,我们看到 MyBatis Generator 给我们默认生成了一些增删改查的方法。
SysUserMapper.java
package com.louis.springboot.demo.dao; import com.louis.springboot.demo.model.SysUser;public interface SysUserMapper {
int deleteByPrimaryKey(Long id);</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> insert(SysUser record); </span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> insertSelective(SysUser record); SysUser selectByPrimaryKey(Long id); </span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> updateByPrimaryKeySelective(SysUser record); </span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> updateByPrimaryKey(SysUser record);
}
编写服务接口
向 SysUserMapper 类中新一个 selectAll 方法,用于查询所有的用户信息。
SysUserMapper.java
package com.louis.springboot.demo.dao; import java.util.List; import com.louis.springboot.demo.model.SysUser;public interface SysUserMapper {
int deleteByPrimaryKey(Long id);</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> insert(SysUser record); </span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> insertSelective(SysUser record); SysUser selectByPrimaryKey(Long id); </span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> updateByPrimaryKeySelective(SysUser record); </span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> updateByPrimaryKey(SysUser record); </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)"> * 查询全部用户 * </span><span style="color: rgba(128, 128, 128, 1)">@return</span> <span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)"> List</span><SysUser><span style="color: rgba(0, 0, 0, 1)"> selectAll();
}
向 SysUserMapper.xml 中加入 selectAll 的查询语句。
SysUserMapper.xml
<select id="selectAll" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from sys_user </select>
新建 service 包,并在其中编写 SysUserService 接口,包含 selectAll 和 findByUserId 两个方法。
SysUserService.java
package com.louis.springboot.demo.service; import java.util.List; import com.louis.springboot.demo.model.SysUser;public interface SysUserService {
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)"> * 根据用户ID查找用户 * </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> userId * </span><span style="color: rgba(128, 128, 128, 1)">@return</span> <span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)"> SysUser findByUserId(Long userId); </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)"> * 查找所有用户 * </span><span style="color: rgba(128, 128, 128, 1)">@return</span> <span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)"> List</span><SysUser><span style="color: rgba(0, 0, 0, 1)"> findAll();
}
在 service 包下新建 impl 包,并在其中编写 SysUserServiceImpl 实现类,调用 SysUserMapper 方法完成查询操作。
SysUserServiceImpl.java
package com.louis.springboot.demo.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.louis.springboot.demo.dao.SysUserMapper; import com.louis.springboot.demo.model.SysUser; import com.louis.springboot.demo.service.SysUserService;@Service
public class SysUserServiceImpl implements SysUserService {@Autowired </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> SysUserMapper sysUserMapper; @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> SysUser findByUserId(Long userId) { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sysUserMapper.selectByPrimaryKey(userId); } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> List<SysUser><span style="color: rgba(0, 0, 0, 1)"> findAll() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sysUserMapper.selectAll(); }
}
新建一个 controller 包,并在其中编写 SysUserController restful 接口,返回 JSON 数据格式,提供外部调用。
SysUserController.java
package com.louis.springboot.demo.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.louis.springboot.demo.service.SysUserService;@RestController
@RequestMapping("user")
public class SysUserController {@Autowired </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> SysUserService sysUserService; @GetMapping(value</span>="/findByUserId"<span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Object findByUserId(@RequestParam Long userId) { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sysUserService.findByUserId(userId); } @GetMapping(value</span>="/findAll"<span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Object findAll() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sysUserService.findAll(); }
}
打包资源配置
虽然代码编写已经完成,但此时启动运行还是会有问题的,因为在编译打包的时候,我们的 XML 映射文件是不在默认打包范围内的,所以需要修改一下配置。
修改 pom.xml ,在 build 标签内加入形如以下的 resource 标签的打包配置,这样代码打包时就会把映射文件也拷贝过去了。
pom.xml
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <!-- 打包时拷贝 MyBatis 的映射文件 --> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/sqlmap/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.*</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
编译测试运行
1. 右键项目 -> Run as -> Maven install,开始执行 Maven 构建,第一次会下载 Maven 依赖,可能需要点时间,如果出现如下信息,就说明项目编译打包成功了。
2. 右键文件 DemoApplication.java -> Run as -> Java Application,开始启动应用,当出现如下信息的时候,就说明应用启动成功了,默认启动端口是 8080。
3. 打开浏览器,访问:http://localhost:8080/swagger-ui.html,进入 swagger 接口文档界面。
4. 分别测试 findAll 和 findUserById 接口,如果能正常返回数据,就说明 MyBatis 已经可以正常使用了。
findAll 接口
findUserById 接口
胡言乱语
JDBC 有点原始,ORM 封装度高。
Hibernate 操作对象,MyBatis 语句灵活。
两者各有利弊,根据条件选择。
完全对象选前者,灵活控制选后者。
参考资料
MyBatis 官网:http://www.mybatis.org/mybatis-3/zh/index.html
MyBatis Generator 官网:http://www.mybatis.org/generator/index.html
MyBatis Plus 官网: http://mp.baomidou.com/#/quick-start
相关导航
源码下载
码云:https://gitee.com/liuge1988/spring-boot-demo.git
作者:朝雨忆轻尘
出处:https://www.cnblogs.com/xifengxiaoma/
版权所有,欢迎转载,转载请注明原文作者及出处。