DB数据源之SpringBoot+MyBatis踏坑过程(二)手工配置数据源与加载Mapper.xml扫描

时间:2022-09-06 22:27:41

DB数据源之SpringBoot+MyBatis踏坑过程(二)手工配置数据源与加载Mapper.xml扫描

liuyuhang原创,未经允许进制转载 

吐槽之后应该有所改了,该方式可以作为一种过渡方式来使用。

 

系列目录连接

DB数据源之SpringBoot+Mybatis踏坑过程实录(一)

1.环境说明

  • 初次使用springboot,时间有限,需要迅速搭建好架构,没有时间研究
  • 使用springboot过程中数据源无法获取;
  • 使用springboot过程中注解莫名其妙失效;
  • 用springboot过程中因为版本不懂,不扫描application.properties;
  • 使用springboot过程中因为版本不懂,不扫描mybatis的mapper.xml包;
  • springboot或spring注解使用十分不习惯或者还没有来得及深入学习的情况;

  假设有以上问题,又时间紧迫,建议使用本文手工配置方式!!

  springboot,parent 2.0.2.和1.5.3.都已经测试过,

  在java8和java7环境下测试过。前者配java8,后者配java7,

  使用MyEclipse 2017 C1 64x,MyEclipse 2016之前的版本无法使用java8

  pom.xml核心如下:

    <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!-- 添加MySQL依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 添加JDBC依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mybaits基础依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.0</version>
</dependency>
<!-- mybatis插件依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!-- mapper依赖 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>3.3.7</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

2.配置思路

  2.1.手工获取application.properties文件中的属性;

  2.2.创建数据源DataSource;

  2.3.注入数据源属性;

  2.4.创建SqlSessionFactory;

  2.5.SqlSessionFactory配置DataSource;

  2.6.SqlSessionFactory配置扫描MyBatis-config.xml文件;

  2.7.SqlSessionFactory配置扫描Mapper.xml所在包;

  2.8.获取session查询数据库进行测试;

3.所需类与结构

  3.0.application.properties文件与相应内容作为数据源;

  3.1.SysConfig类,用于获取application.properties中的property;

  3.2.DataConfig类,用于获取SqlSessionFactory;

  3.3.ExampleController类,用于测试;

  3.4.AppRun类,springboot的启动入口,将DataConfig初始化;

  3.5.mapper.xml内容

4.代码 

  4.0.application.properties部分内容段落:

  

 master.url=jdbc:mysql://qqq.jjj.xxx.iii:3306/master?characterEncoding=utf8
master.username=root
master.password=root
master.driver=com.mysql.jdbc.Driver
#master.driver-class-name=com.mysql.jdbc.Driver  一般是使用这个命名模式

  

  4.1.SysConfig类,代码如下:

 package com.FM.config;

 import java.io.IOException;
