前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot(3)-使用mysql详解

Spring Boot(3)-使用mysql详解

作者头像
黄规速
发布2022-04-14 17:02:10
3.5K0
发布2022-04-14 17:02:10
举报

Spring Boot构建的Web应用中,基于MYSQL数据库的几种数据库连接方式进行介绍,包括JDBC、JPA、MyBatis、多数据源和事务。

Spring Boot的Web应用中使用Mysq数据库,也充分展示Spring Boot的优势(尽可能少的代码和配置)。数据访问层我们将使用Spring Data JPA和Hibernate(JPA的实现之一)。

注意:如果你想JDBC和JPA可以一起使用,Spring Boot 是支持的,你只需要把JDBC和JPA的依赖都添加在pom.xml 中即可。无需其他特殊处理。

我们先看看java应用使用mysql:

一、JAVA应用使用mysql

1、JDBC (Java DataBase Connectivity/Java数据库连接 )[原始手工]

java应用接口访问数据库的Java API规范。为各种数据库(mysql、oracle),提供一个统一的接口,应用程序通过JDBC执行各种SQL(select、insert)操作。不同的数据库厂商都有自己的实现类,统一规范也就有了数据库驱动。

  • 优点:运行期:快捷、高效
  • 缺点:编辑器:代码量大、繁琐异常处理、不支持数据库跨平台

2、JdbcTemplate [半自动化]

JDBC已经能够满足大部分用户最基本的需求,但是接使用原始的JDBC操作数据库过于低效,必须自己来管理数据库资源如:获取PreparedStatement,设置SQL语句参数,关闭连接等步骤。

JdbcTemplate是Spring框架自带的对JDBC操作的封装,目的是使JDBC更加易于使用,我们只需要提供SQL语句和提取结果。它处理了资源的建立和释放,帮助我们避免一些常见的错误,比如忘了总要关闭连接。

优点:

  • 运行期,简单效率快
  • 内嵌Spring框架中,支持基于AOP的声明式事务
  • 是spring对 jdbc操作数据库进行的封装,使得开发者可以直接在java文件中 编写sql,无需配置xml文件

缺点:

  • 必须于Spring框架结合在一起使用、不支持数据库跨平台、默认没有缓存
  • result结果集遍历时,需要硬编码获取表数据的映射,不利于维护。

使用JdbcTemplate时候:频繁创建关闭连接资源,影响数据库的性能。解决办法:使用数据库连接池,管理数据库的连接。

3、MyBatis [半自动化ORM]

MyBatis的前身就是iBatis,iBatis本是apache的一个开源项目,2010年这个项目由apahce sofeware foundation 迁移到了google code,并且改名。MyBatis提供的持久层框架包括SQL Maps和Dao,允许开发人员直接编写SQL(更好灵活).(Sql操作方式)

它消除了JDBC大量冗余的代码,不需要手动开关连接。因为操作简单,提高开发效率,节约不必要浪费的时间。

  • 优点: 高效、支持动态、复杂的SQL构建, 支持与Spring整合和AOP事务、结果集做了轻量级Mapper封装、支持缓存
  • 缺点:不支持数据库跨平台, 还是需要自己写SQL语句。过于笨重,比如在多表联合查询时相当繁琐。

通过 mybatis提供的映射方式,半自动的生成sql,大部分还是需要程序员编写sql。因此MyBatis 并不是一个完整的ORM框架

4、JPA(Java Persistence API/Java持久层接口规范)[ORM规范]

JPA全称为Java Persistence API(Java持久层API),它是Sun公司在JavaEE 5中提出的Java持久化规范。

JPA 是ORM(Object Relational Mapping/对象关系映射)的一个标准规范,ORM的作用是在数据库表与Java对象之间建立映射,理论上来说有ORM就无需直接通过SQL操作数据库了,通过Java对象即可,这样会方便很多,Hibernate是实现JPA标准的一个有名例子。但JPA也是建立在JDBC之上,也是通过JDBC访问数据库。本身是一种ORM规范,不是ORM框架.很多ORM框架都是实现了JPA的规范,如:Hibernate、EclipseLink。

JPA为我们提供了以下规范:

1. ORM映射元数据:JPA支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中

2. JPA 的API:用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发人员不用再写SQL了

3. JPQL查询语言:通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。

5、Spring Data JPA [ORM抽象]

Spring Data JPA是在实现了JPA规范的基础上封装的一套 JPA 应用框架,虽然ORM框架都实现了JPA规范,但是在不同的ORM框架之间切换仍然需要编写不同的代码,而使用Spring Data JPA能够方便大家在不同的ORM框架之间进行切换而不需要更改代码。Spring Data JPA旨在通过将统一ORM框架的访问持久层的操作,来提高开发人的效率。

Spring Data JPA给我们提供的主要的类和接口 Repository 接口: Repository CrudRepository JpaRepository Repository 实现类: SimpleJpaRepository QueryDslJpaRepository

6、Hibernate[完整ORM实现]

目前比较流行的ORM框架,设计灵巧,文档丰富(完全自动操作),只是性能不好控制(自己去控制性能,不是很好控制)。Hibernate是一个完整的ORM框架,常规CRUD我们不需要写一句SQL;

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用。

7、JPA、Spring Data JPA和Hibernate的关系

