首页 > 编程知识 正文

数据库接口如何实现,oracle数据库连接池

时间:2023-05-06 14:33:38 阅读:142851 作者:1945

连接池数据库连接池与线程池类似,显示时避免使用资源反复创建释放

数据库连接后台数据库连接是重要的、有限的、昂贵的资源。 这在多用户web APP应用中尤为明显。 管理数据库连接会严重影响整个APP应用程序的性能指标。 数据库连接池负责分配、管理和释放针对此问题提出的数据库连接池,以便APP应用程序可以重用现有的数据库连接。该技术可以提高数据库操作的性能

DataSource接口概述javax.sql.DataSource接口:数据源(数据库连接池)。 java DataSource提供的数据库连接池规范要完成数据库连接池的计数,必须实现此接口的核心功能。 获取数据库连接对象: Connection getConnection (自定义数据库连接池以定义类,并实现DataSource接口以定义包含多个连接对象的容器定义静态代码块,从JDBC工具类中检索10个连接并将其存储在容器中。 重写getConnection方法以从容器中检索连接并返回连接。 获取并返回容器大小的getSize ) )方法。/* * @ author : luoxin * @ create :2021-07-1602336036 * */package com.example.qqq; import javax.sql.DataSource; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import Java.SQL.sqlfeaturenotsupportedexception; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Logger; publicclassmydatasourcreimplementsdatasource { publicstaticvoidmain (string [ ] args ) }//打开用于存储多个连接对象的容器//因为需要线程安全集合,所以直接新建List对象privatestaticlistconnectionpool=collections.synchronized list (new ArrayList ) ) //定义静态代码块,从JDBC工具类中获取10个连接并将其存储在容器中。 //此处的JDBCUtils必须由您自己创建,而不是由官方提供的类创建。 怎么制作可以在网上确认。 也可以不通过//JDBCutils获取连接。 使用我们熟悉的DriverManeger.getConnection (也一样。 如果能获得连接,则为static (for ) ) ) 652 i10; I ) { connection con=JDBC utils.getconnection (; pool.add(con; 重写getConnection方法以从容器获取连接并返回。 @ overridepublicconnectiongetconnection (throws sqlexception ) if ) pool.size )0) connection connection=pool.re moon retun } else { throw new RuntimeException ('连接数已过期!' ); }//用于获取和返回容器大小的getSize (定义方法。 公共获取((return pool.size ) ); } @ overridepublicconnectiongetconnection (string username,String password ) throwssqlexception ) return空值; } @ overridepublictunwrap (classt iface ) Throwssqlexception ) returnnull; } @ overridepublicbooleaniswrapperfor (class? iface ) thr

ows SQLException { return false; } @Override public PrintWriter getLogWriter() throws SQLException { return null; } @Override public void setLogWriter(PrintWriter out) throws SQLException { } @Override public void setLoginTimeout(int seconds) throws SQLException { } @Override public int getLoginTimeout() throws SQLException { return 0; } @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { return null; }}

3 . 自定义数据库连接池的测试

创建连接池对象通过连接池对象获取连接对象通过连接对象对数据库进行操作释放资源(包括resultSet.close preparedstatement.close con.close)

但是当我们使用完一次之后查询连接池连接数发现数量变成了9,这并不符合我们的预期,我们创建数据库连接池就是为了不重复创建和释放对象,但现在看来这似乎与我们之前没有什么区别,都是在使用完一个连接对象后就释放了。

问题就出在con.close();这个方法会释放掉连接,但我们不想释放连接,而是想在close之后将原来的对象放回线程池中。即归还连接

归还连接的方式

