Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说【JAVA】JAVA数据源「终于解决」,希望能够帮助你!!!。
我们在进行数据访问,声明模板和repository之前【JAVA】Spring对JDBC的支持,都需要配置数据源用来连接数据库。数据源又可以分为两大类:直连的数据源 和 连接池的数据源 ,其中连接池的数据源又有多种,接下来就让我们来学习一下这两种数据源。当然在学习之前,我们首先需要知道连接池、数据源、JNDI是什么,分别从当什么角色,有什么作用。
Java中的数据源就是连接到数据库的一条路径,数据源中并无真正的数据,它仅仅记录的是你连接到哪个数据库,以及如何连接。DataSource
的创建可以有不同的实现。DataSource
通常被称为数据源,它包含连接池 和连接池管理 两部分,习惯上也经常把DataSource
称为连接池。
在系统初始化的时候,将数据库连接对象(Connection) 存储在内存中,当用户需要访问数据库时候,并不是建立一个新的连接,而是从连接池中取出一个已经建立好的空闲连接对象。而连接池负责分配、管理、释放数据库连接对象。注意的是:连接池是由容器(比如tomcat) 提供的,同时容器也管理着连接池。
JNDI(Java Naming and Directory Interface,Java命名和目录接口),JNDI是Java平台的一个标准扩展,提供一组接口、类和关于命名空间的概念。其功能通俗的来说,就是提供一个类似全局的map,key保存JNDI的名称,value保存你要放到里面的资源的引用(如Java对象),以后要想要获取value的资源即可通过lookup
名称检索。
注意:需要区分开JNDI和通过JNDI查找的数据源的概念,不能将JNDI和连接池混为一谈。
使用JNDI访问Tomcat内置连接池
/lib/
中,这样Tomcat服务器才能找到数据库驱动context.xml
),创建数据库连接池,该连接池由Tomcat管理。用户每次请求都需要向数据库获得连接,而数据库创建连接通常需要消耗相对较大的资源,创建的时间也较长。
数据库连接是一种关键的有限的昂贵的资源,如果每次访问数据库的时候,都需要进行数据库连接,那么势必会造成性能低下;同时,如果用户失误忘记释放数据库连接,会导致资源的浪费等。而数据库连接池就是刚好可以解决这些问题,通过管理连接池中的多个连接对象(Connection),实现连接对象(connection)重复利用,从而大大提高了数据库连接方面的性能。
Tomcat在7.0以前的版本都是使用commons-dbcp作为连接池的实现,但是由于commons-dbcp饱受诟病。因此很多人会选择一些第三方的连接池组件,例如c3p0,bonecp等。为此,Tomcat从7.0开始引入了一个新的模块:Tomcat Jdbc Pool(Tomcat Dbcp)。关于更多请看这里
连接池的配置:
<Context>
<Resource
name="jdbc/login_register"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
maxActive="100" maxIdle="30" maxWait="10000"
username="root" password="root"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/db_user"/>
</Context>
属性的说明:
org.apache.tomcat.jdbc.pool.DataSourceFactory
javax.sql.DataSource
这里指定为连接池对象)。类型应为 javax.sql.DataSource 或 javax.sql.XADataSource。根据类型,将创org.apache.tomcat.jdbc.pool.DataSource 或 org.apache.tomcat.jdbc.pool.XADataSource。我们需要注意的属性是factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
如果你没有声明以上的属性,当Tomcat读到type="javax.sql.DataSource"
属性时也会自动安装DBCP,除非你指定不同的factory。
连接池的获取:
public class DBUtil {
public static Connection getConnection(){
Connection conn = null;
try {
Context c = new InitialContext();
DataSource dataSource = (DataSource) c.lookup("java:/comp/env/jdbc/login_register");//这里的jdbc/login_register和篇配置文件中的name属性一致
conn = dataSource.getConnection();
return conn;
} catch (SQLException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
return conn;
}
}
lookup
方法用于查找指定JNDI名称的连接池,java:/comp/env/jdbc/login_registe
的jdbc/login_registe
和配置文件中JNDI的名称相对应。这样既可查找到数据库连接池,也就能获得到连接对象了。当然,连接池的获取方式不只一种,比如还有通过配置文件来获取的,感兴趣的可以查阅资料。
大概流程是这样的:
Resource
声明资源为连接池类型(javax.sql.DataSource
)的对象org.apache.tomcat.jdbc.pool.DataSourceFactory
通过这个例子我们看到了JNDI的作用,JNDI你可以理解成一个水池的门牌,连接池就相当于这个水池,应用要取到要访问数据库时,通过找到JNDI,然后再通过连接池和数据库所建立的连接来访问。
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。C3P0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能。C3P0是改写的javax.sql.DataSource
。
连接池的配置
配置文件:c3p0-config.xml
<c3p0-config>
<default-config>
//默认是mysql数据库
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///项目名?useUnicode=true&characterEncoding=utf8</property>
<property name="user">数据库用户名</property>
<property name="password">数据库密码</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">10</property>
</default-config>
//也可以用oracle数据库
<named-config name="oracleConfig">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///项目名</property>
<property name="user">数据库用户名</property>
<property name="password">数据库密码</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">10</property>
</named-config>
</c3p0-config>
连接池的获取
// 创建c3p0连接池核心工具类
// 自动加载src下c3p0的配置文件【c3p0-config.xml】
ComboPooledDataSource dataSource = new ComboPooledDataSource();// 使用默认的配置
PreparedStatement pstmt = null;
// 获取连接
Connection con = dataSource.getConnection();
//执行sql语句
String sql="sql语句"
//执行
pstmt.executeUpdate();
//关闭连接
pstmt.close();
con.close();
注意:创建C3P0的连接池时候还可以在()加上名称,连接指定配置文件中的连接池。
ComboPooledDataSource dataSource =
new ComboPooledDataSource("oracleConfig");
当然数据库连接池除了以上的配置、获取方式外,还有别的方式,例如用JNDI配置和获取的。
连接池配置
在tomcat的context.xml里的标签添加标签:
<Resource name="jdbc/TestDB"
auth="Container"
factory="org.apache.naming.factory.BeanFactory"
type="com.mchange.v2.c3p0.ComboPooledDataSource"
driverClass="oracle.jdbc.driver.OracleDriver"
jdbcUrl="jdbc:oracle:thin:@localhost:1521:XE"
user="orcl"
password="newsnews"/>
不同数据源的 driverClass,jdbcUrl等 属性不同,依照连接池自身的属性配置,这里是使用的c3p0数据源,若使用其他数据源要修改属性。jdbc/TestDB
为JNDI名称。
在项目的web.xml添加
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
res-ref-name引入context.xml里配置的Resource,res-type都设置为javax.sql.DataSource。
在spring的applicationContext.xml配置里添加
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/comp/env/jdbc/TestDB" />
</bean>
DBCP(Database Connection Pool) 是一个依赖Jakarta commons-pool对象池机制的数据库连接池,Tomcat的数据源使用的就是DBCP。
连接池配置
dbcpconfig.properties文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_user
username=root
password=root
initialSize=10
maxActive=50
maxIdle=20
minIdle=5
maxWait=60000
connectionProperties=useUnicode=true;characterEncoding=utf8
defaultAutoCommit=true
defaultReadOnly=
defaultTransactionIsolation=REPEATABLE_READ
连接池获取
public class DBUtil {
public static Connection getConnection(){
Connection conn = null;
try {
conn = getDataSource().getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
private static DataSource getDataSource(){
DataSource dataSource=null;
Properties p = new Properties();
try {
p.load(DBUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"));
dataSource = BasicDataSourceFactory.createDataSource(p);
} catch (Exception e) {
throw new RuntimeException("获取DataSource对象失败");
}
return dataSource;
}
}
编写连接池需要实现javax.sql.DataSource
接口,具体可以网上查阅相关资料。
还有更多的连接池例如:Proxool、BoneCP、HikariCP、阿里druid等可以自行查阅资料。
以上,介绍了几种常用的数据源连接池;这几种连接池在使用过程,即支持硬编码的方式,也支持配置文件的配置方式;在正式实用的时候,应该尽量使用配置的方式,便于维护和管理。硬编码的方式,可以做为测试使用。同时,spring框架,通过他自己的方式集成上述几种数据源,理论上来说,都支持。各个数据源连接池都有一些公有的属性,因为他们都是从javax.sql.datasource继 承而来,而且都有最大连接数,初始化连接数等概念。同时,他们又分别有各自不同的属性,做了扩展。这里只是简单的介绍,在实际使用中,想要实现高性能的数 据库连接池管理,还需要深入研究每种方式的连接属性配置;例如:根据实际需要,设置合适的最小连接数和最大连接数,等待时间等。
欢迎加入JAVA学习群949419296,一起交流!
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。