Hibernate其实是JPA的一种实现,而Spring Data JPA是一个JPA数据访问抽象。也就是说Spring Data JPA不是一个实现或JPA提供的程序,它只是一个抽象层,主要用于减少为各种持久层存储实现数据访问层所需的样板代码量。但是它还是需要JPA提供实现程序,其实Spring Data JPA底层就是使用的 Hibernate实现。

8、JPA 和Hibernate 和 Mybatis的区别

JPA:ORM规范,各大ORM框架实现这个规范。可以自动建表。

Hibernate:是完整的ORM,不需要我们写sql,框架比较重,学习成本比较高,性能不好控制,功能强大且文档丰富。

Mybatis:不是完整的ORM,程序员需要自己去写全部的SQL,轻量级框架,学习成本低,性能好控制。不能自动建表。虽然mybatis经常被和Hibernate比较,但mybatis不是JPA的一个实现。mybatis可以理解为加强版的SQL,实现了诸如动态SQL、结果集映射等,高效又不失灵活。

java使用数据库相关组件/规范的关系如下:

二、JPA方式:Spring Data Jpa

Spring Data Jpa 极大简化了数据库访问层代码,简单几步:

1. 添加pom.xml依赖 2. 配置数据库连接 3. 编写Entity类,依照JPA规范,定义实体 4. 编写Repository接口,依靠SpringData规范,定义数据访问接口(注意,只要接口,不需要任何实现) 5. 写一小陀配置文件 (Spring Scheme配置方式极大地简化了配置方式)

1.添加依赖 :Maven pom.xml文件

要使用MySQL,需要引入对应的mysql connector,因此,首先在pom文件中添加如下依赖:

代码语言:javascript
复制
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
  </dependency>
</dependencies>

2.属性配置文件application.properties

在src/main/resources/application.properties中设置数据源和jpa配置,不需要另外的XML配置和Java配置。

代码语言:javascript
复制
spring.datasource.url = jdbc:mysql://localhost:3306/test
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy

# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

#Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy

# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

简单说明

hibernate的ddl-auto=update配置表名,数据库的表和列会自动创建(根据Java实体的熟悉), 这里 可以看到更多得hibernate配置。如果希望通过Hibernate依靠Entity类自动创建数据库和数据表,则还需要加上配置项——spring.jpa.hibernate.ddl-auto=create-drop

PS:在生产环境中不要使用create-drop,这样会在程序启动时先删除旧的,再自动创建新的,最好使用update;还可以通过设置 spring.jpa.show-sql = true来显示自动创建表的SQL语句,通过 spring.jpa.database = MYSQL指定具体的数据,如果不明确指定Spring boot会根据classpath中的依赖项自动配置。

在Spring项目中,如果数据比较简单,我们可以考虑使用JdbcTemplate,而不是直接定义Datasource,配置jdbc的代码如下:

代码语言:javascript
复制
@Autowired
private JdbcTemplate jdbcTemplate;

只要定义了上面这个代码,Spring Boot会自动创建一个Datasource对象,然后再创建一个jdbctemplate对象来管理datasource,通过jdbctemplate操作数据库可以减少大量模板代码。如果你对SpringBoot的原理感兴趣,可以在org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration类中查看其具体实现。

3、实体

我们本例是一个城市相关系统:

数据库中应该具备以下领域对象(domain object)

创建一个City实体。User实体和Mysql数据库的city表相对应。

首先在src\main\java\com\city\data\下建立包domain,然后再在这个包下建立相应的实体类

代码语言:javascript
复制
package com.city.data.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
@Table(name = "city")
public class City implements Serializable {
	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue
	private int cityId;
	
	@Column(nullable = false)
	private String name;
	@Column(nullable = false)
	private int provinceId;
	
	public City() {
	}
	public City( int cityId) {
		super();
		this.cityId = cityId;
	}
	public int  getCityId() {  
	      return cityId;  
	 }  
	public void setCityId(int id) {  
	     this.cityId = id;  
	}    
        ......
	
}

4.实体的数据访问层Dao

创建完实体类,还需要创建CityRepository接口,该接口继承自Repository,这个接口放在src\main\java\com\city\data\service包中,具体代码如下:

代码语言:javascript
复制
package com.city.data.service;
/**
 *DAO层
 */
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;

import com.city.data.domain.City;
interface CityRepository extends Repository<City, Long> {
	City findByName(String name);
}

我们都没有写一行SQL语句,也没有在代码中涉及到数据库连接、建立查询等方面的内容。只有实体类上的各种注解表明我们在于数据库做交互:@Entity,@Repository,@Id,@GeneratedValue,@ManyToOne,@ManyToMany以及@OneToMany,这些注解属于Java Persistance API。我们通过Respository接口的子接口与数据库交互,同时由Spring建立对象与数据库表、数据库表中的数据之间的映射关系。下面依次说明这些注解的含义和使用:

  • @Entity,说明被这个注解修饰的类应该与一张数据库表相对应,表的名称可以由类名推断,当然了,也可以明确配置,只要加上@Table(name = "books")即可。需要特别注意,每个Entity类都应该有一个protected访问级别的无参构造函数,用于给Hibernate提供初始化的入口。
  • @Id and @GeneratedValue:@Id注解修饰的属性应该作为表中的主键处理、@GeneratedValue修饰的属性应该由数据库自动生成,而不需要明确指定。
  • @ManyToOne, @ManyToMany表明具体的数据存放在其他表中,在这个例子里,书和作者是多对一的关系,书和出版社是多对一的关系,因此book表中的author和publisher相当于数据表中的外键;并且在Publisher中通过@OneToMany(mapped = "publisher")定义一个反向关联(1——>n),表明book类中的publisher属性与这里的books形成对应关系。
  • @Repository 用来表示访问数据库并操作数据的接口,同时它修饰的接口也可以被component scan机制探测到并注册为bean,这样就可以在其他模块中通过@Autowired织入。

