zoukankan      html  css  js  c++  java
  • spring-boot支持双数据源mysql+mongo

    这里,首先想说的是,现在的web应用,处理的数据对象,有结构化的,也有非结构化的。同时存在。但是在spring-boot操作数据库的时候,若是在properties文件中配置数据源的信息,通过默认配置加载数据源的话,往往只会启动一个。

    我出于想弄清如何配置数据源的目的,在这里demo一个配置两个数据源的例子。分别是mysql和mongo。mysql的持久化采用的是mybatis。

    mongo的操作比较简单,直接贴上配置数据库的代码:

    复制代码
     1 package com.shihuc.dbconn.sourceconfig.mongo;
     2 
     3 import java.util.Arrays;
     4 
     5 import org.springframework.beans.factory.annotation.Value;
     6 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
     7 import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
     8 import org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration;
     9 import org.springframework.context.annotation.Bean;
    10 import org.springframework.context.annotation.ComponentScan;
    11 import org.springframework.context.annotation.Configuration;
    12 import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
    13 import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
    14 
    15 import com.mongodb.Mongo;
    16 import com.mongodb.MongoClient;
    17 import com.mongodb.MongoCredential;
    18 import com.mongodb.ServerAddress;
    19 import com.mongodb.WriteConcern;
    20 
    21 @Configuration
    22 @EnableAutoConfiguration(exclude={MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
    23 @ComponentScan
    24 @EnableMongoRepositories
    25 public class MongoDataSourceConfig extends AbstractMongoConfiguration{
    26 
    27     @Value("${mongo.database}")
    28     private String dbname;
    29     
    30     @Value("${mongo.host}")
    31     private String dbhost;
    32     
    33     @Value("${mongo.port}")
    34     private String dbport;
    35     
    36     @Value("${mongo.username}")
    37     private String username;
    38     
    39     @Value("${mongo.password}")
    40     private String password;
    41     
    42     @Override
    43     protected String getDatabaseName() {
    44         return this.dbname;
    45     }
    46     
    47     public MongoDataSourceConfig(){
    48         if(null == dbport || "".equalsIgnoreCase(dbport.trim())){
    49             dbport = "27017";
    50         }
    51     }
    52 
    53     @Override
    54     @Bean(name = "mongods")
    55     public Mongo mongo() throws Exception {
    56         ServerAddress serverAdress = new  ServerAddress(dbhost, Integer.valueOf(dbport));        
    57         MongoCredential credential = MongoCredential.createMongoCRCredential(username, dbname , password.toCharArray());
    58         //Do not use new Mongo(), is deprecated.
    59         Mongo mongo =  new MongoClient(serverAdress, Arrays.asList(credential));
    60         mongo.setWriteConcern(WriteConcern.SAFE);
    61         return mongo;
    62     }
    63 }
    复制代码

    mongo数据库配置继承AbstractMongoConfiguration,在这个过程中,会向spring容器注册一个mongoTemplate,这个很重要,后期操作mongo数据库时,主要靠它。

    这里重点说下spring-boot和mybatis集成操作mysql的配置和注意事项。

    复制代码
     1 package com.shihuc.dbconn.sourceconfig.mysql;
     2 
     3 import javax.sql.DataSource;
     4 
     5 import org.springframework.beans.factory.annotation.Value;
     6 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
     7 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
     8 import org.springframework.context.annotation.Bean;
     9 import org.springframework.context.annotation.Configuration;
    10 import org.springframework.jdbc.datasource.DriverManagerDataSource;
    11 
    12 @Configuration
    13 @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
    14 public class MysqlDataSourceConfig {
    15 
    16     @Value("${mysql.driver}")
    17     private String driver;
    18 
    19     @Value("${mysql.url}")
    20     private String url;
    21 
    22     @Value("${mysql.username}")
    23     private String username;
    24 
    25     @Value("${mysql.password}")
    26     private String password;
    27 
    28     @Bean(name="mysqlds")
    29     public DataSource mysql()
    30     {
    31         DriverManagerDataSource ds = new DriverManagerDataSource();
    32         ds.setDriverClassName(driver);
    33         ds.setUrl(url);
    34         ds.setUsername(username);
    35         ds.setPassword(password);
    36         return ds;
    37     }
    38 }
    复制代码

    这个是datasource的配置,注意,类似mongo的配置,要将自动配置的类给exclude掉。让spring只处理我们希望的数据源。否则会受到classpath下的信息,干扰数据源的配置。

    另外,就是mybatis的配置。由于spring-boot重点特色是纯java config,所以,这里也采用java配置和注解启用mybatis。

    复制代码
     1 package com.shihuc.dbconn.sourceconfig.mysql;
     2 
     3 import javax.sql.DataSource;
     4 
     5 import org.apache.ibatis.session.SqlSessionFactory;
     6 import org.mybatis.spring.SqlSessionFactoryBean;
     7 import org.mybatis.spring.annotation.MapperScan;
     8 import org.springframework.beans.factory.annotation.Autowired;
     9 import org.springframework.beans.factory.annotation.Qualifier;
    10 import org.springframework.context.annotation.Bean;
    11 import org.springframework.context.annotation.Configuration;
    12 
    13 @Configuration
    14 @MapperScan(basePackages = "com.shihuc.dbconn.dao.mysql")
    15 public class MysqlMybatisConfig {
    16     
    17     @Autowired
    18     @Qualifier("mysqlds")
    19     private DataSource mysqlds;
    20     
    21     @Bean
    22     public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
    23         final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    24         sessionFactory.setDataSource(mysqlds);
    25         return sessionFactory.getObject();
    26     }
    27 }
    复制代码

    这里,mapperscan主要是为配置JavaBean和持久化对象之间的映射关系设定根路径。在这个例子中,mapper部分,其实就是通过insert,delete,update,select等注解,结合具体的SQL语句实现ORM的关系。看看这里的代码:

    复制代码
     1 package com.shihuc.dbconn.dao.mysql;
     2 
     3 import org.apache.ibatis.annotations.Insert;
     4 import org.apache.ibatis.annotations.Select;
     5 
     6 import com.shihuc.dbconn.pojo.mysql.MysqlUser;
     7 
     8 public interface IMysqlUser {
     9 
    10     @Select("SELECT * FROM user WHERE id = #{userId}")
    11     public MysqlUser getUser(int userId);
    12 
    13     @Insert("insert into user (username, job, age, hometown) values(#{username}, #{job}, #{age}, #{hometown})")
    14     public int addUser(MysqlUser user);
    15 }
    复制代码

    另外,配合这个IMysqlUser使用的MysqlUser的定义也很重要,主要是里面的constructor函数,通常,添加数据,比如上面的addUser操作,是要创建一个POJO的对象,为了方便,一般都会创建一个带参数的构造函数,注意,必须也同时创建一个无参数的构造函数,否则,在做查询操作,比如上面的getUser时,会出现下面的错误:

    复制代码
     1   .   ____          _            __ _ _
     2  /\ / ___'_ __ _ _(_)_ __  __ _    
     3 ( ( )\___ | '_ | '_| | '_ / _` |    
     4  \/  ___)| |_)| | | | | || (_| |  ) ) ) )
     5   '  |____| .__|_| |_|_| |_\__, | / / / /
     6  =========|_|==============|___/=/_/_/_/
     7  :: Spring Boot ::        (v1.2.7.RELEASE)
     8 
     9 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)
    10 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
    11 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)
    12 2016-01-29 15:01:09.915  INFO 30880 --- [           main] o.s.j.d.DriverManagerDataSource          : Loaded JDBC driver: com.mysql.jdbc.Driver
    13 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)
    14 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)
    15 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)
    16 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)
    17 2016-01-29 15:01:10.876  INFO 30880 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
    18 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)
    19 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>()
    20     at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75)
    21     at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:371)
    22     at com.sun.proxy.$Proxy26.selectOne(Unknown Source)
    23     at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:163)
    24     at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:63)
    25     at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:43)
    26     at com.sun.proxy.$Proxy34.getUser(Unknown Source)
    27     at com.shihuc.dbconn.service.mysql.MysqlUserService.getUser(MysqlUserService.java:20)
    28     at com.shihuc.dbconn.DbConnApp.main(DbConnApp.java:34)
    29 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>()
    30     at org.apache.ibatis.reflection.factory.DefaultObjectFactory.instantiateClass(DefaultObjectFactory.java:83)
    31     at org.apache.ibatis.reflection.factory.DefaultObjectFactory.create(DefaultObjectFactory.java:45)
    32     at org.apache.ibatis.reflection.factory.DefaultObjectFactory.create(DefaultObjectFactory.java:38)
    33     at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:530)
    34     at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:509)
    35     at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:329)
    36     at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:289)
    37     at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:264)
    38     at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:234)
    39     at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:152)
    40     at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:57)
    41     at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:70)
    42     at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:57)
    43     at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:259)
    44     at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:132)
    45     at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:105)
    46     at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:81)
    47     at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:104)
    48     at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:98)
    49     at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:62)
    50     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    51     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    52     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    53     at java.lang.reflect.Method.invoke(Method.java:606)
    54     at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:358)
    55     ... 7 more
    56 Caused by: java.lang.NoSuchMethodException: com.shihuc.dbconn.pojo.mysql.MysqlUser.<init>()
    57     at java.lang.Class.getConstructor0(Class.java:2892)
    58     at java.lang.Class.getDeclaredConstructor(Class.java:2058)
    59     at org.apache.ibatis.reflection.factory.DefaultObjectFactory.instantiateClass(DefaultObjectFactory.java:57)
    60     ... 31 more
    61 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
    62 2016-01-29 15:01:11.142  INFO 30880 --- [       Thread-1] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
    复制代码
    View Code

    方便说明问题,将MysqlUser也附上代码:

    复制代码
     1 package com.shihuc.dbconn.pojo.mysql;
     2 
     3 import com.shihuc.dbconn.pojo.User;
     4 
     5 public class MysqlUser extends User{
     6 
     7     private static final long serialVersionUID = -6412107575129572581L;
     8 
     9     //这个id是数据库中通过设置auto_increment得到的主键值
    10     private int id;
    11 
    12     public int getId() {
    13         return id;
    14     }
    15 
    16     public void setId(int id) {
    17         this.id = id;
    18     }
    19     
    20     public MysqlUser(){
    21         
    22     }
    23     
    24     public MysqlUser(String username, String job, int age, String hometown){
    25         this.username = username;
    26         this.job = job;
    27         this.age = age;
    28         this.hometown = hometown;
    29     }
    30     
    31 }
    复制代码

    下面看看,测试程序吧,我是在main函数里面写的,如下:

    复制代码
     1 package com.shihuc.dbconn;
     2 
     3 import org.springframework.boot.SpringApplication;
     4 import org.springframework.boot.autoconfigure.SpringBootApplication;
     5 import org.springframework.context.ApplicationContext;
     6 import org.springframework.context.annotation.PropertySource;
     7 
     8 import com.shihuc.dbconn.pojo.mongo.MongoUser;
     9 import com.shihuc.dbconn.pojo.mysql.MysqlUser;
    10 import com.shihuc.dbconn.service.mongo.MongoUserService;
    11 import com.shihuc.dbconn.service.mysql.MysqlUserService;
    12 
    13 /**
    14  * 
    15  * @author  shihuc
    16  * @date    Jan 29, 2016
    17  * 
    18  */
    19 @SpringBootApplication
    20 @PropertySource(value = "dbconn.properties")
    21 public class DbConnApp 
    22 {
    23     
    24        public static void main(String[] args) throws Throwable {
    25           
    26         SpringApplication app = new SpringApplication(DbConnApp.class);
    27         
    28         ApplicationContext ctx = app.run(args);        
    29         
    30         MysqlUserService mysqlUserService = (MysqlUserService)ctx.getBean("mysqlUserService");        
    31 //        MysqlUser su = new MysqlUser("shihuc", "SW", 30 , "wuhan");
    32 //        mysqlUserService.addUser(su);    
    33         MysqlUser ue = mysqlUserService.getUser(1);
    34         System.out.println("Mysql User: " + ue);        
    35         
    36         MongoUserService mongoUserService = (MongoUserService)ctx.getBean("mongoUserService");
    37 //        MongoUser mu = new MongoUser("shihuc", "SW", 30 , "wuhan");
    38 //        mongoUserService.addUser(mu);                
    39         MongoUser um = mongoUserService.getUser("shihuc");
    40         System.out.println("Mongo User: " + um);
    41     }
    42 }
    复制代码

    最后附上我的maven项目的pom文件:

    复制代码
     1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     2   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     3   <modelVersion>4.0.0</modelVersion>
     4 
     5   <groupId>com.shihuc</groupId>
     6   <artifactId>dbconn</artifactId>
     7   <version>0.0.1-SNAPSHOT</version>
     8   <packaging>jar</packaging>
     9 
    10   <name>dbconn</name>
    11   <url>http://maven.apache.org</url>
    12 
    13   <parent>
    14         <groupId>org.springframework.boot</groupId>
    15         <artifactId>spring-boot-starter-parent</artifactId>
    16         <version>1.2.7.RELEASE</version>
    17   </parent>
    18   
    19   <properties>
    20     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    21   </properties>
    22 
    23   <dependencies>
    24       <dependency>
    25           <groupId>org.springframework.boot</groupId>
    26         <artifactId>spring-boot-starter-jdbc</artifactId>        
    27     </dependency>
    28     <dependency>
    29         <groupId>mysql</groupId>
    30         <artifactId>mysql-connector-java</artifactId>
    31         </dependency>
    32     <dependency>
    33         <groupId>org.mybatis</groupId>
    34         <artifactId>mybatis</artifactId>
    35         <version>3.2.3</version>
    36     </dependency>
    37     <dependency>
    38         <groupId>org.mybatis</groupId>
    39         <artifactId>mybatis-spring</artifactId>
    40         <version>1.2.2</version>
    41     </dependency>
    42     <dependency>
    43         <groupId>org.springframework.boot</groupId>
    44         <artifactId>spring-boot-starter-data-mongodb</artifactId>
    45     </dependency>
    46   </dependencies>
    47   
    48   <build>
    49     <plugins>
    50         <plugin>
    51             <groupId>org.springframework.boot</groupId>
    52             <artifactId>spring-boot-maven-plugin</artifactId>
    53         </plugin>
    54     </plugins>
    55   </build>
    56 </project>
    复制代码

    还是相对比较简单的配置和操作。对于这个demo的例子程序,可以在GitHub https://github.com/shihuc/dbconn上下载。

    http://www.cnblogs.com/shihuc/p/5169418.html

  • 相关阅读:
    Proj THUDBFuzz Paper Reading: The Art, Science, and Engineering of Fuzzing: A Survey
    Proj THUDBFuzz Paper Reading: A systematic review of fuzzing based on machine learning techniques
    9.3 付费代理的使用
    11.1 Charles 的使用
    第十一章 APP 的爬取
    10.2 Cookies 池的搭建
    10.1 模拟登录并爬取 GitHub
    11.5 Appium 爬取微信朋友圈
    11.4 Appium 的基本使用
    11.3 mitmdump 爬取 “得到” App 电子书信息
  • 原文地址:https://www.cnblogs.com/softidea/p/5699971.html
Copyright © 2011-2022 走看看