为什么要讲Spring去配置数据源呢?其实这里的数据源就是我们之前讲的连接池,这个地方我们使用连接池去充当我们的数据源。
我们之前通过Spirng的配置文件去配置我们的bean,但是这些bean都是我们自定义的,自定义完之后配置到容器当中的。而数据源呢,不管是什么c3p0啊什么dbcp啊什么Druid啊,像这些东西一般都是第三方提供的,我们既然要用它,那我们能不能也让容器去帮我们产生这些非自定义bean呢?这个是肯定的。
数据源(连接池)的作用
1、数据源(连接池)是为了提高程序性能出现的
2、事先实例化数据源,初始化部分连接资源
3、使用连接资源时从数据源中获取
4、使用完毕后将连接资源归还给数据源
常见的数据源(连接池):DBCP、C3P0、BoneCP、Druid等。
数据源的开发步骤
1、导入数据源的坐标和数据库驱动坐标(引入依赖)
<?xml version="1.0" encoding="UTF-8"?>
<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.Why</groupId>
<artifactId>SpringLearning</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--导入数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<!--导入c3p0数据源
c3p0是什么?
c3p0是一个库。它拓展了传统的jdbc数据库连接池,并且支持JDBC3和JDBC2的标准扩展
为什么使用c3p0?
首先,c3p0是一种jdbc数据库连接池,那么为什么要使用数据库连接池呢?因为数据库连接是一种
关键的、有限的、昂贵的资源。传统的模式(如传统的java web项目中,servlet的beans中
建立数据库连接),每次连接都需要验证用户,消耗了大量的时间和资源。
而数据库连接池在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,
并非建立一个新的连接,而是从连接池中取出一个已经建立的空闲连接对象。使用完毕后,
用户不关闭连接,而是将数据库连接对象放回连接池中。数据库连接池管理数据连接的建立、断开,
同时监视数据库连接数量和使用情况。使用数据库连接池会显著提高整个应用程序的伸缩性,
(因为大大提高了连接数量)和健壮性(能够应对大量用户频繁连接数据库,减少系统资源的消耗)
提高了应用程序的性能指标。
-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!--导入德鲁伊数据源
Druid是阿里巴巴开源平台上一个数据库连接池实现,结合了c3p0、dbcp等DB池的优点,
同时加入了日志监控。
-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--再导入一个单元测试的-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
</dependencies>
</project>
2、创建数据源对象
3、设置数据源的基本连接数据
4、使用数据源获取连接资源和归还连接资源
因为引用了两个数据源,所以两个数据源的创建都写一下,对比着看
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
public class DataSourceTest {
@Test
//测试手动创建c3p0数据源
public void test1() throws Exception {
//创建c3p0的对象:ComboPooledDataSource
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//设置驱动
dataSource.setDriverClass("com.mysql.jdbc.Driver");
//设置路径
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm");
//设置用户名
dataSource.setUser("root");
//设置密码
dataSource.setPassword("121314");
//获取连接
Connection connection = dataSource.getConnection();
//输出一下connection,证明获取成功就行
System.out.println(connection);
//关闭连接
connection.close();
}
@Test
//测试手动创建德鲁伊数据源
public void test2() throws SQLException {
//创建德鲁伊的对象:ComboPooledDataSource
DruidDataSource dataSource = new DruidDataSource();
//设置驱动
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
//设置路径
dataSource.setUrl("jdbc:mysql://localhost:3306/ssm");
//设置用户名
dataSource.setUsername("root");
//设置密码
dataSource.setPassword("121314");
//获取连接
DruidPooledConnection connection = dataSource.getConnection();
//输出一下connection,证明获取成功就行
System.out.println(connection);
//关闭连接
connection.close();
}
}
从上面的程序可以看出,其中传入的字符串都是对应的数据库的配置信息,如果我们更换数据库的话势必会去修改源代码,这不利于程序的解耦合,所以我们采取的做法是抽取配置文件,将这些参数抽取到一个properties的键值对形式的文件当中(xml文件也行,但是xml解析文件费劲,所以还是这个好使)。
配置文件呢叫啥都行,一般叫jdbc.properties,放在resources根目录文件下
引用jdbc.properties之后,原来的程序就该改了
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ResourceBundle;
public class DataSourceTest {
@Test
//测试配置文件创建c3p0数据源
public void test1() throws Exception {
//读取配置文件的方式很多,这里采用最简单的java自带的ResourceBundle资源绑定工具
//传入的字符串是properties文件的名字
ResourceBundle rb = ResourceBundle.getBundle("jdbc");
//设置参数,getString方法中传入的是配置文件中的key值
String driver = rb.getString("jdbc.driver");
String url = rb.getString("jdbc.url");
String username = rb.getString("jdbc.username");
String password = rb.getString("jdbc.password");
//创建数据源对象 设置连接参数
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
//其他数据源同理,这里不再演示
}
}
抽取配置的文件目的说明
抽取配置文件的目的再说一下,这是为了解耦,这Java程序经过编译之后就成了字节码文件被打成jar或者war包,然而字节码文件我们是看不懂的,但是配置文件是不一样的,配置文件开发阶段长什么样打完包还长什么样,便于维护。我们要修改就可以直接修改包中的配置文件即可而不必修改字节码文件或者源代码。
重点:Spirng配置数据源
像DataSource这种对象也是不需要我们去创建的,可以交给Spring容器来帮我们做。
同时由上面的程序可以清晰的看出,在Spring中我们也是使用set方法来实现数据源注入的。
记得使用Spring之前先导入Spring的坐标:
<?xml version="1.0" encoding="UTF-8"?>
<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.Why</groupId>
<artifactId>SpringLearning</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--导入数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<!--导入c3p0数据源
c3p0是什么?
c3p0是一个库。它拓展了传统的jdbc数据库连接池,并且支持JDBC3和JDBC2的标准扩展
为什么使用c3p0?
首先,c3p0是一种jdbc数据库连接池,那么为什么要使用数据库连接池呢?因为数据库连接是一种
关键的、有限的、昂贵的资源。传统的模式(如传统的java web项目中,servlet的beans中
建立数据库连接),每次连接都需要验证用户,消耗了大量的时间和资源。
而数据库连接池在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,
并非建立一个新的连接,而是从连接池中取出一个已经建立的空闲连接对象。使用完毕后,
用户不关闭连接,而是将数据库连接对象放回连接池中。数据库连接池管理数据连接的建立、断开,
同时监视数据库连接数量和使用情况。使用数据库连接池会显著提高整个应用程序的伸缩性,
(因为大大提高了连接数量)和健壮性(能够应对大量用户频繁连接数据库,减少系统资源的消耗)
提高了应用程序的性能指标。
-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!--导入德鲁伊数据源
Druid是阿里巴巴开源平台上一个数据库连接池实现,结合了c3p0、dbcp等DB池的优点,
同时加入了日志监控。
-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--再导入一个单元测试的-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<!--导入Spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.1</version>
</dependency>
</dependencies>
</project>
然后在Spring的配置文件中配置上数据源:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--创建c3p0数据源:其他数据源同理-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--创建完bean之后,还要把那些属性注入-->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm"></property>
<property name="user" value="root"></property>
<property name="password" value="121314"></property>
</bean>
</beans>
在Spring中抽取jdbc配置文件
前面已经提过了,其实jdbc的配置文件用xml或者properties都行,已经到达了解耦合的作用,但这里还是会在上面的xml文件中对这些使用的属性进行抽取,这样做的好处是可以使得每个配置文件的作用域变得十分清晰。Spring的配置文件就只管Spring的,jdbc的配置文件就只管jdbc的。
那么怎么在Spring配置文件中去加载jdbc的配置文件呢?
问题又来了,那么长的句子,哪儿能全部记住啊,其实有方法可以参考的。
首先将主命名空间复制一份,这是beans的命名空间
xmlns="http://www.springframework.org/schema/beans"
然后粘贴在xmlns:xsi的下面,并在xmlns后面加上:context,且把后面部分中的beans全部改为context
xmlns:context="http://www.springframework.org/schema/context"
除了引入命名空间,还需要引入这个schema的真实地址在哪儿(就是xsi:schemaLocation那一块儿)。一样是老方法,将beans的地址复制一份,将其中的beans全部改为context,粘贴在主schema地址的后面即可,注意是合在一对儿双引号里的。再将Spring的表达式写上即完成Spring中的配置文件注入:
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--加载外部的配置文件
property-placeholder属性加载器,location:外部配置文件的位置
-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--配置c3p0数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--创建完bean之后,还要把那些属性注入
因为加载了jdbc的配置文件,所以可以用Spring的表达式来将这些值引入
引入值的Spring表达式:${}
-->
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
</beans>