我们可以添加自定义的接口函数,JPA会提供对应的SQL查询,例如,在本例中的CityRepository中可以增加findByName(String name)函数,JPA会自动创建对应的SQL查询——根据name查询城市,这种将方法名转换为SQL语句的机制十分方便且功能强大,例如你可以增加类似findByNameIgnoringCase(String name)这种复杂查询。

5.业务逻辑层service

接口放在 src\main\java\com\city\data\service 包中,具体代码如下:

代码语言:javascript
复制
package com.city.data.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;


import com.city.data.domain.City;

@Component("cityService")
@Transactional
public class CityServiceImpl implements CityService {

	private final CityRepository cityRepository;
	@Autowired
	public CityServiceImpl(CityRepository cityRepository) {
		this.cityRepository = cityRepository;
	}


	//@Override
	public City getCity(String cityName) {
		Assert.notNull(cityName, "Name must not be null");
		return this.cityRepository.findByName(cityName);
	}
}	

6.测试的控制器CityController

新建一个查询控制器CityController,接口放在src\main\java\com\city\data\web包中,具体代码如下:

代码语言:javascript
复制
package com.city.data.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;


import com.city.data.service.CityService;
import com.city.data.domain.City;;


//原始格式
//@Controller
//json格式
@RestController
public class CityController {


	@Autowired
	private CityService cityService;


	@RequestMapping("/")
	@ResponseBody
	@Transactional(readOnly = true)
	public int getBeijing() {
		//return "helloWorld";
		return this.cityService.getCity("beijing").getCityId();
	}

	/**
	 * @PathVariable是用来获得请求url中的动态参数的
	 * @param name
	 * @return
	 */
	 @RequestMapping(value = "/{name}", method = RequestMethod.GET)
	public Map<String, Object> getCity( @PathVariable String name) {
	     City city =  this.cityService.getCity(name);

	    Map<String, Object> response = new LinkedHashMap<>();
	    response.put("msg", "get city with name(" + name +")");
	    response.put("city", city);
	    return response;
	 }

}

你可以使用浏览器访问url http://127.0.0.1:8080

三、使用jdbctemplate

1、属性配置文件

application.properties

代码语言:javascript
复制
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driverClassName=com.mysql.jdbc.Driver

如果使用JNDI,则可以替代 spring.datasource 的 url、username、password,如:

代码语言:javascript
复制
spring.datasource.jndi-name=java:tomcat/datasources/example 

值得一提的是,无论是Spring Boot默认的DataSource配置还是你自己的DataSource bean,都会引用到外部属性文件中的属性配置。所以假设你自定义的DataSource bean,你可以在定义bean时设置属性,也可以在属性文件中,以“spring.datasource.*”的方式使属性配置外部化。

2、pom.xml 配置maven依赖

代码语言:javascript
复制
        <!-- MYSQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
         </dependency>
         <!-- Spring Boot JDBC -->
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
          </dependency>

3、Java代码范例

CityServiceImpl.java

注意,使用jdbc要有变量

@Autowired private JdbcTemplate jdbcTemplate;

代码语言:javascript
复制
package com.city.data.service;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;


import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

import com.city.data.domain.City;
import com.city.data.common.JdbcSQL;

@Component("cityService")
@Transactional

public class CityServiceImpl implements CityService {

	private final CityRepository cityRepository;

	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	@Autowired
	public CityServiceImpl(CityRepository cityRepository) {
		this.cityRepository = cityRepository;

	}
	
	/**
	 * 
	 */
	 public List<City> getCityList(CitySearchCriteria criteria){
	        String sql = "SELECT *  FROM city";
	        String cityName = criteria.getName();
	        int  provinceid  = criteria.getProvinceId();
	        String where  = "";
	        if(provinceid > 0 ) {
	        	where += " province_id=" + provinceid;
	        }
	        if(StringUtils.hasLength(cityName) ) {
	        	where += " name=" + cityName;
	        }
	        if(!where.isEmpty() ) {
	        	sql =sql + " where "  + where;
	        }
	        
	        
	        return (List<City>) jdbcTemplate.query(sql, new RowMapper<City>(){
	            @Override
	            public City mapRow(ResultSet rs, int rowNum) throws SQLException {
	                City  city = new City();
	                city.setCityId(rs.getInt("city_id"));
	                city.setName(rs.getString("name"));
	                city.setMap(rs.getString("map"));
	                city.setProvinceId(rs.getInt("province_id"));
	                return city;
	            }

	        });
	    }


	
	public  List getCityList2(Map<String, Object> condition){
		JdbcSQL jdbcSQL  =new JdbcSQL();
		jdbcSQL.setTable("city");
		jdbcSQL.setConditon(condition);
		return jdbcSQL.selectByCondition();
	}

	public  List<Map<String, Object>> getCityList2(Map<String, Object> condition) {
		 	String sql = "select * from city";
	        return jdbcTemplate.queryForList(sql);
	        
	}

}

然后启动项目,访问地址: http://localhost:8080/

4、连接池说明