import java.util.Properties; import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils; /**
* 用于读取properties的类,基础配置文件名为application.properties,置于resources根目录下
* @author Liuyuhang
*/
public class SysConfig { private Properties properties; /**
* 修改无参构造,默认该类实例化的时候,加载配置文件中的内容,不做单例,因为配置文件可能更改
*/
public SysConfig() {
try {
Resource resource = new ClassPathResource("/application.properties");
properties = PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 获取属性,传入参数key
*/
public String getProperty(String key) {
return properties.getProperty(key);
}
}

  4.2.DataSourceConfig类,代码如下:

 package com.FM.config;

 import java.util.HashMap;

 import javax.sql.DataSource;

 import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
/**
* DataConfig,获取数据源,配置给SqlSessionFactory,并以此获取session
*
* @author liuyuhang
*/
public class DataConfig {
/**
* 缓存factory的map,作为单例SessionFactory存储
*/
public static HashMap<String, SqlSessionFactory> factoryMap = new HashMap<String, SqlSessionFactory>(); /**
* 构造器对缓存中的factory只实例化一次
* 不保证该单例能顺利执行,若看出问题,自行更改
* @throws Exception
*/
public DataConfig() {
System.out.println("out init sessionFactory:" + factoryMap);
if (factoryMap.isEmpty()) {
synchronized (factoryMap) {
if (factoryMap.isEmpty()) {
try {
SqlSessionFactory sessionFactory = getSessionFactory();
factoryMap.put("master", sessionFactory);
System.out.println("in init sessionFactory:" + factoryMap);
} catch (Exception e) {
System.out.println("该错误比较严重,出现在数据源无参构造函数中!!");
e.printStackTrace();
} }
} } } /**
* 手动获取sessionFactory用例
* @param dataSourcePerfix
* @return
* @throws Exception
*/
public SqlSessionFactory getSessionFactory() throws Exception {
SysConfig sc = new SysConfig();
String masterUrl = sc.getProperty("master.url");
String masterDriver = sc.getProperty("master.driver");
String masterUsername = sc.getProperty("master.username");
String masterPassword = sc.getProperty("master.password");
// 创建数据源
DataSourceBuilder create = DataSourceBuilder.create();
create.url(masterUrl);
create.driverClassName(masterDriver);
create.username(masterUsername);
create.password(masterPassword);
DataSource source = create.build();
// 创建sessionFactory
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(source);// 加载数据源
// 扫描mapper.xml
Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:com/FM/mapper/*.xml");
factoryBean.setMapperLocations(resources);
// 读取config
factoryBean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis-config.xml"));
SqlSessionFactory sessionFactory = factoryBean.getObject();
return sessionFactory;
} }

  4.3.ExampleController类,代码如下:

  package com.FM.controller;

  import java.util.HashMap;
import java.util.List;
import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import com.FM.config.DataConfig; /**
* Controler用于测试
* @author liuyuhang
*/
@RestController //等同于responseBody + controller双重注解
public class ExampleController { /**
* 手动创建session查询数据库用例,该方法可以创建多个sessionFactory,用多线程
* @param request
* @return
* @throws Exception
*/
@RequestMapping("/helloMybatis")
public List helloMybatis(HttpServletRequest request) throws Exception {
//数据源配置无参构造器
DataConfig dc = new DataConfig();
SqlSessionFactory sessionFactory = dc.getSessionFactory();//获取sessionfactory
SqlSession session = sessionFactory.openSession();//获取session
List<Object> selectList = session.selectList("com.FM.mapper.MySqlMapper.getUser");
return selectList;//自动转换为json
}
}

  4.4.AppRun类,代码如下:

 package com.FM;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.web.servlet.ServletComponentScan; import com.FM.config.DataConfig; @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) // 禁用默认的单数据源配置
@SpringBootConfiguration // springboot基础配置注解
@ServletComponentScan // springboot servlet filter
// @EnableConfigurationProperties//该注解于springboot1.5以上废弃
public class AppRun { public static void main(String[] args) throws Exception {
SpringApplication.run(AppRun.class, args);
DataConfig dc = new DataConfig();//初始化配置 }
}

  4.5.mapper.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.FM.mapper.MySqlMapper">
<!-- 随便写作为测试而已 -->
<resultMap id="getUserMap" type="java.util.Map">
<result column="id" property="id" jdbcType="INTEGER" javaType="int" />
<result column="username" property="username" jdbcType="VARCHAR" javaType="String" /><
<result column="password" property="password" jdbcType="VARCHAR" javaType="String" />
</resultMap>
<select id="getUser" parameterType="java.util.Map" resultMap="getUserMap">
select * from user
</select>
</mapper>

5.测试

  启动后控制台显示如下:

DB数据源之SpringBoot+MyBatis踏坑过程(二)手工配置数据源与加载Mapper.xml扫描

  浏览器输入    http://localhost:8080/helloMybatis

  控制台结果如下图:

DB数据源之SpringBoot+MyBatis踏坑过程(二)手工配置数据源与加载Mapper.xml扫描

  页面结果如下图:

DB数据源之SpringBoot+MyBatis踏坑过程(二)手工配置数据源与加载Mapper.xml扫描

6.总结

  spring注解一直是我饿心结,当我想将我的代码改成以注解方式来进行装配注入的时候,总是不行的,

  于是乎我学会了很多奇葩的手段,可能不主流。

  吐槽归吐槽,学习归学习,工作归工作,一码是一码!!!

  注:本文配置方式会产生几个问题

    要确保手动加载mapper.xml的扫描只扫描一次,否则是否会加载产生多个mapper加入VM管理并不确定,很可能数量很多。

    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"

        DB数据源之SpringBoot+MyBatis踏坑过程(二)手工配置数据源与加载Mapper.xml扫描

        本示例中使用的是MySql数据库,Threads_connected设置的数值是512,因此报上述错误。

        该错误的原因不仅有Mysql数据库优化的问题,同时也有连接池管理配置的问题

    以上列举问题将在后文中处理,更新后将在文尾插入连接!

  对于以上配置过程的springBoot的注解版,明日再更

 

休息!

以上!

DB数据源之SpringBoot+MyBatis踏坑过程(二)手工配置数据源与加载Mapper.xml扫描的更多相关文章

  1. DB数据源之SpringBoot&plus;Mybatis踏坑过程实录系列(一)

    DB数据源之SpringBoot+MyBatis踏坑过程(一) liuyuhang原创,未经允许进制转载 系列目录 DB数据源之SpringBoot+Mybatis踏坑过程实录(一) DB数据源之Sp ...

  2. DB数据源之SpringBoot&plus;MyBatis踏坑过程(三)手工&plus;半自动注解配置数据源与加载Mapper&period;xml扫描

    DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描 liuyuhang原创,未经允许禁止转载    系列目录连接 DB数据源之Spr ...

  3. DB数据源之SpringBoot&plus;MyBatis踏坑过程(四)没有使用连接池的后果

    DB数据源之SpringBoot+MyBatis踏坑过程(四)没有使用连接池的后果 liuyuhang原创,未经允许禁止转载  系列目录连接 DB数据源之SpringBoot+Mybatis踏坑过程实 ...

  4. DB数据源之SpringBoot&plus;MyBatis踏坑过程(五)手动使用Hikari连接池

    DB数据源之SpringBoot+MyBatis踏坑过程(五)手动使用Hikari连接池 liuyuhang原创,未经允许禁止转载  系列目录连接 DB数据源之SpringBoot+Mybatis踏坑 ...

  5. DB数据源之SpringBoot&plus;MyBatis踏坑过程(七)手动使用Tomcat连接池

    DB数据源之SpringBoot+MyBatis踏坑过程(七)手动使用Tomcat连接池 liuyuhang原创,未经允许禁止转载  系列目录连接 DB数据源之SpringBoot+Mybatis踏坑 ...

  6. DB数据源之SpringBoot&plus;MyBatis踏坑过程(六)mysql中查看连接,配置连接数量

    DB数据源之SpringBoot+MyBatis踏坑过程(六)mysql中查看连接,配置连接数量 liuyuhang原创,未经允许禁止转载 系列目录连接 DB数据源之SpringBoot+Mybati ...

  7. 在mybatis 中批量加载mapper&period;xml

    可以直接加载一个包文件名,将这个包里的所有*mapper.xml文件加载进来. 指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载: 必须按一定的标准:即xml文件和 ...

  8. Mybatis热加载Mapper&period;xml

    开发的时候,写Mybatis Mapper.xml文件的时候,每次修改SQL都需要重启服务,感觉十分麻烦,于是尝试写了一个Mybatis的Mapper.xml热加载. 能在修改Mapper.xml之后 ...

  9. Springboot &amp&semi; Mybatis 构建restful 服务二

    Springboot & Mybatis 构建restful 服务二 1 前置条件 成功执行完Springboot & Mybatis 构建restful 服务一 2 restful ...

随机推荐

  1. Atitit 边缘检测原理attilax总结

    Atitit 边缘检测原理attilax总结 1. 边缘检测的概念1 1.1. 边缘检测的用途1 2. 边缘检测方法分类1 3. 边缘检测的基本方法2 3.1. Roberts边缘检测算子2 3.2. ...

  2. C&num;中js文本提示

    Page.ClientScript 与 ClientScript 的关系 这二者实际上是一个东西,后者只是省略了 Page.都是获取用于管理脚本.注册脚本和向页添加脚本的 ClientScriptMa ...

  3. JSBinding &plus; SharpKit &sol; Coroutine支持

    首先得深入了解协程的原理.如果还没有完全理解,建议看这篇: http://wiki.unity3d.com/index.php/CoroutineScheduler 另外还要对 JavaScript ...

  4. Orchard官方文档翻译&lpar;六&rpar; 建立你的第一个Orchartd站点

    让我们开始 该主题内容已在Orchard1.8Release版本下测试通过. 这里通过向导式的教程来告诉大家Orchard的功能如何使用.如果你是第一次使用Orchard,该文档就是为你而准备的! O ...

  5. 【模板】【网络流】Dinic

    /* 唐代杜荀鹤 <小松> 自小刺头深草里,而今渐觉出蓬蒿. 时人不识凌云木,直待凌云始道高. */ #include <iostream> #include <cstd ...

  6. socket编程——一个简单的例子

    从一个简单的使用TCP例子开始socket编程,其基本步骤如下: server                                                  client ++++ ...

  7. centos下修改hostname&comma;ip&comma;netmask&comma;gateway&comma;dns

    http://itlab.idcquan.com/linux/set/917191.html http://jingyan.baidu.com/article/e4d08ffdd417660fd3f6 ...

  8. 网易云课堂js学习笔记

    javascript:用来在页面中编写特效的,和html/css一样都是由浏览器解析的 javascript语言: 一.js如何运行的(javaScript,jscript,vbscript,appl ...

  9. 9&period;28 h5日记

    9.28 1.transparent 透明的 颜色 2.placeholder 提示语 在input中使用 跟velue不同 3.写页面需要注意的 (1)页面一定要有层次,分清层次 (2)保证元素模块 ...

  10. C&num;实现的协同过滤算法

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace SlopeOn ...