继承方式 继承方式归还数据库的思想 通过printf(con)打印对象,发现DriveManeger获取的连接对象是JDBC4Connection那我们就自定义一个类,继承JDBC4Connection并重写close方法,完成连接对象的归还 继承方式归还数据库连接的实现步骤 定义一个类,继承JDBC4Connection定义Connection连接对象和连接池容器对象的成员变量通过有参构造方法完成对成员变量的赋值重写close方法,将连接对象添加到池中 /** * @author: luoxin * @create: 2021-07-16 03:27 **/package com.example.qqq;import com.mysql.jdbc.JDBC4Connection;import java.sql.Connection;import java.sql.SQLException;import java.util.List;import java.util.Properties;public class MyConnection1 extends JDBC4Connection { private Connection con; private List<Connection> pool;// 在原有构造方法的基础上添加了 Connection con , List<Connection> pool 两个参数 public MyConnection1(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url, Connection con , List<Connection> pool) throws SQLException { super(hostToConnectTo, portToConnectTo, info, databaseToConnectTo, url); this.con = con; this.pool = pool; } @Override public void close() throws SQLException { pool.add(con); } public static void main(String[] args) { }}

但是我们很快会发现,虽然我们重写了close方法,但这是我们自定义的类啊,而JDBCUtils获取的还是原来JDBC4Connection,而那里面的close方法并没有变化,如果我们想要获取自己定义的连接的话,就需要重写getConnection方法,也就是需要自己再定义一个类,但如果这个类中还有和前面一样的情况的话,我们仍然需要自定义类然后重写方法,这难度很大,所以我们不使用这种方法。

装饰设计模式

装饰设计模式归还数据库连接的思想

我们可以自定义一个类,实现Connection接口。这样就具备了和JDBC4Connection相同的行为了重写close方法,其余功能还调用mysql驱动包实现类原有方法即可

装饰设计模式归还数据库连接的实现步骤

定义一个类实现Connection接口

定义Connection连接对象和连接池容器对象的成员变量

通过有参构造方法完成对成员变量的赋值

自己定义带两个参数的构造方法

public MyConnection2(Connection con , List<Connection> pool) { this.con = con; this.pool = pool; }

重写close方法

​ 和之前一样

剩余方法,只需要调用mysql驱动包的连接对象完成即可

​ 这是一个工程量巨大的工作,因为方法很多,去网上找现有的吧

在自定义连接池中,将获取的连接对象通过自定义连接对象进行包装

​ 找到我们自定义的连接池对象类,修改GetConnection方法,使其返回我们自定义的Connection:

@Override public Connection getConnection() throws SQLException { if(pool.size()>0) { Connection connection = pool.remove(0); MyConnection2 con = new MyConnection2(connection,pool); return con; } else { throw new RuntimeException("连接数量已用完!"); } }

这时候再运行测试类,就会发现运行前后的数量不会变化。完成了我们需要实现的功能。

但是这种方法也较为麻烦,有大量方法需要重写(第五步)

适配器设计模式

适配器模式归还数据库连接的思想

我们可以提供一个适配器类(也叫中间类,一般为抽象类),实现Connection接口,将所有方法进行实现(除了close)自定义连接类只需继承这个适配器类,重写close方法即可

适配器模式归还数据库连接的步骤

​ 通过这种方法,虽然自定义类实现的功能少了,但是适配器类还是需要我们自己编写,完成的工作量其实并没有减少

动态代理模式(建议先了解以下反射)

动态代理:在不改变目标对象方法的情况下对方法进行增强

组成

被代理对象:真是的对象代理对象:内存中的一个对象(没有具体的java文件)

要求

代理对象必须和被代理对象实现相同接口

实现

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h); proxy就是代理的意思,需要三个参数,第一个参数是一个类加载器,第二个参数是一个接口类型Class数组,第三个参数代表代理规则。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IzdLi6Jz-1626404421215)(C:Usersluo’xinAppDataRoamingTyporatypora-user-imagesimage-20210716043217984.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5p3ZfxwG-1626404421218)(C:Usersluo’xinAppDataRoamingTyporatypora-user-imagesimage-20210716043247909.png)]

被代理对象实现相同接口

实现

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h); proxy就是代理的意思,需要三个参数,第一个参数是一个类加载器,第二个参数是一个接口类型Class数组,第三个参数代表代理规则。

连接池原理已经学习完毕,其实我们可以直接使用第三方的功能强大的连接池

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。