30分钟带你了解Springboot与Mybatis整合最佳实践
前言:Springboot怎么使用想必也无需我多言,Mybitas作为实用性极强的ORM框架也深受广大开发人员喜爱,有关如何整合它们的文章在网络上随处可见。但是今天我会从实战的角度出发,谈谈我对二者结合与使用的最佳实践。
一、依赖与pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
目前SpringBoot官方的最新版本是2.0.4.RELEASE我们就以这个版本为基础,2.0以下版本可能会有些区别这里不多解释。
二、创建配置文件和启动类
Spring官方推荐使用yml文件,既然是最佳实践我们就按照官方的要求来做。
application.yml
server:
port: 8090
spring:
datasource:
mimas:
driverClassName: com.mysql.jdbc.Driver
jdbcUrl: jdbc:mysql://192.168.56.101:3306/mimas
username: root
password: 12345678
logging:
level:
com.learnhow.springboot.mybatis.dao: debug
解释一下三个部分的含义:
(1)server:代表当前服务通过8090端口访问。
(2)spring:配置了一个名为mimas的数据源,如果项目需要多个数据源可以按照这样的方式将数据源配置成不同的名称。
(3)logging:定义dao包下的日志记录级别为debug,标准输出会显示sql语句(这一点对开发还是很重要的)
Application.java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
三、xml文件与接口
Springboot与Mybatis整合以后可以使用annotation(注解)和xml(配置文件)两种方式编写sql语句,我推荐的做法是后者。就目前我接触到的项目来说,项目部署环境都比较严格,往往修改一个BUG到重新部署完成少则2个小时,多则数天。而很多BUG有时候仅仅需要修改几条SQL语句。如果采用配置文件的方式,这类问题只需要在服务器上修改一下文件然后再重启一下服务就能完成。其次,我个人也很不喜欢Java代码和SQL代码混再一起开发方式,既不美观也不便于维护。所以通常在项目初期我都会尽量避免这类为以后埋坑的行为。
以下是一个典型的xml配置:
<?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.learnhow.springboot.mybatis.dao.mimas.UserDao">
<resultMap type="User" id="UserMap">
<id column="id" property="id" jdbcType="BIGINT" />
<result column="user_name" property="username" jdbcType="VARCHAR" />
<result column="user_age" property="age" jdbcType="INTEGER" />
<result column="user_gender" property="gender" jdbcType="INTEGER" />
<result column="ep_id" property="enterpriseId" jdbcType="BIGINT" />
</resultMap>
<select id="getAll" resultType="User">
select * from user_t
</select> <select id="getOne" resultType="User" parameterType="Long">
select * from user_t t where t.id = #{id}
</select> <insert id="saveUsers">
insert into user_t(user_name, user_age, user_gender, ep_id) values
<foreach collection="users" item="user" separator=",">
(#{user.username}, #{user.age}, #{user.gender}
<trim prefix="," suffix=")">
<choose>
<when test="user.enterpriseId != null and user.enterpriseId != 0">
#{user.enterpriseId}
</when>
<otherwise>
null
</otherwise>
</choose>
</trim>
</foreach>
</insert> <update id="modifyEnterpriseId">
update user_t set ep_id = #{eid} where id = #{uid}
</update>
</mapper>
具体语句和表原型大家不用过分关心,一个mybatis的sql配置文件主要有几个细节需要注意:
(1)配置文件中的sql语句与dao接口是如何结合的?
实际上mybatis先扫描配置文件然后将sql语句通过namespace和id反向注册到dao接口中,所以namespace属性表示接口类的全限定名,每一个方法的id则对应接口类中的每一个接口方法。
(2)查询中遇到多个参数的情况怎么办?
如果多个参数都属于一个单一实体,我们可以直接使用实体对象最为参数。例如配置文件中的两条select语句。如果实体的属性名与表的字段明称不一致可以通过resultMap做关联。
如果多个参数不属于单一实体,我们可以在接口方法中通过@Param指定参数的名字然后在语句中使用(参考update方法)。我们应尽量避免在配置文件中使用parameterMap方法和在接口中使用Map对象,因为这样都不利于大型代码的维护。
(3)根据情况的不同动态生成SQL语句也是Mybatis的一大亮点,我很喜欢这个特征(参考insert方法)。不过在实际开发中我不并要求开发人员大量使用(任何一种增加编写难度和提高维护成本的行为都应该被谨慎选择)。
import java.util.List;
import java.util.Set; import org.apache.ibatis.annotations.Param; import com.learnhow.springboot.mybatis.entity.User; public interface UserDao {
List<User> getAll(); User getOne(long id); int saveUsers(@Param("users") Set<User> users); int modifyEnterpriseId(@Param("uid") long userId, @Param("eid") long enterpriseId);
}
四、Mybatis配置文件
DataSourceConfig.java
import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; @Configuration
@MapperScan(basePackages = "com.learnhow.springboot.mybatis.dao.mimas", // 为指定包中的DAO注入SqlSessionTemplate
sqlSessionTemplateRef = "mimasSqlSessionTemplate") // 指定SqlSessionTemplate
public class DataSourceConfig {
@Bean(name = "mimasDataSource")
@ConfigurationProperties(prefix = "spring.datasource.mimas")
@Primary
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
} @Bean(name = "mimasSqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("mimasDataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/mimas/*.xml"));
bean.setTypeAliasesPackage("com.learnhow.springboot.mybatis.entity"); // 指定entity的别名
return bean.getObject();
} @Bean(name = "mimasSqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("mimasSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
Springboot的项目都需要配置主数据源,MapperScan表示扫描dao.mimas.*下的所有接口并注入指定的SessionTemplate。下面的三个方法就是产生这个SessionTemplate的过程。
五、事务控制
传统的方法是在service中做事务控制,我们还是沿用这样的开发逻辑。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import com.learnhow.springboot.mybatis.dao.mimas.UserDao;
import com.learnhow.springboot.mybatis.entity.User; @Component
public class UserService {
@Autowired
private UserDao userDao; @Transactional
public int saveUsers(Set<User> users) {
return userDao.saveUsers(users);
} @Transactional
public void modifyEnterpriseIdByUserId(Set<User> users) {
for(User u : users) {
userDao.modifyEnterpriseId(u.getId(), u.getEnterpriseId());
}
}
}
至此,有关Springboot和mybatis的整合我们已经完成。完整代码由于十分简单我就不提供链接了,有需要帮助的小伙伴可以私信@我。
30分钟带你了解Springboot与Mybatis整合最佳实践的更多相关文章
- SpringBoot+Shiro+mybatis整合实战
SpringBoot+Shiro+mybatis整合 1. 使用Springboot版本2.0.4 与shiro的版本 引入springboot和shiro依赖 <?xml version=&q ...
- SpringBoot与Mybatis整合方式01(源码分析)
前言:入职新公司,SpringBoot和Mybatis都被封装了一次,光用而不知道原理实在受不了,于是开始恶补源码,由于刚开始比较浅,存属娱乐,大神勿喷. 就如网上的流传的SpringBoot与Myb ...
- 30分钟带你了解Docker
最近一直在忙项目,不知不觉2个多月没有更新博客了.正好自学了几天docker就干脆总结一下,也顺带增加一篇<30分钟入门系列>.网上能够查到的对于docker的定义我就不再重复了,说说我自 ...
- Springboot与Mybatis整合
最近自己用springboot和mybatis做了整合,记录一下: 1.先导入用到的jar包 <dependency> <groupId>org.springframework ...
- SpringBoot系列——MyBatis整合
前言 MyBatis官网:http://www.mybatis.org/mybatis-3/zh/index.html 本文记录springboot与mybatis的整合实例:1.以注解方式:2.手写 ...
- SpringBoot与Mybatis整合实例详解
介绍 从Spring Boot项目名称中的Boot可以看出来,SpringBoot的作用在于创建和启动新的基于Spring框架的项目,它的目的是帮助开发人员很容易的创建出独立运行的产品和产品级别的基于 ...
- spring-boot、mybatis整合
一.MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 X ...
- springBoot和MyBatis整合中出现SpringBoot无法启动时处理方式
在springBoot和Myatis 整合中出现springBoot无法启动 并且报以下错误 Description: Field userMapper in cn.lijun.control ...
- 30分钟带你快速入门MySQL教程
这是一篇真正适合初学者的MySQL数据库入门文章,哪怕你从来没有接触过数据库,或者说你从来没有听说过有数据库这东西,请一定要相信我,我当时就是这么过来的. 如果你刚开始接触MySQL数据库,或者你需要 ...
随机推荐
- #C++初学记录(sort函数)
sort函数 前言:当进行贪心算法的学习时,需要用到sort函数,因为初学c++汇编语言,sort的具体用法没有深入学习,所以这里进行sort学习记录并只有基础用法并借用贪心算法题目的代码. 百度百科 ...
- Python消息队列工具 Python-rq 中文教程
原创文章,作者:Damon付,如若转载,请注明出处:<Python消息队列工具 Python-rq 中文教程>http://www.tiangr.com/python-xiao-xi-du ...
- javascript闭包(Module模式)的用途和高级使用方式
javascript闭包(Module模式)的用途和高级使用方式 javascript闭包的用途:1. 匿名自执行函数:或者可以理解为,避免污染全局变量2. 缓存:源于闭包的核心特性便是保存状态,应用 ...
- python3.4学习笔记(二十五) Python 调用mysql redis实例代码
python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...
- 根据wsdl,基于wsimport生成代码的客户端
根据wsdl,基于wsimport生成代码的客户端 wsimport是jdk自带的命令,可以根据wsdl文档生成客户端中间代码,基于生成的代码编写客户端,可以省很多麻烦. 局限性:wsimport ...
- HTML JavaScript 基础学习
HTML 中肯定会用到 JavaScript 的知识点,会点 JavaScript 的基础知识不会吃亏,其实打算去买JavaScript的教程去专门学习一下,但是交给我的时间不多了,记录一点,能会一点 ...
- 09:Linux 中各个文件夹的作用
参考博客 / 根目录 包含了几乎所的文件目录.相当于中央系统.进入的最简单方法是:cd /. /boot 引导程序,内核等存放的目录 这个目录,包括了在引导过程中所必需的文件.在最开始的启动阶段, ...
- 使用CloudFlare 的 PKI 工具集 cfssl 来生成 Certificate Authority (CA) 证书和秘钥文件
要安装kubernetes最新版集群,https://github.com/opsnull/follow-me-install-kubernetes-cluster 这个文档必须要研习一下了. 以下实 ...
- 20145204《网络对抗》MAL后门原理与实践
20145204<网络对抗>MAL后门原理与实践 实践内容说明 (1)使用netcat获取主机操作Shell,cron启动 (1分) (2)使用socat获取主机操作Shell, 任务计划 ...
- 如何写出格式优美的javadoc?
如果你读过Java源码,那你应该已经见到了源码中优美的javadoc.在eclipse 中鼠标指向任何的公有方法都会显示出详细的描述,例如返回值.作用.异常类型等等. 本文主要来自<Thinki ...