首页 技术 正文
技术 2022年11月13日
0 收藏 614 点赞 2,997 浏览 14515 个字

这里,首先想说的是,现在的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上下载。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,488
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,903
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,736
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,487
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,127
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,289