Tomcat7之前,Tomcat本质应用了DBCP连接池技术来实现的JDBC数据源,但在Tomcat7之后,Tomcat提供了新的JDBC连接池方案,作为DBCP的替换或备选方案,解决了许多之前使用DBCP的不利之处,并提高了性能。详细请参考:http://wiki.jikexueyuan.com/project/tomcat/tomcat-jdbc-pool.html

Spring Boot为我们准备了最佳的数据库连接池方案,只需要在属性文件(例如application.properties)中配置需要的连接池参数即可。 我们使用Tomcat数据源连接池,需要依赖tomcat-jdbc,只要应用中添加了spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa依赖,则无需担心这点,因为将会自动添加 tomcat-jdbc 依赖。 假如我们想用其他方式的连接池技术,只要配置自己的DataSource bean,即可覆盖Spring Boot的自动配置。

请看我的数据源配置:

代码语言:javascript
复制
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
spring.datasource.validation-query=SELECT 1
spring.datasource.test-on-borrow=false
spring.datasource.test-while-idle=true
spring.datasource.time-between-eviction-runs-millis=18800
spring.datasource.jdbc-interceptors=ConnectionState;SlowQueryReport(threshold=0)

配置过连接池的开发人员对这些属性的意义都有所认识。

我们打开DEBUG日志输出,logback.xml 中添加:

代码语言:javascript
复制
<logger name="org.springframework.boot" level="DEBUG"/>

然后启动项目,注意观察日志输出,如下图中会显示自动启用了连接池: 我在上面的数据源配置中添加了过滤器,并设置了延迟时间为0(故意设置很低,实际项目中请修改):

代码语言:javascript
复制
spring.datasource.jdbc-interceptors=ConnectionState;SlowQueryReport(threshold=0)

这个时候,我们访问 http://localhost:8080/myspringboot/stu/list 观察日志,会发现框架自动将大于该时间的数据查询进行警告输出,如下:

问题: 1、连接池的连接在最大生存时间 时间内没有请求数据库,再次使用的连接就报错。 spring.datasource.max-lifetime=86400000 (单位 毫秒) 2、如果连接池的连接长时间不使用(可能时间短于max-lifetime),但是超过mysql的wait_timeout的时间,mysql也会进行回收这个连接的。

my.cnf wait_timeout=31536000 interactive_timeout=31536000

Mysql服务器默认的“wait_timeout”是8小时【也就是默认的值默认是28800秒】,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection,通俗的讲就是一个连接在8小时内没有活动,就会自动断开该连接。 wait timeout的值可以设定,但最多只能是2147483,不能再大了。也就是约24.85天 .

四、使用mybatis


Mybatis作为近年来最流行的ORM框架,其特点:

1、易于上手和掌握。 2、sql可以写在xml里,便于统一管理和优化。 3、sql与程序代码的解耦。 4、提供映射标签,支持对象与数据库的orm字段关系映射 5、 提供对象关系映射标签,支持对象关系组建维护 6、提供xml标签,支持编写动态sql。

总的来说,虽然jdbc性能稍好点,但mybatis提高了开发效率,使开发变得简单。不过使用jdbc封装成工具类后也很好用。

1、数据库表:

CREATE TABLE `user` ( `uid` bigint(20) NOT NULL AUTO_INCREMENT, `username` varchar(120) NOT NULL COMMENT 'username', `password` varchar(255) NOT NULL COMMENT 'password', `ctime` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

2. Springmvc集成Mybatis

我们先了解Springmvc集成Mybatis,然后就知道springboot集成Mybatis简单了很多。

1)、项目添加mybatis依赖

在pom.xml文件中增加如下:

代码语言:javascript
复制
<!-- jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>
<!-- MyBatis相关 -->

<dependency> <!-- 导入Mysql数据库链接jar包 -->
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.6</version>
</dependency>

<dependency><!-- mybatis核心包 -->
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.3.1</version>
</dependency>
<dependency><!-- mybatis/spring包 -->
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.2.5</version>
</dependency>

<dependency><!-- 导入dbcp的jar包,用来在applicationContext.xml中配置数据库 -->
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>
<!-- end -->

2)、配置mybatis

可以单独使用文档spring-mybatis.xml来配置mybatis。主要内容就是自动扫描,自动注入,配置数据库。

