zoukankan      html  css  js  c++  java
  • DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描

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

     

    liuyuhang原创,未经允许禁止转载 

     

    系列目录连接

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

    1.环境说明

      Springboot初学者,需要学习手工配置数据源,不需要多数据源配置的情况下

      建议使用本说明进行配置。

      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.创建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=utf8
    2 master.username=root
    3 master.password=root
    4 master.driver=com.mysql.jdbc.Driver
    5 #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,并以此获取session
    18  * @author liuyuhang
    19  */
    20 @Configuration//作为配置,交给spring管理
    21 public class DataConfig {
    22 
    23     @Autowired//注入SystemConfig类,注意变量名
    24     private SystemConfig systemConfig;
    25 
    26     /**
    27      * 手动获取sessionFactory并配置用例
    28      * @param dataSourcePerfix
    29      * @return
    30      * @throws Exception
    31      */
    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         // 创建sessionFactory
    46         SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
    47         factoryBean.setDataSource(source);// 加载数据源
    48         // 扫描mapper.xml
    49         Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:com/FM/mapper/*.xml");
    50         factoryBean.setMapperLocations(resources);
    51         // 读取config
    52         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     @Autowired
    22     DataConfig dataConfig;
    23 
    24     /**
    25      * 手动创建session查询数据库用例,该方法可以创建多个sessionFactory,用多线程
    26      * @param request
    27      * @return
    28      * @throws Exception
    29      */
    30     @RequestMapping("/helloMybatis")
    31     public List helloMybatis(HttpServletRequest request) throws Exception {
    32         SqlSessionFactory sessionFactory = dataConfig.getSessionFactory();//获取sessionfactory
    33         SqlSession session = sessionFactory.openSession();//获取session
    34         List<Object> selectList = session.selectList("com.FM.mapper.MySqlMapper.getUser");
    35         return selectList;//自动转换为json
    36     }
      }

      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 filter
    12 // @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.测试

      结果如下图:

    以上!

  • 相关阅读:
    解压缩编码列表
    按既定顺序创建目标数组
    整数的各位积和之差
    好数对的数目
    拿硬币
    设计 Goal 解析器
    【求助】win 2008 R2 远程桌面多用户,破解最大连接数2的限制
    Java 字符串拼接 五种方法的性能比较分析 从执行100次到90万次
    Java abstract class 和 interface 的区别
    忘记BIOS超级管理员密码,怎么破解?
  • 原文地址:https://www.cnblogs.com/liuyuhangCastle/p/9630681.html
Copyright © 2011-2022 走看看