spring-boot支持双数据源mysql+mongo
这里,首先想说的是,现在的web应用,处理的数据对象,有结构化的,也有非结构化的。同时存在。但是在spring-boot操作数据库的时候,若是在properties文件中配置数据源的信息,通过默认配置加载数据源的话,往往只会启动一个。
我出于想弄清如何配置数据源的目的,在这里demo一个配置两个数据源的例子。分别是mysql和mongo。mysql的持久化采用的是mybatis。
mongo的操作比较简单,直接贴上配置数据库的代码:
- package com.shihuc.dbconn.sourceconfig.mongo;
- import java.util.Arrays;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
- import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
- import org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.ComponentScan;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
- import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
- import com.mongodb.Mongo;
- import com.mongodb.MongoClient;
- import com.mongodb.MongoCredential;
- import com.mongodb.ServerAddress;
- import com.mongodb.WriteConcern;
- @Configuration
- @EnableAutoConfiguration(exclude={MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
- @ComponentScan
- @EnableMongoRepositories
- public class MongoDataSourceConfig extends AbstractMongoConfiguration{
- @Value("${mongo.database}")
- private String dbname;
- @Value("${mongo.host}")
- private String dbhost;
- @Value("${mongo.port}")
- private String dbport;
- @Value("${mongo.username}")
- private String username;
- @Value("${mongo.password}")
- private String password;
- @Override
- protected String getDatabaseName() {
- return this.dbname;
- }
- public MongoDataSourceConfig(){
- if(null == dbport || "".equalsIgnoreCase(dbport.trim())){
- dbport = "27017";
- }
- }
- @Override
- @Bean(name = "mongods")
- public Mongo mongo() throws Exception {
- ServerAddress serverAdress = new ServerAddress(dbhost, Integer.valueOf(dbport));
- MongoCredential credential = MongoCredential.createMongoCRCredential(username, dbname , password.toCharArray());
- //Do not use new Mongo(), is deprecated.
- Mongo mongo = new MongoClient(serverAdress, Arrays.asList(credential));
- mongo.setWriteConcern(WriteConcern.SAFE);
- return mongo;
- }
- }
mongo数据库配置继承AbstractMongoConfiguration,在这个过程中,会向spring容器注册一个mongoTemplate,这个很重要,后期操作mongo数据库时,主要靠它。
这里重点说下spring-boot和mybatis集成操作mysql的配置和注意事项。
- package com.shihuc.dbconn.sourceconfig.mysql;
- import javax.sql.DataSource;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
- import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.jdbc.datasource.DriverManagerDataSource;
- @Configuration
- @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
- public class MysqlDataSourceConfig {
- @Value("${mysql.driver}")
- private String driver;
- @Value("${mysql.url}")
- private String url;
- @Value("${mysql.username}")
- private String username;
- @Value("${mysql.password}")
- private String password;
- @Bean(name="mysqlds")
- public DataSource mysql()
- {
- DriverManagerDataSource ds = new DriverManagerDataSource();
- ds.setDriverClassName(driver);
- ds.setUrl(url);
- ds.setUsername(username);
- ds.setPassword(password);
- return ds;
- }
- }
这个是datasource的配置,注意,类似mongo的配置,要将自动配置的类给exclude掉。让spring只处理我们希望的数据源。否则会受到classpath下的信息,干扰数据源的配置。
另外,就是mybatis的配置。由于spring-boot重点特色是纯java config,所以,这里也采用java配置和注解启用mybatis。
- package com.shihuc.dbconn.sourceconfig.mysql;
- import javax.sql.DataSource;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.mybatis.spring.SqlSessionFactoryBean;
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Qualifier;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- @Configuration
- @MapperScan(basePackages = "com.shihuc.dbconn.dao.mysql")
- public class MysqlMybatisConfig {
- @Autowired
- @Qualifier("mysqlds")
- private DataSource mysqlds;
- @Bean
- public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
- final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
- sessionFactory.setDataSource(mysqlds);
- return sessionFactory.getObject();
- }
- }
这里,mapperscan主要是为配置JavaBean和持久化对象之间的映射关系设定根路径。在这个例子中,mapper部分,其实就是通过insert,delete,update,select等注解,结合具体的SQL语句实现ORM的关系。看看这里的代码:
- package com.shihuc.dbconn.dao.mysql;
- import org.apache.ibatis.annotations.Insert;
- import org.apache.ibatis.annotations.Select;
- import com.shihuc.dbconn.pojo.mysql.MysqlUser;
- public interface IMysqlUser {
- @Select("SELECT * FROM user WHERE id = #{userId}")
- public MysqlUser getUser(int userId);
- @Insert("insert into user (username, job, age, hometown) values(#{username}, #{job}, #{age}, #{hometown})")
- public int addUser(MysqlUser user);
- }
另外,配合这个IMysqlUser使用的MysqlUser的定义也很重要,主要是里面的constructor函数,通常,添加数据,比如上面的addUser操作,是要创建一个POJO的对象,为了方便,一般都会创建一个带参数的构造函数,注意,必须也同时创建一个无参数的构造函数,否则,在做查询操作,比如上面的getUser时,会出现下面的错误:
- . ____ _ __ _ _
- /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
- ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
- \\/ ___)| |_)| | | | | || (_| | ) ) ) )
- ' |____| .__|_| |_|_| |_\__, | / / / /
- =========|_|==============|___/=/_/_/_/
- :: Spring Boot :: (v1.2.7.RELEASE)
- 2016-01-29 15:01:07.930 INFO 30880 --- [ main] com.shihuc.dbconn.DbConnApp : Starting DbConnApp on CloudGame with PID 30880 (/home/webWps/dbconn/target/classes started by root in /home/webWps/dbconn)
- 2016-01-29 15:01:07.997 INFO 30880 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@a85aa40: startup date [Fri Jan 29 15:01:07 CST 2016]; root of context hierarchy
- 2016-01-29 15:01:09.887 INFO 30880 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'mysqlDataSourceConfig' of type [class com.shihuc.dbconn.sourceconfig.mysql.MysqlDataSourceConfig$$EnhancerBySpringCGLIB$$63c6820a] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
- 2016-01-29 15:01:09.915 INFO 30880 --- [ main] o.s.j.d.DriverManagerDataSource : Loaded JDBC driver: com.mysql.jdbc.Driver
- 2016-01-29 15:01:09.923 INFO 30880 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'mysqlds' of type [class org.springframework.jdbc.datasource.DriverManagerDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
- 2016-01-29 15:01:09.926 INFO 30880 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'mysqlMybatisConfig' of type [class com.shihuc.dbconn.sourceconfig.mysql.MysqlMybatisConfig$$EnhancerBySpringCGLIB$$bbfde9e4] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
- 2016-01-29 15:01:09.991 INFO 30880 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'sqlSessionFactoryBean' of type [class org.apache.ibatis.session.defaults.DefaultSqlSessionFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
- 2016-01-29 15:01:10.040 INFO 30880 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'IMysqlUser' of type [class org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
- 2016-01-29 15:01:10.876 INFO 30880 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
- 2016-01-29 15:01:10.888 INFO 30880 --- [ main] com.shihuc.dbconn.DbConnApp : Started DbConnApp in 3.274 seconds (JVM running for 3.561)
- Exception in thread "main" org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: Error instantiating class com.shihuc.dbconn.pojo.mysql.MysqlUser with invalid types () or values (). Cause: java.lang.NoSuchMethodException: com.shihuc.dbconn.pojo.mysql.MysqlUser.<init>()
- at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75)
- at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:371)
- at com.sun.proxy.$Proxy26.selectOne(Unknown Source)
- at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:163)
- at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:63)
- at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:43)
- at com.sun.proxy.$Proxy34.getUser(Unknown Source)
- at com.shihuc.dbconn.service.mysql.MysqlUserService.getUser(MysqlUserService.java:20)
- at com.shihuc.dbconn.DbConnApp.main(DbConnApp.java:34)
- Caused by: org.apache.ibatis.reflection.ReflectionException: Error instantiating class com.shihuc.dbconn.pojo.mysql.MysqlUser with invalid types () or values (). Cause: java.lang.NoSuchMethodException: com.shihuc.dbconn.pojo.mysql.MysqlUser.<init>()
- at org.apache.ibatis.reflection.factory.DefaultObjectFactory.instantiateClass(DefaultObjectFactory.java:83)
- at org.apache.ibatis.reflection.factory.DefaultObjectFactory.create(DefaultObjectFactory.java:45)
- at org.apache.ibatis.reflection.factory.DefaultObjectFactory.create(DefaultObjectFactory.java:38)
- at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:530)
- at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:509)
- at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:329)
- at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:289)
- at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:264)
- at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:234)
- at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:152)
- at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:57)
- at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:70)
- at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:57)
- at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:259)
- at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:132)
- at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:105)
- at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:81)
- at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:104)
- at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:98)
- at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:62)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
- at java.lang.reflect.Method.invoke(Method.java:606)
- at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:358)
- ... 7 more
- Caused by: java.lang.NoSuchMethodException: com.shihuc.dbconn.pojo.mysql.MysqlUser.<init>()
- at java.lang.Class.getConstructor0(Class.java:2892)
- at java.lang.Class.getDeclaredConstructor(Class.java:2058)
- at org.apache.ibatis.reflection.factory.DefaultObjectFactory.instantiateClass(DefaultObjectFactory.java:57)
- ... 31 more
- 2016-01-29 15:01:11.139 INFO 30880 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@a85aa40: startup date [Fri Jan 29 15:01:07 CST 2016]; root of context hierarchy
- 2016-01-29 15:01:11.142 INFO 30880 --- [ Thread-1] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
方便说明问题,将MysqlUser也附上代码:
- package com.shihuc.dbconn.pojo.mysql;
- import com.shihuc.dbconn.pojo.User;
- public class MysqlUser extends User{
- private static final long serialVersionUID = -6412107575129572581L;
- //这个id是数据库中通过设置auto_increment得到的主键值
- private int id;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public MysqlUser(){
- }
- public MysqlUser(String username, String job, int age, String hometown){
- this.username = username;
- this.job = job;
- this.age = age;
- this.hometown = hometown;
- }
- }
下面看看,测试程序吧,我是在main函数里面写的,如下:
- package com.shihuc.dbconn;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.annotation.PropertySource;
- import com.shihuc.dbconn.pojo.mongo.MongoUser;
- import com.shihuc.dbconn.pojo.mysql.MysqlUser;
- import com.shihuc.dbconn.service.mongo.MongoUserService;
- import com.shihuc.dbconn.service.mysql.MysqlUserService;
- /**
- *
- * @author shihuc
- * @date Jan 29, 2016
- *
- */
- @SpringBootApplication
- @PropertySource(value = "dbconn.properties")
- public class DbConnApp
- {
- public static void main(String[] args) throws Throwable {
- SpringApplication app = new SpringApplication(DbConnApp.class);
- ApplicationContext ctx = app.run(args);
- MysqlUserService mysqlUserService = (MysqlUserService)ctx.getBean("mysqlUserService");
- // MysqlUser su = new MysqlUser("shihuc", "SW", 30 , "wuhan");
- // mysqlUserService.addUser(su);
- MysqlUser ue = mysqlUserService.getUser(1);
- System.out.println("Mysql User: " + ue);
- MongoUserService mongoUserService = (MongoUserService)ctx.getBean("mongoUserService");
- // MongoUser mu = new MongoUser("shihuc", "SW", 30 , "wuhan");
- // mongoUserService.addUser(mu);
- MongoUser um = mongoUserService.getUser("shihuc");
- System.out.println("Mongo User: " + um);
- }
- }
最后附上我的maven项目的pom文件:
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.shihuc</groupId>
- <artifactId>dbconn</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>dbconn</name>
- <url>http://maven.apache.org</url>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.2.7.RELEASE</version>
- </parent>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jdbc</artifactId>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.2.3</version>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>1.2.2</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-mongodb</artifactId>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </project>
还是相对比较简单的配置和操作。对于这个demo的例子程序,可以在GitHub https://github.com/shihuc/dbconn上下载。
spring-boot支持双数据源mysql+mongo的更多相关文章
- spring boot 配置双数据源mysql、sqlServer
背景:原来一直都是使用mysql数据库,在application.properties 中配置数据库信息 spring.datasource.url=jdbc:mysql://xxxx/test sp ...
- Spring Boot与多数据源那点事儿~
持续原创输出,点击上方蓝字关注我 目录 前言 写这篇文章的目的 什么是多数据源? 何时用到多数据源? 整合单一的数据源 整合Mybatis 多数据源如何整合? 什么是动态数据源? 数据源切换如何保证线 ...
- 后端Spring Boot+前端Android交互+MySQL增删查改(Java+Kotlin实现)
1 前言&概述 这篇文章是基于这篇文章的更新,主要是更新了一些技术栈以及开发工具的版本,还有修复了一些Bug. 本文是SpringBoot+Android+MySQL的增删查改的简单实现,用到 ...
- spring boot项目自定义数据源,mybatisplus分页、逻辑删除无效解决方法
Spring Boot项目中数据源的配置可以通过两种方式实现: 1.application.yml或者application.properties配置 2.注入DataSource及SqlSessio ...
- Spring Boot配置多数据源并实现Druid自动切换
原文:https://blog.csdn.net/acquaintanceship/article/details/75350653 Spring Boot配置多数据源配置yml文件主数据源配置从数据 ...
- spring boot: 支持jsp,支持freemarker
spring boot: 支持jsp,支持freemarker 支持jsp: 加入依赖 <!--jsp--> <dependency> <groupId>org.a ...
- Spring Boot 支持多种外部配置方式
Spring Boot 支持多种外部配置方式 http://blog.csdn.net/isea533/article/details/50281151 这些方式优先级如下: 命令行参数 来自java ...
- Spring Boot 项目学习 (二) MySql + MyBatis 注解 + 分页控件 配置
0 引言 本文主要在Spring Boot 基础项目的基础上,添加 Mysql .MyBatis(注解方式)与 分页控件 的配置,用于协助完成数据库操作. 1 创建数据表 这个过程就暂时省略了. 2 ...
- Spring Boot 支持 HTTPS 如此简单,So easy!
这里讲的是 Spring Boot 内嵌式 Server 打 jar 包运行的方式,打 WAR 包部署的就不存在要 Spring Boot 支持 HTTPS 了,需要去外部对应的 Server 配置. ...
随机推荐
- LeetCode Combinations (DFS)
题意: 产生从1-n的k个数的所有组合,按升序排列并返回. 思路: DFS一遍即可解决.注意升序. class Solution { public: vector<vector<int&g ...
- js中获取样式的俩种方法 style.color和style['color'] 区别
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Linux 下网络性能优化方法简析
概述 对于网络的行为,可以简单划分为 3 条路径:1) 发送路径,2) 转发路径,3) 接收路径,而网络性能的优化则可基于这 3 条路径来考虑.由于数据包的转发一般是具备路由功能的设备所关注,在本文中 ...
- httpclient 发送一个请求
httpclient版本 4.1 发送一个post请求 public static JSONObject post(String url,JSONObject json){ HttpClient cl ...
- Git简易的命令行入门教程
简易的命令行入门教程: Git 全局设置: git config --global user.name "imsoft" git config --global user.emai ...
- telnet命令使用示例
导读 telnet命令通常用来远程登录.telnet程序是基于TELNET协议的远程登录客户端程序.Telnet协议是TCP/IP协议族中的一员,是Internet远程登录服务的标准协议和主要方式.它 ...
- 权限分配界面 纯手工 仅用到bootstrap的架构 以及 c标签
<div class="form-group"> <div class="row"> <label ...
- hdu4642 Fliping game ——博弈
link:http://acm.hdu.edu.cn/showproblem.php?pid=4642 refer to: http://www.cnblogs.com/jackge/archive/ ...
- 最小二乘法 java
import java.util.ArrayList; import java.util.Collection; import org.apache.commons.math3.optim.Point ...
- 工作中遇到的问题--使用DTO减少数据字段
Location中包含如下字段以及AMfgObject中关于创建信息的字段,然而有时使用并不需要传输那么多数据,则对其中字段进行过滤. @Entity@Table(name = "LOCAT ...