文章目录
一、数据源连接池介绍
在Java开发中,使用JDBC操作数据库包括以下四个步骤:
① 加载数据库驱动程序:Class.forName(“数据库驱动类”);
② 连接数据库:Connection con = DriverManager.getConnection();
③ 操作数据库:PreparedStatement stat = con.prepareStatement(sql);stat.executeQuery();
④ 关闭数据库,释放连接:con.close();
所有用户都需要通过以上四步才能完成对数据库的操作,而在这四步中的①、②、④三步对于所有用户来说都是一样的,即每个用户都需要加载驱动、连接和关闭数据库,且使用同样的操作即可实现。对所有用户来说,只有第③步是不一样的,这样就造成了很大的性能浪费。
数据源连接池便可以很好地解决上述问题,其基本原理为:使用一个空间保存着所有数据库连接,用户想要操作数据库时只需要从数据源中取出自己需要的数据库连接即可,不需要进行上面的①加载数据库驱动程序、②连接数据库这两个操作。操作完数据库后,用户也无需④释放数据库连接,直接把取出的连接放回数据源空间中即可。
虽然理论上比较简单,但想要实现连接池需要考虑很多问题,比如:
1、 如果没有任何一个用户使用连接,那么那么应该维持一定数量的连接,等待用户使用。
2、 如果连接已经满了,则必须打开新的连接,供更多用户使用。
3、 如果一个服务器就只能有100个连接,那么如果有第101个人过来呢?应该等待其他用户释放连接。
4、 如果一个用户等待时间太长了,则应该告诉用户,操作是失败的。
如果直接用程序实现以上功能,则会比较麻烦,所以在Tomcat 4.1.27之后,在服务器上就直接增加了数据源的配置选项,直接在服务器上配置好数据源连接池即可。在J2EE服务器上保存着一个数据库的多个连接,每一个连接通过DataSource可以找到。DataSource被绑定在了JNDI树上,为每一个DataSource提供了一个唯一的名称,客户端通过这个名称就可以找到在JNDI树上绑定的DataSource,再由DataSource找到一个连接。如下图所示:
二、SpringBoot内置Tomcat实现JNDI多数据源配置
1、添加依赖
所需的依赖包括mybatis-starter、mysql驱动以及tomcat依赖
在pom.xml中添加:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>${tomcat.version}</version>
</dependency>
2、启动类注解
在项目的启动类中加入以下注解:
@EnableAutoConfiguration(exclude = {
DataSourceAutoConfiguration.class})
此注解能够使springboot在启动时(自动配置阶段)排除自动配置数据源信息。
这一步很重要,如果没有这个注解就会因为自动配置了数据源而找不到数据源的配置报错!
PS:使用上面注解时需要将@springbootapplication注解删掉,若添加@EnableAutoConfiguration注解时出现红色下波浪线,则需要将以下注解一并引入:
@ComponentScan
@EnableAutoConfiguration(exclude = {
DataSourceAutoConfiguration.class})
3、配置dataSource数据源信息
创建一个数据源配置类DBConfiguration,配置数据源信息,多个数据源可以配置多个Resource
@Configuration
public class DBConfiguration {
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
tomcat.enableNaming();//启用默认禁用的JNDI命名
return super.getTomcatWebServer(tomcat);
}
@Override
protected void postProcessContext(Context context) {
//数据源 1
//构建一个ContextResource对象,然后添加到Context对象中
ContextResource resource = new ContextResource();
resource.setName("jdbc/MyFirstMySql");
resource.setType(DataSource.class.getName());
resource.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
resource.setProperty("url", "jdbc:mysql://127.0.0.1:3306/osbpm?serverTimezone=GMT%2B8");
resource.setProperty("username", "root");
resource.setProperty("password","123456");
context.getNamingResources().addResource(resource);
//数据源 2
//构建一个ContextResource对象,然后添加到Context对象中
ContextResource resource1 = new ContextResource();
resource1.setName("jdbc/MySecondMySql");
resource1.setType(DataSource.class.getName());
resource1.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
resource1.setProperty("url", "jdbc:mysql://127.0.0.1:3306/osbpm?serverTimezone=GMT%2B8");
resource1.setProperty("username", "root");
resource1.setProperty("password","123456");
context.getNamingResources().addResource(resource1);
super.postProcessContext(context);
}
};
return tomcat;
}
}
resource.setName方法中写的是对应datasource中的JNDI名称(jndi-name)。
4、配置yml文件
yml文件的配置十分简单,只需指定要使用的数据源名称即可,其他的不需要配置
spring:
datasource:
jndi-name: jdbc/MyFirstMySql
至此,数据源的配置工作就结束了,下面进行测试!
5、测试
创建mapper文件(SQL语句自行修改)
@Mapper
public interface TestMapper {
@Select(value = "select * from [表名]")
List<Map> getList();
}
创建Controller测试类
@Controller
public class TestController{
@Autowired
TestMapper testMapper;
@RequestMapping("/getList")
@ResponseBody
public List<Map> getList(){
return testMapper.getList();
}
}
启动项目并运行,访问接口:http://localhost:8080/getList
更改yml文件中配置的jndi数据源名称为MySecondMySql,重启项目,访问接口http://localhost:8080/getList
三、其他
以下几种情况分别集成jndi数据源区别还是很大的,多注意一下!
1、spring 外部容器集成JNDI
2、springboot 外部容器集成JNDI
3、springboot 1.X 内部容器集成JNDI
4、springboot 2.X 内部容器集成JNDI