\src\main\resources/spring-mybatis.xml:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd
                        http://www.springframework.org/schema/mvc
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <context:component-scan base-package="com.demo.springmvc.drm.dao"></context:component-scan>
    <!--  引入配置文件:加载jdbc.properties文件中的内容,jdbcproperties文件中的key要有一定的特殊规则 -->
    <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:jdbc.properties" />
    </bean>
    <!-- 配置数据源,使用dbcp连接池 -->
    <!--创建nlp_tuling数据源 -->
    <bean id="dataSourceDemo" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!-- 数据库连接池 -->
        <property name="defaultAutoCommit" value="false" />
        <!-- 连接池中可同时连接的最大的连接数(默认值为8,调整为20,高峰单机器在20并发左右,自己根据应用场景定) -->
        <property name="maxActive" value="25"></property>
        <!-- 连接池启动时创建的初始化连接数量(默认值为0) -->
        <property name="initialSize" value="15"></property>
        <!-- 最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待(默认为无限,调整为60000ms,避免因线程池不够用,而导致请求被无限制挂起) -->
        <property name="maxWait" value="60000"></property>
        <!-- 连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制(默认为8个,maxIdle不能设置太小,因为假如在高负载的情况下,连接的打开时间比关闭的时间快,会引起连接池中idle的个数
            上升超过maxIdle,而造成频繁的连接销毁和创建,类似于jvm参数中的Xmx设置) -->
        <property name="maxIdle" value="20"></property>
        <!-- 连接池中最小的空闲的连接数,低于这个数量会被创建新的连接(默认为0,调整为5,该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大,因为在机器很空闲的时候,也会创建低于minidle个数的连接,类似于jvm参数中的Xmn设置) -->
        <property name="minIdle" value="15"></property>
        <!-- 超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收(默认为false,调整为true) -->
        <property name="removeAbandoned" value="true"></property>
        <!-- 超过时间限制,回收没有用(废弃)的连接(默认为 300秒,调整为180) -->
        <property name="removeAbandonedTimeout" value="180"></property>
    </bean>

    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
    <bean id="dataSourceSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSourceDemo" />
        <!-- 自动扫描mapping.xml文件 -->
        <property name="mapperLocations" value="classpath*:mapper/*Mapper.xml"></property>
    </bean>


    <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.demo.springmvc.drm.dao" />
        <property name="sqlSessionFactoryBeanName" value="dataSourceSqlSessionFactory"></property>
    </bean>

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
    <!--<bean id="transactionManager"-->
          <!--class="org.springframework.jdbc.datasource.DataSourceTransactionManager">-->
        <!--<property name="dataSource" ref="dataSourceDemo" />-->
    <!--</bean>-->
</beans>
代码语言:javascript
复制
然后在xxx-servlet.xml引入文件
<import resource="classpath*:spring-mybatis.xml" />

3)、创建UserEntity

代码语言:javascript
复制
package com.demo.springmvc.drm.entity;

public class UserEntity {
    private Integer uid;
    private String userName;
    private String password;
    public Integer getUid() {
        return uid;
    }
    public void setUid(Integer uid) {
        this.uid = uid;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName == null ? null : userName.trim();
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }
    @Override
    public String toString() {
        return "User [id=" + uid + ", userName=" + userName + ", password="
                + password + "]";
    }

}

4)、创建dao

IUserDao接口

代码语言:javascript
复制
package com.demo.springmvc.drm.dao;
import com.demo.springmvc.drm.entity.UserEntity;
import org.springframework.stereotype.Service;

@Service
public interface IUserDao {

    public UserEntity getUserByUid(Integer uid);
    public Integer updateUser(UserEntity userEntity);
    public Integer insertUser(UserEntity userEntity);
}

UserDao

代码语言:javascript
复制
package com.demo.springmvc.drm.dao.impl;

import com.demo.springmvc.drm.dao.IUserDao;
import com.demo.springmvc.drm.entity.UserEntity;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class UserDao extends SqlSessionDaoSupport implements IUserDao {
    @Autowired
    @Override
    public void setSqlSessionFactory( SqlSessionFactory sqlSessionFactory){
        super.setSqlSessionFactory(sqlSessionFactory);
    }

    @Override
    public UserEntity getUserByUid(Integer uid) {
        return this.getSqlSession().selectOne("selectUser", uid);
    }

    @Override
    public Integer updateUser(UserEntity userEntity) {
        return this.getSqlSession().update("updateUser", userEntity);
    }

    @Override
    public Integer insertUser(UserEntity userEntity) {
        return this.getSqlSession().update("insertUser", userEntity);
    }

}

5)、创建mapper配置

src\main\resources\mapper\UserMapper.xml:

代码语言:javascript
复制
<?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.demo.springmvc.drm.dao.impl.UserDaoImpl">
<select id="selectUser" resultType="com.demo.springmvc.drm.entity.UserEntity">
    SELECT * FROM user WHERE uid = #{uid};
</select>
<update id="updateUser" parameterType="com.demo.springmvc.drm.entity.UserEntity">
    UPDATE user SET username =#{username} WHERE uid = #{uid};
</update>
<insert id="insertUser" parameterType="com.demo.springmvc.drm.entity.UserEntity">
    INSERT  INTO user (username, password,ctime) VALUES (#{username},#{password},now());
</insert>
</mapper>

6)、service和controller测试

UserService :

代码语言:javascript
复制
package com.demo.springmvc.service;

import com.demo.springmvc.drm.dao.IUserDao;
import com.demo.springmvc.drm.entity.UserEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Created by huangguisu on 2020/8/5.
 */
@Service
public class UserService {
    @Autowired
    private IUserDao userDao;

    public UserEntity getUserById(Integer userId) {
        return this.userDao.getUserByUid(userId);
    }
}

UserController:

代码语言:javascript
复制
package com.demo.springmvc.controller;
import com.demo.springmvc.drm.entity.UserEntity;
import com.demo.springmvc.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/user")

public class UserController {
    @Autowired
    UserService userService;
    @RequestMapping("/")
    @ResponseBody
    public String index() {
        return "Hello world";
    }

    @RequestMapping("/getuser/")
    @ResponseBody
    public UserEntity getUser(@RequestParam Integer uid) {

        UserEntity userEntity = userService.getUserById(uid);
        return userEntity;
    }


}

3. Spring boot集成Mybatis:使用xml配置【sql和代码解耦】

xml配置保持映射文件的老传统,优化主要体现在不需要实现dao的实现层【只需要定义接口类和方法】,系统会自动根据方法名在映射文件中找对应的sql【由namespace和名称坐标确定】。

