数据库连接控制加强 | 学习笔记

简介: 简介:快速学习数据库连接控制加强

开发者学堂课程【DAO 开发实战业务分析:数据库连接控制加强】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/399/detail/5171


数据库连接控制加强

 

内容介绍:
一、简要介绍

二、步骤

三、总结


一、简要介绍

在整个 DAO 设计模式之中可以发现数据库的连接与连接控制都是放在了业务层之中完成,而后在实例化数据层对象的时候往往要有一个 Connection 接口对象。


二、步骤

· 观察 DAO 接口实现类,MessageDAOImpl :首先在此实现类之中,其代码有一个关键性的问题。

public MemberDAOImpl(Connection conn) {

this.conn = conn ;

}

通过观察,可发现在这个实现类上会发现需要一个明确的 Connection 作为构造的参数。

在工厂设计方法里面还需要使用 Constructor 明确地去进行

指定参数构造的调用。如果是真实的工厂最好运用的是无参。

public static < T > T getInstance(Class < T > cls,Connection{

try {

Constructor < T > cons = cls.getConstructor (Connection.class) ;

return cons.newInstance(conn) ;

} catch (Exception e) {

e.printStackTrace();

}

在整个 DAOFactory 的设计开发过程中,很少关注 Constructor,但现在必须去关注,因为需要得到一个明确的并且具备有 Connection 接口对象的操作。

· 既然 Connection 是整个操作的关键,如果没有 Connection 对象,整个的项目将无法运行,同时程序一定是多线程的模式来进行处理的,那么就必须考虑到每一个线程都可能有自己的 Connection 对象,所以现在最好的做法是使用 ThreadLocal 来实现 Connection 对象处理操作。真实的情况之中建议 DAO 的工厂类实现应该如下所示:

package cn.mldn.oracle.factory;

/**

* 取得DAO接口的工厂类

* @author mldn

*/

public class DAOFactory {

private DAOFactory(){}  // 为了不实现实例化对象

/**

* 定义DAO接口的对象取得

* @param cls 子类的Class对象

* @return 一个接口的实例化对象

*/

public static < T > T getInstance(Class < T > cls){

try {

return cls.newInstance() ;

} catch (Exception e) {

e.printStackTrace();

}

return null 

}

}

DAO 工厂最好的实现方法是通过 cls.newInstance() 来进行实例化而不是接收 connection,而采用反射的最大好处是没有实例化的同时整个过程也不会出错,因为所有的反射都不是固定类型而是动态加载类型。

· 此时如果要想通过业务层将 Connection 接口对象进行传递,就必须修改DatabaseConnection 的连接类。整个处理操作之中如果要使用 ThreadLocal 类来进行控制处理,那么就建议整体的方法都变为 static 是比较合适的。

首先 Memberservice 的 Connection 不再进行传,直接进行替换后可得到整个代码过程中只传了一个子类对象。

DatabaseConnection 要进行一个大的修改,原先是数据库进行连接处理,而现在改为写入 public static Connection rebuild Connection() {,指的是取得一个Connection 的接口对象,而返回的是一个 Connection 对象,即写入@return Connection 对象。

在整个代码的处理过程中,既然都是 static ,那么就要删除private Connection conn;,

将 this.conn =改为 return,否则为 return null 。但代码过程中的 Connection 不能被外部调用,因为 Connection 需要 ThreadLocale 包装,既然要通过ThreadLocale 进行包装,就写 private static ThreadLocale threadLocale = new ThreadLocale();,

表示保存每一个现成类的对象再进行引用操作,存的则是 Connection,

即表示为

private static ThreadLocale<Connection> threadLocale = new ThreadLocale<Connection>();。

用户关注的功能有 public static Connection getConnection() {以及public static void close() {,而两种方法都不采取。而此处表示取得一个Connection对象,是通过 ThreadLocal 类对象取得,每一个线程存放自己的对象,返回一个连接对象,即@return 返回一个连接对象。

当用户第一次执行操作时,跟上 Connection conn = threadLocal.get();,

这时表示取得一个 Connection。如果 if(conn == null) {,则表示现在还没有创建 Connection,ThreadLocal 没有保存数据,即写为threadLocal.set(rebuildConnection());,表示为保存对象。但要先进行接收,即conn = rebuildConnection();,表示为建立新的数据库连接对象,

再写为

threadLocal.set(rebuildConnection(conn);。随后 return conn;,此时连接便有了着落。而关闭数据库连接后要注意还是要通过 Connection conn = threadLocal.get();取得保存的对象,如果 if(conn != null){,表示现在还有连接对象,然后写入 conn.close();进行关网,如果 threadLocal 中还有对象则不能进行关网。

写入 threadLocal.remove();,表示清空 ThreadLocal 原本的内容,这时可表示为关闭。在对原始功能进行修改后,一个新的数据库连接类就完成了,原则为使用私有化构造方法去保存,如下:

package cn.mldn.oracle.dbc;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

/**

*本类负责Oracle数据库的连接与打开操作处理

*一旦实例化本类对象,将自动取得相对应的数据库连接

*@author mldn

*/

public class DatabaseConnection {

private static final String DBDRIVER

= “oracle.jdbc.driver.OracleDriver”;

private static final String DBURL

= “jbdc:oracle:thin:@localhost:1521:M”;

private static final String DBUSER = “scott”;

private static final String PASSWORD = “tiger”;

private static ThreadLocale<Connection> threadLocal = new ThreadLocale<Connection>() ;

/**

* 取得一个Connection接口对象

* @return Connection对象

*/

private static Connection rebuildConnection() ;

try {

Class.forName(DBDRIVER) ;

return DriverManager.getConnection() ;

} catch (Exception e) {

e.printStackTrace() ;

}

return null ;

}

/**

* 取得一个Connection对象,是通过ThreadLocal类对象取得

* @return 返回一个连接对象

*/

public static Connection get Connection() {

Connection conn = threadLocal.get() ;

if (conn == null) {  //表示现在还没有创建Connection,ThreadLocal没有保存数据

conn = rebuildConnection() ;  //建立新的数据库连接对象

threadLocal.set(conn);    

}

return conn ;

/**

* 关闭数据库连接

*/

public static void close() {

connection conn = threadLocal.get() ;

//取得保存的对象

if (conn !=null) {

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

//现在还有连接对象

}

threadLocal.remove() ;

//清空ThreadLocal原本的内容

}

}

}

· 当新的连接类对象完成之后,那么下面如果要想进行数据层的操作使用,直接通过 getConnection()方法就可以重复取出使用的连接对象。

public MemberDAOImpl(Connection conn) {

this.conn = DatabaseConnection.getaConnection() ;

· 但是在业务层里面需要进行数据库的连接关闭,而连接关闭直接使用 close()方法即可。

业务层里没有必要再做实例化对象,在业务层调用的时候少了一个实例对象,但如果在多线程的开发之中,每一个线程都有一个业务层的对象时,会发现对象不至少实例化一个而是少了很多,所以对于整个代码来说,一是结构变简单了,而是对象减少了,最重要的是反射变得方便。

· 那么此时的工厂类之中不再需要为 Constructor 类执行调用而痛苦了。

在进行改正后,打开 junit 进行检验操作看是否成功,但出现了 newInstance 错误,而数据层的构造方法应该使用无参,再次进行测试后,测试成功。


三、总结

在以后的项目开发之中,如果是手写代码,那么对于 Connection 数据库的连接控制必须要通过 ThreadLocal 类取得。

相关文章
|
7月前
|
存储 关系型数据库 MySQL
Linux C/C++ 开发(学习笔记八):Mysql数据库图片存储
Linux C/C++ 开发(学习笔记八):Mysql数据库图片存储
147 0
|
7月前
|
关系型数据库 MySQL 数据库
Linux C/C++ 开发(学习笔记七):Mysql数据库C/C++编程实现 插入/读取/删除
Linux C/C++ 开发(学习笔记七):Mysql数据库C/C++编程实现 插入/读取/删除
149 0
|
2月前
|
存储 SQL 关系型数据库
Mysql学习笔记(二):数据库命令行代码总结
这篇文章是关于MySQL数据库命令行操作的总结,包括登录、退出、查看时间与版本、数据库和数据表的基本操作(如创建、删除、查看)、数据的增删改查等。它还涉及了如何通过SQL语句进行条件查询、模糊查询、范围查询和限制查询,以及如何进行表结构的修改。这些内容对于初学者来说非常实用,是学习MySQL数据库管理的基础。
138 6
|
2月前
|
SQL Ubuntu 关系型数据库
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
本文为MySQL学习笔记,介绍了数据库的基本概念,包括行、列、主键等,并解释了C/S和B/S架构以及SQL语言的分类。接着,指导如何在Windows和Ubuntu系统上安装MySQL,并提供了启动、停止和重启服务的命令。文章还涵盖了Navicat的使用,包括安装、登录和新建表格等步骤。最后,介绍了MySQL中的数据类型和字段约束,如主键、外键、非空和唯一等。
75 3
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
|
3月前
|
SQL 关系型数据库 MySQL
php学习笔记-连接操作mysq数据库(基础)-day08
本文介绍了PHP中连接操作MySQL数据库的常用函数,包括连接服务器、设置字符集、关闭连接、选择数据库、结果集释放、获取影响行数以及遍历结果集等操作。通过书籍查询的实例演示了如何使用这些函数进行数据库操作,并提供了一个PHP操纵MySQL数据库的模板。
php学习笔记-连接操作mysq数据库(基础)-day08
|
4月前
|
SQL druid Java
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
60 3
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
|
4月前
|
SQL Java 关系型数据库
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(上)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
169 3
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(上)
|
4月前
|
SQL 关系型数据库 MySQL
Java数据库部分(MySQL+JDBC)(一、MySQL超详细学习笔记)(下)
Java数据库部分(MySQL+JDBC)(一、MySQL超详细学习笔记)
40 6
|
4月前
|
存储 关系型数据库 MySQL
Java数据库部分(MySQL+JDBC)(一、MySQL超详细学习笔记)(上)
Java数据库部分(MySQL+JDBC)(一、MySQL超详细学习笔记)
71 4
|
4月前
|
SQL 关系型数据库 MySQL
Java数据库部分(MySQL+JDBC)(一、MySQL超详细学习笔记)(中)
Java数据库部分(MySQL+JDBC)(一、MySQL超详细学习笔记)
35 3