JavaWeb-JDBC连接池、JDBC框架
来源:互联网 发布:网络涉黄举报 编辑:程序博客网 时间:2024/05/17 11:58
一、连接池概念
- 应用程序直接获取连接的缺点
- 出现的问题
- 用户请求Servlet,Servlet请求Service,Service调用Dao。
- 用户请求多次,Dao需要打开关闭connection多次。
- 频繁的开关connection很多次,浪费时间和消耗资源,并且容易造成数据库服务器内存溢出、宕机。
- 连接池图示
- 解决方法-连接池
- 解决方法:连接资源有限,需要重复利用,而不是关闭。怎么重复利用,连接池。
- 连接池:连接池是一个pool(缓存),里面封装了一个数据或者集合,这里使用List集合。
- 过程:每次应用启动的时候,创建一片缓存,即连接池,连接池中创建一定的connection对象。用户访问的时候从连接池取出一个connection连接,当使用结束后需要还回这个connection。
二、编写连接池遇到的问题
- 要对connection进行归还,需要重写connection的close方法。调用close的时候,归还这个conenction到连接池中。
- 对一个已有类com.mysql.Connection(不能修改)中的某个方法进行增强或者更改它的行为,直接继承可以吗?
- 直接继承在这里不可以,因为close方法中,归还的时候,父类的一些参数(URL、username、password)不能一起归还。
- com.mysql.Connection这个接口中的方法,都没有实现。(这里看一下Connection是哪个包中的,还有是接口还是类。)
- 简单的连接池:自己编写的简单连接池太简单,实际开发中不能满足需求。
三、编写数据库连接池的原理。
- 编写连接池需实现javax.sql.DataSource接口。
- 只有实现了这个接口,才是一个标准的数据连接池(数据源)
- 框架中就是使用这个接口的实现得到连接。上面简单的连接池没有实现,框架没法调用所以不规范。
- DataSource接口中定义了两个重载的getConnection方法:
- Connection getConnection()
Connection getConnection(String username, String password)(基本都不实现)
- 总体思路
- 实现DataSource接口,并实现连接池功能的步骤:
- 在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加入LinkedList对象中。
- 实现getConnection方法,让getConnection方法每次调用时,从LinkedList中取一个Connection返回给用户。
- 当用户使用完Connection,调用Connection.close()方法时,Collection对象应保证将自己返回到LinkedList中,而不要把conn还给数据库。
- Collection保证将自己返回到LinkedList中是此处编程的难点。
四、连接池的实现
- 使用包装设计模式,包装:com.mysql.jdbc.Connection
- 编写一个类,实现与被包装类相同的接口或继承被包装类
- 定义一个私有变量,记住被包装对象的引用,LinkedList<Connection>对象
- 定义构造方法,传入被包装对象的引用
- 对于要增强的方法,只管重写
- 对于不需要增强的方法,调用原有对象的原有方法。、
- 包装设计模式的实现
- 思路:
- 默认适配器实现了Connection接口,子类继承了默认适配器
- 用户要连接的时候,拿到的是适配器的子类
- 适配器的子类重写了close方法,并且引用了Connection对象和LinkedList<Connection>对象。当调用close时,把Connection对象添加到集合中。
- 下面为参考:
- 调用Connection对象的close()方法时, 为阻止系统销毁该连接, 而改为将连接归还给连接池, 可以采用包装设计模式. 此时包装的目标类为Connection, 因此需要定义MyConnection类并实现Connection接口. MyConnection类应该存在2个成员: Connection对象和LinkedList<Connection>对象, 这2个成员可以通过构造函数存入. 同时需要覆写close()方法, 在close()方法中实现将Connection添加到集合中.
- 核心代码
- 思路:
- 动态代理
- 编写一个与目标类具有相同接口的代理类,当外界访问被代理类时,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码。
- 代理类的缺陷是,只能代理接口中的方法。
- 思路:
- 用户要连接的时候,不给他原有对象,而是给一个代理(proxy)对象
- 这个代理类是com.mysql.jdbc.Connection的代理类$Proxy0
- 三个参数及用途
- 代理类的类加载器是所在的类的类加载器
- 代理类与被代理对象conn有相同的接口conn.getClass().getInterfaces(),所以有相同的行为。
- 代理类通过内部类invoke拦截想要的方法close,把conn返回池中
- 核心代码;
- 动态代理模式的实现
- 思路:
- 在内存中创建一集合,其中包含固定数目的连接。
- 获取连接时,直接从集合中获取集合对象。
- 关闭连接时,将不同的集合对象再加入集合中.
- 要遵循先入先出的原则(LinkedList.removeLast方法)
- 核心代码
- proxyConn = (Connection) Proxy.newProxyInstance(this.getClass()
- .getClassLoader(), conn.getClass().getInterfaces(),
- new InvocationHandler() {
- //此处为内部类,当close方法被调用时将conn还回池中,其它方法直接执行
- public Object invoke(Object proxy, Method method,
- Object[] args) throws Throwable {
- if (method.getName().equals("close")) {
- pool.addLast(conn);
- return null;
- }
- return method.invoke(conn, args);
- }
- });
- 思路:
五、开源的连接池使用
- 现在很多WEB服务器(Weblogic, WebSphere, Tomcat)都提供了DataSoruce的实现,即连接池的实现。通常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现。
- 也有一些开源组织提供了数据源的独立实现:
- DBCP 数据库连接池
- C3P0 数据库连接池
- 实际应用时不需要编写连接数据库代码,直接从数据源获得数据库的连接。程序员编程时也应尽量使用这些数据源的实现,以提升程序的数据库访问性能。
- DBCP():全称是Data Base Connectivity Pool
- DBCP 是 Apache 软件基金组织下的开源连接池实现,使用DBCP数据源,应用程序应在系统中增加如下两个 jar 文件:
- Commons-dbcp.jar:连接池的实现
- Commons-pool.jar:连接池实现的依赖库
- 使用DBCP
- static{
- InputStream in = JdbcUtil.class.getClassLoader().
- getResourceAsStream("dbcpconfig.properties");
- Properties prop = new Properties();
- prop.load(in);
- BasicDataSourceFactory factory = new BasicDataSourceFactory();
- dataSource = factory.createDataSource(prop);
- }
- <-这是DBCP使用的配置文件
- 原理是用的包装
- C3P0()
- 原理是用的代理、
- Tomcat 的连接池是采用 DBCP连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。
- 前提:拷贝数据库的驱动到Tomcat\lib目录下
- 在应用的META-INF目录下建立一个名字为context.xml的配置文件,内容如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <Context>
- <Resource name="jdbc/day14" auth="Container" type="javax.sql.DataSource"
- maxActive="30" maxIdle="10" maxWait="10000"
- username="root" password="sorry" driverClassName="com.mysql.jdbc.Driver"
- url="jdbc:mysql://localhost:3306/day14"/>
- </Context>
- 注:经过以上配置,容器启动时就是会创建好数据源。
- 获取数据源并使用。(JNDI的API)Java Naming and Directory Interface Java命名与目录服务
- Context initContext = new InitialContext();
- DataSource ds = (DataSource)initContext.lookup("java:/comp/env/jdbc/day14");
- Connection conn = ds.getConnection();
- 特别提醒:此种配置下,驱动jar文件需放置在tomcat的lib下
- JNDI简介:
- JNDI(Java Naming and Directory Interface),Java命名和目录接口,它对应于J2SE中的javax.naming包,
- 这套API的主要作用在于:它可以把Java对象放在一个容器中(JNDI容器),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需通过名称检索即可。
- 其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。
七、获取数据库的元信息(编写框架用)
- 元数据:数据库、表、列的定义信息。
- 元数据- DataBaseMetaData
- 获得:Connection.getMetaData()
- 返回 DataBaseMetaData对象
- DataBaseMetaData对象
- getURL():返回一个String类对象,代表数据库的URL。
- getUserName():返回连接当前数据库管理系统的用户名。
- getDatabaseProductName():返回数据库的产品名称。
- getDatabaseProductVersion():返回数据库的版本号。
- getDriverName():返回驱动驱动程序的名称。
- getDriverVersion():返回驱动程序的版本号。
- isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。
- 获得:Connection.getMetaData()
- 元数据- ParameterMetaData
- 获得:PreparedStatement . getParameterMetaData() :
- 返回代表PreparedStatement元数据的ParameterMetaData对象。(可得到有几个问号)
- Select * from user where name=? And password=?
- ParameterMetaData对象
- getParameterCount() :获得指定参数的个数
- getParameterType(int param) :获得指定参数的sql类型(驱动可能不支持)
- 获得:PreparedStatement . getParameterMetaData() :
- 元数据- ResultSetMetaData
- ResultSet. getMetaData()
- 返回代表ResultSet对象元数据的ResultSetMetaData对象。
- ResultSetMetaData对象
- getColumnCount() :返回resultset对象的列数
- getColumnName(int column): 获得指定列的名称,从第一列开始
- getColumnTypeName(int column):获得指定列的类型 java.sql.Types
- ResultSet. getMetaData()
- 元数据的应用-使用元数据简化JDBC代码
- 业务背景:系统中所有实体对象都涉及到基本的CRUD操作:
- 所有实体的CUD操作代码基本相同,仅仅发送给数据库的SQL语句不同而已,因此可以把CUD操作的所有相同代码抽取到工具类的一个update方法中,并定义参数接收变化的SQL语句。
- 实体的R操作,除SQL语句不同之外,根据操作的实体不同,对ResultSet的映射也各不相同,因此可义一个query方法,除以参数形式接收变化的SQL语句外,可以使用策略模式由qurey方法的调用者决定如何把ResultSet中的数据映射到实体对象中。(Bean,BeanList,Long)
- 核心代码
- String columnName = md.getColumnName(i);
- Object columnData = rs.getObject(i);
- Field feild = clazz.getDeclaredField(columnName);
- feild.setAccessible(true);
- feild.set(obj, columnData);
八、自定义JDBC框架
- 策略设计模式
- 反射和泛型
- JavaWeb-JDBC连接池、JDBC框架
- JavaWeb-JDBC-数据连接池
- JavaWeb-JDBC连接数据库
- JavaWeb入门:JDBC连接数据库
- javaweb通过jdbc连接数据库
- javaweb—JDBC连接数据库
- javaweb之自定义JDBC框架
- JavaWeb JDBC初步连接和JDBC连接规范化
- 连接池,元数据与jdbc框架
- JavaWeb系列之十三(jdbc事务与连接池)
- JavaWeb-JDBC
- JavaWeb----JDBC
- JavaWeb:JDBC
- idea下javaWeb jdbc连接sqlite数据库
- JavaWeb-JDBC-1-不仅仅只是连接
- JavaWeb-JDBC-2-不仅仅只是连接
- JavaWeb-JDBC-3-不仅仅只是连接
- JavaWeb JDBC连接MySql数据库小项目
- CSS 基础:HTML 标记与文档结构(1)<思维导图>
- 怎么做才能拥有良好的网站用户体验
- 机器学习实战决策树之眼镜男买眼镜
- 怎么看php有没有支持mysql
- Dialog about college and College Entrance Examination
- JavaWeb-JDBC连接池、JDBC框架
- 这十几年编程的不同认知层次——摘自聊天记录
- java获取各种常用时间方法
- 谷歌搜索引擎的语音功能特色j
- 第一年续签总结以及工作第二年的发展计划
- 网站如何做到完全不需要jQuery
- UVa 357 - Let Me Count The Ways
- ClipSync -- 安卓手机的黄金搭档
- 项目技术选用要求