1)、添加mybatis依赖

在pom.xml文件中增加如下:

引入mybatis-spring-boot-starter和mysql-connector-java

代码语言:javascript
复制
<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.0.0</version>
</dependency>

2)、数据源配置

在resource文件夹下添加application.properties配置文件并输入数据库参数,如下:

spring.datasource.driverClassName = com.mysql.jdbc.Driver spring.datasource.url = jdbc:mysql://192.168.10.34:3306/test spring.datasource.username = test spring.datasource.password = test123 spring.datasource.max-idle=10 spring.datasource.max-wait=1000 spring.datasource.min-idle=5 spring.datasource.initial-size=5

3)、映射器:添加mapper的接口

定义映射器

spring boot简化了很多Mybatis复杂的xml配置,但是作为Mybatis的四大组件之一的映射器是不可或缺的。可以这样理解,一个映射器 = 一个接口 + 一个xml文件。

在dao目录中创建IUserDao 接口. 使用@Mapper确保在IoC容器初始化

代码语言:javascript
复制
package com.demo.springboot2.web.drm.dao;

import com.demo.springboot2.web.drm.UserEntity;
import org.springframework.stereotype.Service;

@Service
public interface IUserDao {
    public UserEntity getUserByUid(Integer uid);
    public Integer updateUser(UserEntity userEntity);
    public Integer insertUser(UserEntity userEntity);
}

4)、映射器:mapper配置xml文件

application.properties新增以下配置

代码语言:javascript
复制
mybatis.config-location=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

UserMapper.xml:

代码语言:javascript
复制
<?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.demo.springboot2.web.drm.dao.IUserDao">
    <!--<resultMap id="BaseResultMap" type="com.demo.springboot2.web.drm.entity.UserEntity" >-->
        <!--<id column="uid" property="uid" jdbcType="BIGINT" />-->
        <!--<result column="username" property="username" jdbcType="VARCHAR" />-->
        <!--<result column="password" property="password" jdbcType="VARCHAR" />-->
    <!--</resultMap>-->

    <sql id="Base_Column_List" >
        uid, username, password
    </sql>

    <select id="getUserByUid"  resultType="com.demo.springboot2.web.drm.entity.UserEntity" >
        SELECT
        <include refid="Base_Column_List" />
        FROM user
        WHERE uid = #{uid}
    </select>

    <insert id="insertUser" parameterType="com.demo.springboot2.web.drm.entity.UserEntity" >
        INSERT INTO
        user
        (username,password)
        VALUES
        (#{username}, #{password})
    </insert>

    <update id="updateUser" parameterType="com.demo.springboot2.web.drm.entity.UserEntity" >
        UPDATE
        user
        SET
        <if test="username != null">userName = #{username},</if>
        <if test="password != null">passWord = #{password},</if>
        WHERE
        uid = #{uid}
    </update>
</mapper>

指定了mybatis基础配置文件和实体类映射文件的地址

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer" />
        <typeAlias alias="Long" type="java.lang.Long" />
        <typeAlias alias="HashMap" type="java.util.HashMap" />
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
        <typeAlias alias="ArrayList" type="java.util.ArrayList" />
        <typeAlias alias="LinkedList" type="java.util.LinkedList" />
    </typeAliases>
</configuration>

3. Spring boot集成Mybatis:注解【耦合性高】

1)、 添加相关maven文件【同上】

2)、application.properties 相关配置【同上】

在启动类中添加对mapper包扫描@MapperScan,如果没有添加mapp包扫描。在Mapper类添加注解@Mapper

代码语言:javascript
复制
@SpringBootApplication
@MapperScan("com.demo.springboot2.web.drm.dao")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3)、开发Mapper接口

通过注解@Select设置sql。

代码语言:javascript
复制
package com.demo.springboot2.web.drm.dao;

import com.demo.springboot2.web.drm.entity.UserEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.*;
@Mapper
public interface IUserDao2 {

    @Select("SELECT * FROM user WHERE uid = #{uid}")
//    @Results({
//            @Result(property = "userSex",  column = "user_sex", javaType = UserSexEnum.class),
//            @Result(property = "nickName", column = "nick_name")
//    })
    UserEntity getOne(Integer uid);
}

4)、使用DAO

上面就基本完成了相关dao层开发,使用的时候当作普通的类注入进入就可以:

代码语言:javascript
复制
package com.demo.springboot2.web.controller;

import com.demo.springboot2.web.drm.dao.IUserDao2;
import com.demo.springboot2.web.drm.entity.UserEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class TestController {
    @RequestMapping("/")
    @ResponseBody
    public String index() {
        return "Hello world";
    }


    @Autowired
    private IUserDao2 iUserDao2;

    @RequestMapping("/getuser2/")
    @ResponseBody
    public UserEntity getUser2(@RequestParam Integer uid) {
        UserEntity userEntity = iUserDao2.getOne(uid);
        return userEntity;
    }
}

五、SpringBoot2整合Druid数据源


Druid是阿里巴巴开源的一个数据源,主要用于java数据库连接池,相比spring推荐的DBCP和hibernate推荐的C3P0、Proxool数据库连接池,Druid在市场上占有绝对的优势;

虽说 HikariCP 的性能比 Druid 高,但是因为 Druid 包括很多维度的统计和分析功能,所以大家都选择使用Druid 的更多;

关于文档可以从官网知道,可以参考https://github.com/alibaba/druid

主要特点:

  • Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。
  • Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池。
  • Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源。

