DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描
liuyuhang原创,未经允许禁止转载
系列目录连接
1.环境说明
Springboot初学者,需要学习手工配置数据源,不需要多数据源配置的情况下
建议使用本说明进行配置。
springboot,parent 2.0.2.和1.5.3.都已经测试过,
在java8和java7环境下测试过。前者配java8,后者配java7,
使用MyEclipse 2017 C1 64x,MyEclipse 2016之前的版本无法使用java8
pom.xml核心如下:
org.springframework.boot spring-boot-starter-parent 2.0.2.RELEASE mysql mysql-connector-java org.springframework.boot spring-boot-starter-jdbc org.mybatis mybatis 3.4.0 org.mybatis.spring.boot mybatis-spring-boot-starter 1.1.1 tk.mybatis mapper 3.3.7 org.springframework.boot spring-boot-configuration-processor true
2.配置思路
2.1.创建SystemConfig类,使用@ConfigurationProperties注解获取application.properties文件中的属性;
2.2.注入SystemConfig到Mybatis的SessionFactory的配置类
2.3.创建数据源DataSource;
2.4.注入数据源属性;
2.5.创建SqlSessionFactory;
2.6.SqlSessionFactory配置DataSource;
2.7.SqlSessionFactory配置扫描MyBatis-config.xml文件;
2.8.SqlSessionFactory配置扫描Mapper.xml所在包;
2.9.获取session查询数据库进行测试;
3.所需类与结构
3.0.application.properties文件与相应内容作为数据源;
3.1.SystemConfig类,用于获取application.properties中的property;
3.2.DataConfig类,用于获取SqlSessionFactory;
3.3.ExampleController类,用于测试;
3.4.AppRun类,springboot的启动入口,将DataConfig初始化;
3.5.mapper.xml内容
4.代码
4.0.application.properties文件,代码如下:
1 master.url=jdbc:mysql://qqq.jjj.xxx.iii:3306/master?characterEncoding=utf82 master.username=root3 master.password=root4 master.driver=com.mysql.jdbc.Driver5 #master.driver-class-name=com.mysql.jdbc.Driver 一般是使用这个命名模式
4.1.SystemConfig类,代码如下:
1 package com.FM.config; 2 3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.stereotype.Component; 5 6 @Component//作为组件交给spring管理 7 @ConfigurationProperties(prefix = "master")//读取application文件前缀为master的属性 8 public class SystemConfig { 9 10 String url;11 String driver;12 String username;13 String password;14 15 //提供setter给spring,提供setter自用16 public String getUrl() {17 return url;18 }19 20 public void setUrl(String url) {21 this.url = url;22 }23 24 public String getDriver() {25 return driver;26 }27 28 public void setDriver(String driver) {29 this.driver = driver;30 }31 32 public String getUsername() {33 return username;34 }35 36 public void setUsername(String username) {37 this.username = username;38 }39 40 public String getPassword() {41 return password;42 }43 44 public void setPassword(String password) {45 this.password = password;46 }47 48 }
4.2.DataConfig类,用于获取SqlSessionFactory,代码如下:
1 package com.FM.config; 2 3 import java.util.HashMap; 4 5 import javax.sql.DataSource; 6 7 import org.apache.ibatis.session.SqlSessionFactory; 8 import org.mybatis.spring.SqlSessionFactoryBean; 9 import org.springframework.beans.factory.annotation.Autowired;10 import org.springframework.boot.jdbc.DataSourceBuilder;11 import org.springframework.context.annotation.Configuration;12 import org.springframework.core.io.DefaultResourceLoader;13 import org.springframework.core.io.Resource;14 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;15 16 /**17 * DataConfig,获取数据源,配置给SqlSessionFactory,并以此获取session18 * @author liuyuhang19 */20 @Configuration//作为配置,交给spring管理21 public class DataConfig {22 23 @Autowired//注入SystemConfig类,注意变量名24 private SystemConfig systemConfig;25 26 /**27 * 手动获取sessionFactory并配置用例28 * @param dataSourcePerfix29 * @return30 * @throws Exception31 */32 public SqlSessionFactory getSessionFactory() throws Exception {33 34 String masterUrl = systemConfig.getUrl();35 String masterDriver = systemConfig.getDriver();36 String masterUsername = systemConfig.getUsername();37 String masterPassword = systemConfig.getPassword();38 // 创建数据源39 DataSourceBuilder create = DataSourceBuilder.create();40 create.url(masterUrl);41 create.driverClassName(masterDriver);42 create.username(masterUsername);43 create.password(masterPassword);44 DataSource source = create.build();45 // 创建sessionFactory46 SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();47 factoryBean.setDataSource(source);// 加载数据源48 // 扫描mapper.xml49 Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:com/FM/mapper/*.xml");50 factoryBean.setMapperLocations(resources);51 // 读取config52 factoryBean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis-config.xml"));53 SqlSessionFactory sessionFactory = factoryBean.getObject();54 return sessionFactory;55 }56 57 }
4.3.ExampleController类,用于测试;
1 package com.FM.controller; 2 3 import java.util.HashMap; 4 import java.util.List; 5 import java.util.Map; 6 7 import javax.servlet.http.HttpServletRequest; 8 9 import org.apache.ibatis.session.SqlSession;10 import org.apache.ibatis.session.SqlSessionFactory;11 import org.springframework.beans.factory.annotation.Autowired;12 import org.springframework.web.bind.annotation.RequestMapping;13 import org.springframework.web.bind.annotation.RestController;14 15 import com.FM.config.DataConfig;16 import com.FM.tool.reqUtils;17 18 @RestController //等同于responseBody + controller双重注解19 public class ExampleController {20 21 @Autowired22 DataConfig dataConfig;23 24 /**25 * 手动创建session查询数据库用例,该方法可以创建多个sessionFactory,用多线程26 * @param request27 * @return28 * @throws Exception29 */30 @RequestMapping("/helloMybatis")31 public List helloMybatis(HttpServletRequest request) throws Exception {32 SqlSessionFactory sessionFactory = dataConfig.getSessionFactory();//获取sessionfactory33 SqlSession session = sessionFactory.openSession();//获取session34 List
4.4.AppRun类,springboot的启动入口,将DataConfig初始化;
1 package com.FM; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.SpringBootConfiguration; 5 import org.springframework.boot.autoconfigure.SpringBootApplication; 6 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 7 import org.springframework.boot.web.servlet.ServletComponentScan; 8 9 @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) // 禁用默认的单数据源配置10 @SpringBootConfiguration // springboot基础配置注解11 @ServletComponentScan // springboot servlet filter12 // @EnableConfigurationProperties//该注解于springboot1.5以上废弃13 public class AppRun {14 15 public static void main(String[] args) throws Exception {16 SpringApplication.run(AppRun.class, args);17 }18 }
4.5.mapper.xml内容:略,前篇有
5.说明
一般来讲是配置数据源,用Mybatis的sessionFactory来读取dao;
然后将dao注入给service,再将service注入给controller。
说明一下,这几个注解本质上是一个意思,即@Repository,@Service,@Controller,
本质上是同样的功能,只是为了分层而使用这种方式,spring的注入是十分灵活的
我平时写业务,习惯写乐观锁,将事务和代码都控制在controller层,
因此在这一层直接获取session并进行操作,省略dao,service两层
不习惯的自行更改
注:本文配置方式会产生几个问题
springboot以这种方式配置的数据源,本质上是交给内置的tomcat来管理的,内置的tomcat来管理会涉及到连接池的问题。
如果数据库对于连接数量没有扩容,而内置tomcat的连接池没有配置,短时间内会产生大量连接而不销毁,会导致连接
拒绝,而报错。
可能报出的两个常见的错误,主要内容如下:
a:Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 14,595,596 milliseconds ago. The last packet sent successfully to the server was 14,595,612 milliseconds ago.
该错误的原因通常是因为session没有保证关闭引起的
b: o.a.tomcat.jdbc.pool.ConnectionPool : Unable to create initial connections of pool.
Data source rejected establishment of connection, message from server: "Too many connections"
本示例中使用的是MySql数据库,Threads_connected设置的数值是512,因此报上述错误。
该错误的原因不仅有Mysql数据库优化的问题,同时也有连接池管理配置的问题
以上列举问题将在后文中处理,更新后将在文尾插入连接!
6.测试
结果如下图:
以上!