如何使用:

1、添加Druid依赖

代码语言:javascript
复制
<!--alibaba druid datasource-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>${druid-version}</version>
</dependency>

2) 添加配置

直接使用springboot的properties配置文件application.properties:

代码语言:javascript
复制
#DataSource settings
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url = jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF8
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver

#连接池的配置信息
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20

# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000

# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000

# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false

# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20

# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.filters=stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

#是否启用StatFilter默认值true
spring.datasource.druid.web-stat-filter.enabled=true
#多个白名单IP以逗号分隔
druid.monitor.allow=127.0.0.1
#多个黑名单IP以逗号分隔
druid.monitor.deny=0.0.0.0
#druid监控管理界面登录帐号
druid.monitor.loginUsername=admin
#druid监控管理界面登录密码
druid.monitor.loginPassword=password
#是否开启重置功能
druid.monitor.resetEnable=false

参数

默认值

解释

initialSize

3

初始化配置连接数

minIdle

3

最小连接数

maxActive

15

最大连接数

maxWait

5000

获取连接超时时间(单位:ms)

timeBetweenEvictionRunsMillis

90000

连接有效性检测时间(单位:ms)

testOnBorrow

false

获取连接检测

testOnReturn

false

归还连接检测

minEvictableIdleTimeMillis

1800000

最大空闲时间(单位ms)

testWhileIdle

true

在获取连接后,确定是否要进行连接空间时间的检查

  • 配置说明:

1:minEvictableIdleTimeMillis(最大空闲时间):默认为30分钟,配置里面不进行设置。 2:testOnBorrow ,testOnReturn 默认为关闭,可以设置为不配置。 3:testWhileIdle(在获取连接后,确定是否要进行连接空闲时间的检查)。默认为true。配置里面不再进行设置。

  • 流程说明:

1:在第一次调用connection的时候,才会进行 initialSize的初始化。 2:心跳检测时间线程,会休眠timeBetweenEvictionRunsMillis时间,然后只对(没有borrow的线程 减去 minIdle)的线程进行检查,如果空闲时间大于minEvictableIdleTimeMillis则进行close。 3:testWhileIdle必须设置为true,在获取到连接后,先检查testOnBorrow,然后再判定testwhileIdle,如果连接空闲时间大于timeBetweenEvictionRunsMillis,则会进行心跳检测。 4:不需要配置validationQuery,如果不配置的情况下会走ping命令,性能更高。 5:连接保存在数组里面,获取连接的时候,获取数组的最后一位。在imeBetweenEvictionRunsMillis时是从前往后进行检查连接的有效性。

3)、数据源配置类

代码语言:javascript
复制
package com.javademo.demo.web.database;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;
import java.util.HashMap;
@Configuration
/**
 * 如果配置文件druid.properties
 * @PropertySource(value = "classpath:druid.properties")
 */
public class DruidConfiguration {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }

}

4)druid监控配置

我们配置了Druid的监听器:

Druid 数据源具有监控的功能,并提供了一个 web 界面方便用户查看,druid提供了一个默认的 web 页面。

代码语言:javascript
复制
package com.javademo.demo.web.database;

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
/**
 * 如果配置文件druid-monitor.properties
 * @PropertySource(value = "classpath:druid-monitor.properties")
 */
public class DruidMonitorConfiguration {

    @Value("${druid.monitor.allow:127.0.0.1}")
    private String allow;
    @Value("${druid.monitor.deny}")
    private String deny;
    @Value("${druid.monitor.loginUsername:admin}")
    private String loginUsername;
    @Value("${druid.monitor.loginPassword:password}")
    private String loginPassword;
    @Value("${druid.monitor.resetEnable:false}")
    private String resetEnable;

    /**
     * 配置Druid的监控
     * @return
     */
    @Bean
    public ServletRegistrationBean druidStatViewServlet() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        servletRegistrationBean.addInitParameter("allow", this.allow);
        servletRegistrationBean.addInitParameter("deny", this.deny);
        servletRegistrationBean.addInitParameter("loginUsername", this.loginUsername);
        servletRegistrationBean.addInitParameter("loginPassword", this.loginPassword);
        servletRegistrationBean.addInitParameter("resetEnable", this.resetEnable);
        return servletRegistrationBean;
    }

    /**
     * 配置一个web监控的filter
     * @return
     */
    @Bean
    public FilterRegistrationBean druidStatFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }
}

登录:http://127.0.0.1:9091/druid/login.html就可以,如果工程集成了SpringSecurity等权限工程的话是需要额外配置的

六、SpringBoot整合Druid多数据源


在一个项目中有多个数据源:

1、添加druid-spring-boot依赖

代码语言:javascript
复制
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.9</version>
</dependency>

2、配置多数据源:

代码语言:javascript
复制
spring.datasource.druid.trade.url=jdbc:mysql://192.168.10.34:3306/demo_db1
spring.datasource.druid.trade.username=demo1
spring.datasource.druid.trade.password=demo123

spring.datasource.druid.member.url=jdbc:mysql://192.168.10.34:3306/demo_db2
spring.datasource.druid.member.username=demo2
spring.datasource.druid.member.password=demo123

3、配置类加载多个数据源:

1、@Primary这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)

2、 通过@MapperScan区分使用的mapper接口, 必须是区分在不同的包下。

3、PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/*Mapper.xml")); 区分使用的mapper xml配置在不同的目录下。

代码语言:javascript
复制
package com.javademo.demo.web.database;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
@Configuration
/**
 * 如果配置文件druid.properties
 * @PropertySource(value = "classpath:druid.properties")
 */
@MapperScan(basePackages = "com.javademo.demo.web.drm.dao.default", sqlSessionFactoryRef = "defaultSqlSessionFactory")
public class DruidConfiguration {
    /**
     * 默认数据源
     * @return
     */
    @Bean(name ="default")
    @ConfigurationProperties(prefix = "spring.datasource")
    @Primary
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }

    @Bean(name = "defaultSqlSessionFactory")
    @Primary
    // @Qualifier表示查找Spring容器中名字为tradeSqlSessionFactory的对象
    public SqlSessionFactory defaultSqlSessionFactory(@Qualifier("default") DataSource datasource)
            throws Exception
    {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(datasource);
        bean.setMapperLocations(
                // 设置mybatis的xml所在位置
                new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/*Mapper.xml"));
        return bean.getObject();
    }

    @Bean("defaultSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate defaultSqlSessionTemplate(
            @Qualifier("defaultSqlSessionFactory") SqlSessionFactory sessionFactory)
    {
        return new SqlSessionTemplate(sessionFactory);
    }

}

member数据源:

代码语言:javascript
复制
package com.javademo.demo.web.database;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
@Configuration
/**
 * 如果配置文件druid.properties
 * @PropertySource(value = "classpath:druid.properties")
 */
@MapperScan(basePackages = "com.javademo.demo.web.drm.dao.member", sqlSessionFactoryRef = "memberSqlSessionFactory")
public class DruidConfigurationMember {

    /**
     * 会员数据源
     * @return
     */
    @Bean(name = "memberDataSource")
    @Qualifier("memberDataSource")
    @ConfigurationProperties(prefix="spring.datasource.druid.member")
    public DataSource memberDataSource() {
        return DruidDataSourceBuilder.create().build();
    }


    @Bean(name = "memberSqlSessionFactory")
    // @Qualifier表示查找Spring容器中名字为tradeSqlSessionFactory的对象
    public SqlSessionFactory memberSqlSessionFactory(@Qualifier("memberDataSource") DataSource datasource)
            throws Exception
    {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(datasource);
        bean.setMapperLocations(
                // 设置mybatis的xml所在位置
                new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/member/*.xml"));
        return bean.getObject();
    }

    @Bean("memberSqlSessionTemplate")
    public SqlSessionTemplate memberSqlSessionTemplate(
            @Qualifier("memberSqlSessionFactory") SqlSessionFactory sessionFactory)
    {
        return new SqlSessionTemplate(sessionFactory);
    }

}

4、在service层中根据不同的业务注入不同的dao层:

代码语言:javascript
复制
@Autowired
private IUserDao iUserDao;

@Autowired
private MUserDao mUserDao;

@Autowired
TUserDao tUserDao;
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016/11/25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、JAVA应用使用mysql
    • 1、JDBC (Java DataBase Connectivity/Java数据库连接 )[原始手工]
      • 2、JdbcTemplate [半自动化]
        • 3、MyBatis [半自动化ORM]
          • 4、JPA(Java Persistence API/Java持久层接口规范)[ORM规范]
            • 5、Spring Data JPA [ORM抽象]
              • 6、Hibernate[完整ORM实现]
                • 7、JPA、Spring Data JPA和Hibernate的关系
                  • 8、JPA 和Hibernate 和 Mybatis的区别
                  • 二、JPA方式:Spring Data Jpa
                    • 1.添加依赖 :Maven pom.xml文件
                      • 2.属性配置文件application.properties
                        • 3、实体
                          • 4.实体的数据访问层Dao
                            • 5.业务逻辑层service
                              • 6.测试的控制器CityController
                              • 三、使用jdbctemplate
                                • 1、属性配置文件
                                  • 2、pom.xml 配置maven依赖
                                    • 3、Java代码范例
                                      • 4、连接池说明
                                      • 四、使用mybatis
                                        • 1、数据库表:
                                          • 2. Springmvc集成Mybatis
                                            • 1)、项目添加mybatis依赖
                                            • 2)、配置mybatis
                                            • 3)、创建UserEntity
                                            • 4)、创建dao
                                            • 5)、创建mapper配置
                                            • 6)、service和controller测试
                                          • 3. Spring boot集成Mybatis:使用xml配置【sql和代码解耦】
                                            • 1)、添加mybatis依赖
                                            • 2)、数据源配置
                                            • 3)、映射器:添加mapper的接口
                                            • 4)、映射器:mapper配置xml文件
                                          • 3. Spring boot集成Mybatis:注解【耦合性高】
                                            • 1)、 添加相关maven文件【同上】
                                            • 2)、application.properties 相关配置【同上】
                                            • 3)、开发Mapper接口
                                            • 4)、使用DAO
                                        • 五、SpringBoot2整合Druid数据源
                                          • 1、添加Druid依赖
                                            • 2) 添加配置
                                              • 3)、数据源配置类
                                                • 4)druid监控配置
                                                • 六、SpringBoot整合Druid多数据源
                                                  • 1、添加druid-spring-boot依赖
                                                    • 2、配置多数据源:
                                                      • 3、配置类加载多个数据源:
                                                        • 4、在service层中根据不同的业务注入不同的dao层:
                                                        相关产品与服务
                                                        数据库
                                                        云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                                                        领券
                                                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档