编程实验
JDBC是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也是个商标名。
有了JDBC,向各种关系数据发送SQL语句就是一件很容易的事。换言之,有了JDBC API,就不必为访问Sybase数据库专门写一个程序,为访问Oracle数据库又专门写一个程序,或为访问Informix数据库又编写另一个程序等等,程序员只需用JDBC API写一个程序就够了,它可向相应数据库发送SQL调用。同时,将Java语言和JDBC结合起来使程序员不必为不同的平台编写不同的应用程序,只须写一遍程序就可以让它在任何平台上运行,这也是Java语言“编写一次,处处运行”的优势。
Java数据库连接体系结构是用于Java应用程序连接数据库的标准方法。JDBC对Java程序员而言是API,对实现与数据库连接的服务提供商而言是接口模型。作为API,JDBC为程序开发提供标准的接口,并为数据库厂商及第三方中间件厂商实现与数据库的连接提供了标准方法。JDBC使用已有的SQL标准并支持与其它数据库连接标准,如ODBC之间的桥接。JDBC实现了所有这些面向标准的目标并且具有简单、严格类型定义且高性能实现的接口。
Java 具有坚固、安全、易于使用、易于理解和可从网络上自动下载等特性,是编写数据库应用程序的杰出语言。所需要的只是 Java应用程序与各种不同数据库之间进行对话的方法。而 JDBC 正是作为此种用途的机制。
JDBC 扩展了 Java 的功能。例如,用 Java 和 JDBC API 可以发布含有 applet 的网页,而该 applet 使用的信息可能来自远程数据库。企业也可以用 JDBC 通过 Intranet 将所有职员连到一个或多个内部数据库中(即使这些职员所用的计算机有 Windows、 Macintosh 和UNIX 等各种不同的操作系统)。随着越来越多的程序员开始使用Java 编程语言,对从 Java 中便捷地访问数据库的要求也在日益增加。
MIS管理员们都喜欢 Java 和 JDBC 的结合,因为它使信息传播变得容易和经济。企业可继续使用它们安装好的数据库,并能便捷地存取信息,即使这些信息是储存在不同数据库管理系统上。新程序的开发期很短。安装和版本控制将大为简化。程序员可只编写一遍应用程序或只更新一次,然后将它放到服务器上,随后任何人就都可得到最新版本的应用程序。对于商务上的销售信息服务, Java 和JDBC 可为外部客户提供获取信息更新的更好方法。
在一般用JDBC 进行连接数据库进行CRUD操作时,每一次都会:
通过:java.sql.Connection conn = DriverManager.getConnection(url,user,password); 重新获取一个数据库的链接再进行操作,这样用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。
所以为了减少服务器的压力,便可用连接池的方法:在启动Web应用时,数据就创建好一定数量的Connection链接
存放到一个容器中,然后当用户请求时,服务器则向容器中获取Connection链接来处理用户的请求,当用户的请求完成后,
又将该Connection 链接放回到该容器中。这样的一个容器称为连接池。
编写一个基本的连接池实现连接复用
步骤:
1、建立一个数据库连接池容器。(因为方便存取,则使用LinkedList集合)
2、初始化一定数量的连接,放入到容器中。
3、等待用户获取连接对象。(该部分要加锁)
|---记得删除容器中对应的对象,放置别人同时获取到同一个对象。
4、提供一个方法,回收用户用完的连接对象。
5、要遵循先入先出的原则。
1 import java.io.InputStream;
2 import java.sql.Connection;
3 import java.sql.DriverManager;
4 import java.sql.SQLException;
5 import java.util.LinkedList;
6 import java.util.Properties;
7
8
9 /**
10 * 一个基本的数据连接池:
11 * 1、初始化时就建立一个容器,来存储一定数量的Connection 对象
12 * 2、用户通过调用MyDataSource 的getConnection 来获取Connection 对象。
13 * 3、再通过release 方法来回收Connection 对象,而不是直接关闭连接。
14 * 4、遵守先进先出的原则。
15 *
16 *
17 * @author 贺佐安
18 *
19 */
20 public class MyDataSource {
21 private static String url = null;
22 private static String password = null;
23 private static String user = null ;
24 private static String DriverClass = null;
25 private static LinkedList《Connection》 pool = new LinkedList《Connection》() ;
26 // 注册数据库驱动
27 static {
28 try {
29 InputStream in = MyDataSource.class.getClassLoader()
30 .getResourceAsStream(“db.properties”);
31 Properties prop = new Properties();
32 prop.load(in);
33 user = prop.getProperty(“user”);
34 url = prop.getProperty(“url”) ;
35 password = prop.getProperty(“password”) ;
36 DriverClass = prop.getProperty(“DriverClass”) ;
37 Class.forName(DriverClass) ;
38
39 } catch (Exception e) {
40 throw new RuntimeException(e) ;
41 }
42 }
43 //初始化建立数据连接池
44 public MyDataSource () {
45 for(int i = 0 ; i 《 10 ; i ++) {
46 try {
47 Connection conn = DriverManager.getConnection(url, user, password) ;
48 pool.add(conn) ;
49 } catch (SQLException e) {
50 e.printStackTrace();
51 }
52 }
53 }
54 //、从连接池获取连接
55 public Connection getConnection() throws SQLException {
56 return pool.remove() ;
57 }
58 // 回收连接对象。
59 public void release(Connection conn) {
60 System.out.println(conn+“被回收”);
61 pool.addLast(conn) ;
62 }
63 public int getLength() {
64 return pool.size() ;
65 }
66 }
这样当我们要使用Connection 连接数据库时,则可以直接使用连接池中Connection 的对象。测试如下:
1 import java.sql.Connection;
2 import java.sql.SQLException;
3
4 import org.junit.Test;
5
6
7 public class MyDataSourceTest {
8
9
10 /**
11 * 获取数据库连接池中的所有连接。
12 */
13 @Test
14 public void Test() {
15 MyDataSource mds = new MyDataSource() ;
16 Connection conn = null ;
17 try {
18
19 for (int i = 0 ; i 《 20 ; i ++) {
20 conn = mds.getConnection() ;
21 System.out.println(conn+“被获取;连接池还有:”+mds.getLength());
22 mds.release(conn) ;
23 }
24 } catch (SQLException e) {
25 e.printStackTrace();
26 }
27 }
28 }
再运行的时候,可以发现,循环10次后,又再一次获取到了第一次循环的得到的Connection对象。所以,这样可以大大的减轻数据库的压力。上面只是一个简单的数据库连接池,不完美的便是,回收需要调用数据池的release() 方法来进行回收,那么可以不可以直接调用Connection 实例的close 便完成Connection 对象的回收呢?
》 编写连接池需实现javax.sql.DataSource接口。
》 实现DataSource接口,并实现连接池功能的步骤:
1、在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加入LinkedList对象中。
2、实现getConnection方法,让getConnection方法每次调用时,从LinkedList中取一个Connection返回给用户。当用户使用完Connection,调用Connection.close()方法时,Collection对象应保证将自己返回到LinkedList中,而不要把conn还给数据库。
利用动态代理和包装设计模式来标准的数据源。
1、包装设计模式实现标准数据源:
这里的用包装设计模式,便是将Connection 接口进行包装。简单总结一下包装设计模式的步骤:
a)定义一个类,实现与被包装类()相同的接口。
|----可以先自己写一个适配器,然后后面继承这个适配器,改写需要改写的方法,提高编程效率。
b)定义一个实例变量,记住被包装类的对象的引用。
c)定义构造方法,转入被包装类的对象。
e)对需要改写的方法,改写。
f)对不需要改写的方法,调用原来被包装类的对应方法。
所以先编写一个类似适配器的类,将Connection 接口的方法都进行实现:
View Code
然后再对Connection 接口进行包装,将close 方法修改掉:
1 import java.sql.Connection;
2 import java.sql.SQLException;
3 import java.util.LinkedList;
4 /**
5 * 对MyConnectionAdapter 进行包装处理
6 * @author 贺佐安
7 *
8 */
9 public class MyConnectionWrap extends MyConnectionAdapter {
10
11 private LinkedList《Connection》 pool = new LinkedList《Connection》() ;
12 public MyConnectionWrap(Connection conn ,LinkedList《Connection》 pool ) {
13 super(conn);
14 this.pool = pool ;
15 }
16
17 //改写要实现的方法
18 public void close() throws SQLException {
19 pool.addLast(conn) ;
20 }
21 }
编写标准数据源:
1 import java.io.PrintWriter;
2 import java.sql.Connection;
3 import java.sql.DriverManager;
4 import java.sql.SQLException;
5 import java.util.LinkedList;
6 import java.util.ResourceBundle;
7
8 import javax.sql.DataSource;
9
10
11 /**
12 * 编写标准的数据源:
13 * 1、实现DataSource 接口
14 * 2、获取在实现类的构造方法中批量获取Connection 对象,并将这些Connection 存储
15 * 在LinkedList 容器中。
16 * 3、实现getConnection() 方法,调用时返回LinkedList容器的Connection对象给用户。
17 * @author 贺佐安
18 *
19 */
20 public class MyDataSource implements DataSource{
21 private static String url = null;
22 private static String password = null;
23 private static String user = null ;
24 private static String DriverClass = null;
25 private static LinkedList《Connection》 pool = new LinkedList《Connection》() ;
26
27 // 注册数据库驱动
28 static {
29 try {
30 ResourceBundle rb = ResourceBundle.getBundle(“db”) ;
31 url = rb.getString(“url”) ;
32 password = rb.getString(“password”) ;
33 user = rb.getString(“user”) ;
34 DriverClass = rb.getString(“DriverClass”) ;
35 Class.forName(DriverClass) ;
36
37 //初始化建立数据连接池
38 for(int i = 0 ; i 《 10 ; i ++) {
39 Connection conn = DriverManager.getConnection(url, user, password) ;
40 pool.add(conn) ;
41 }
42 } catch (Exception e) {
43 throw new RuntimeException(e) ;
44 }
45
46 }
47 public MyDataSource () {
48 }
49
50 //、从连接池获取连接:通过包装模式
51 public synchronized Connection getConnection() throws SQLException {
52 if (pool.size() 》 0) {
53 MyConnectionWrap mcw = new MyConnectionWrap(pool.remove(), pool) ;
54 return mcw ;
55 }else {
56 throw new RuntimeException(“服务器繁忙!”);
57 }
58 }
59
60 // 回收连接对象。
61 public void release(Connection conn) {
62 System.out.println(conn+“被回收”);
63 pool.addLast(conn) ;
64 }
65
66 public int getLength() {
67 return pool.size() ;
68 }
69
70
71 @Override
72 public PrintWriter getLogWriter() throws SQLException {
73 return null;
74 }
75 @Override
76 public void setLogWriter(PrintWriter out) throws SQLException {
77
78 }
79 @Override
80 public void setLoginTimeout(int seconds) throws SQLException {
81
82 }
83 @Override
84 public int getLoginTimeout() throws SQLException {
85 return 0;
86 }
87 @Override
88 public 《T》 T unwrap(Class《T》 iface) throws SQLException {
89 return null;
90 }
91 @Override
92 public boolean isWrapperFor(Class《?》 iface) throws SQLException {
93 return false;
94 }
95 @Override
96 public Connection getConnection(String username, String password)
97 throws SQLException {
98 return null;
99 }
100
101 }
2、动态代理实现标准数据源:
相对于用包装设计来完成标准数据源,用动态代理则方便许多:
1 import java.io.PrintWriter;
2 import java.lang.reflect.InvocationHandler;
3 import java.lang.reflect.Method;
4 import java.lang.reflect.Proxy;
5 import java.sql.Connection;
6 import java.sql.DriverManager;
7 import java.sql.SQLException;
8 import java.util.LinkedList;
9 import java.util.ResourceBundle;
10
11 import javax.sql.DataSource;
12
13
14 /**
15 * 编写标准的数据源:
16 * 1、实现DataSource 接口
17 * 2、获取在实现类的构造方法中批量获取Connection 对象,并将这些Connection 存储
18 * 在LinkedList 容器中。
19 * 3、实现getConnection() 方法,调用时返回LinkedList容器的Connection对象给用户。
20 * @author 贺佐安
21 *
22 */
23 public class MyDataSource implements DataSource{
24 private static String url = null;
25 private static String password = null;
26 private static String user = null ;
27 private static String DriverClass = null;
28 private static LinkedList《Connection》 pool = new LinkedList《Connection》() ;
29
30 // 注册数据库驱动
31 static {
32 try {
33 ResourceBundle rb = ResourceBundle.getBundle(“db”) ;
34 url = rb.getString(“url”) ;
35 password = rb.getString(“password”) ;
36 user = rb.getString(“user”) ;
37 DriverClass = rb.getString(“DriverClass”) ;
38 Class.forName(DriverClass) ;
39
40 //初始化建立数据连接池
41 for(int i = 0 ; i 《 10 ; i ++) {
42 Connection conn = DriverManager.getConnection(url, user, password) ;
43 pool.add(conn) ;
44 }
45 } catch (Exception e) {
46 throw new RuntimeException(e) ;
47 }
48 }
49 public MyDataSource () {
50
51 }
52
53 //、从连接池获取连接:通过动态代理
54 public Connection getConnection() throws SQLException {
55 if (pool.size() 》 0) {
56 final Connection conn = pool.remove() ;
57 Connection proxyCon = (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(),
58 new InvocationHandler() {
59 //策略设计模式:
60 @Override
61 public Object invoke(Object proxy, Method method, Object[] args)
62 throws Throwable {
63 if(“close”.equals(method.getName())){
64 //谁调用,
65 return pool.add(conn);//当调用close方法时,拦截了,把链接放回池中了
66 }else{
67 return method.invoke(conn, args);
68 }
69 }
70 });
71 return proxyCon ;
72 }else {
73 throw new RuntimeException(“服务器繁忙!”);
74 }
75 }
76
77 public int getLength() {
78 return pool.size() ;
79 }
80
81
82 @Override
83 public PrintWriter getLogWriter() throws SQLException {
84 return null;
85 }
86 @Override
87 public void setLogWriter(PrintWriter out) throws SQLException {
88
89 }
90 @Override
91 public void setLoginTimeout(int seconds) throws SQLException {
92
93 }
94 @Override
95 public int getLoginTimeout() throws SQLException {
96 return 0;
97 }
98 @Override
99 public 《T》 T unwrap(Class《T》 iface) throws SQLException {
100 return null;
101 }
102 @Override
103 public boolean isWrapperFor(Class《?》 iface) throws SQLException {
104 return false;
105 }
106 @Override
107 public Connection getConnection(String username, String password)
108 throws SQLException {
109 return null;
110 }
111 }
当然觉得麻烦的则可以直接使用一些开源的数据源如:DBCP、C3P0等。DBCP的原理是用包装设计模式开发的数据源,而C3P0则是动态代理的。
1、DBCP的使用:
1 import java.io.InputStream;
2 import java.sql.Connection;
3 import java.sql.SQLException;
4 import java.util.Properties;
5
6 import javax.sql.DataSource;
7
8 import org.apache.commons.dbcp.BasicDataSourceFactory;
9
10 /**
11 * 创建DBCP 工具类
12 * @author 贺佐安
13 *
14 */
15 public class DbcpUtil {
16 private static DataSource ds = null ;
17 static {
18 try {
19 //读取配置文件
20 InputStream in = DbcpUtil.class.getClassLoader().getResourceAsStream(“dbcpconfig.properties”) ;
21 Properties prop = new Properties() ;
22 prop.load(in) ;
23
24 //通过BasicDataSourceFactory 的creatDataSurce 方法创建 BasicDataSource 对象。
25 ds = BasicDataSourceFactory.createDataSource(prop) ;
26
27 } catch (Exception e) {
28 e.printStackTrace();
29 }
30 }
31 public static DataSource getDs() {
32 return ds ;
33 }
34 public static Connection getConnection () {
35 try {
36 return ds.getConnection() ;
37 } catch (SQLException e) {
38 throw new RuntimeException() ;
39 }
40 }
41 }
2、C3P0 的使用:
1 import java.sql.Connection;
2 import java.sql.SQLException;
3
4 import com.mchange.v2.c3p0.ComboPooledDataSource;
5 /**
6 * C3P0 开源数据源的使用
7 * @author 贺佐安
8 *
9 */
10 public class C3p0Util {
11 private static ComboPooledDataSource cpds = null ;
12 static {
13
14 cpds = new ComboPooledDataSource() ;
15 }
16 public static Connection getConnection() {
17 try {
18 return cpds.getConnection() ;
19 } catch (SQLException e) {
20 throw new RuntimeException() ;
21 }
22 }
23 }
使用这两个数据源时,直接调用获取到的Connection 连接的close 方法,也是将连接放到pool中去。
三、元数据(DatabaseMetaData)信息的获取
》 元数据:数据库、表、列的定义信息。
》 元数据信息的获取:为了编写JDBC框架使用。
1、数据库本身信息的获取:java.sql.DataBaseMateData java.sql.Connection.getMetaData() ;
DataBaseMateData 实现类的常用方法:
getURL():返回一个String类对象,代表数据库的URL。
getUserName():返回连接当前数据库管理系统的用户名。
getDatabaseProductName():返回数据库的产品名称。
getDatabaseProductVersion():返回数据库的版本号。
getDriverName():返回驱动驱动程序的名称。
getDriverVersion():返回驱动程序的版本号。
isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。
2、ParameterMetaData: 代表PerparedStatment 中的SQL 参数元数据信息: java.sql.ParameterMetaData java.sql.PerparedStatement.getParameterMetaData() ;
ParameterMetaData 实现类常用方法:
getParameterCount() :获得指定参数的个数
getParameterType(int param) :获得指定参数的sql类型(驱动可能不支持)
3、ResultSetMetaData : 代表结果集的源数据信息:相当于SQL 中的 :DESC java.sql.ResultSetMetaData java.sql.ResultSet.getMetaData() ;
java.sql.ResultSetMetaData 接口中常用的方法:
a) getColumnCount() : 获取查询方法有几列。
b) getColumnName(int index) : 获取列名:index从1开始。
c) getColumnType(int index) : 获取列的数据类型。返回的是TYPES 中的常量值。
四、编写自己的JDBC框架:
JDBC框架的基本组成:
1、核心类:
a、定义一个指定javax.sql.DataSource 实例的引用变量,通过构造函数获取指定的实例并给定义的变量。
b、编写SQL运行框架。
DML 语句的编写:
1、通过获取的javax.sql.DataSource 实例,获取Connection 对象。
2、通过ParamenterMeteData 获取数据库元数据。
DQL 语句的编写:
1、通过获取的DataSource 实例,获取Connection 对象。
2、通过ParamenterMeteData、ResultSetMetaData 等获取数据库元数据。
3、用抽象策略设计模式:设计一个ResultSetHandler 接口,作用:将查找出的数据封装到指定的JavaBean中。
|————这里的JavaBean,由用户来指定。
抽象策略模式,用户可以更具具体的功能来扩展成具体策略设计模式。如:查找的一条信息、查找的所有信息。
1 import java.sql.Connection;
2 import java.sql.ParameterMetaData;
3 import java.sql.PreparedStatement;
4 import java.sql.ResultSet;
5 import java.sql.SQLException;
6 import java.sql.Statement;
7
8 import javax.sql.DataSource;
9
10 /**
11 * 实现JDBC 框架的核心类。
12 * 在该类中定义了SQL语句完成的方法;
13 * @author 贺佐安
14 *
15 */
16 public class MyJdbcFrame {
17 /**
18 * javax.sql.DataSource 实例的引用变量
19 */
20 private DataSource ds = null ;
21 /**
22 * 将用户指定的DataSource 指定给系统定义的DataSource 实例的引用变量
23 * @param ds
24 */
25 public MyJdbcFrame(DataSource ds ) {
26 this.ds = ds ;
27 }
28 /**
29 * 执行UPDATE、DELETE、INSERT 语句。
30 * @param sql
31 * @param obj
32 */
33 public void update(String sql , Object[] obj) {
34 Connection conn = null ;
35 PreparedStatement stmt = null ;
36 try {
37 //获取Connection 对象
38 conn = ds.getConnection() ;
39 stmt = conn.prepareStatement(sql) ;
40
41 // 获取ParameterMetaData 元数据对象。
42 ParameterMetaData pmd = stmt.getParameterMetaData() ;
43
44 //获取SQL语句中需要设置的参数的个数
45 int parameterCount = pmd.getParameterCount() ;
46 if (parameterCount 》 0) {
47 if (obj == null || obj.length != parameterCount) {
48 throw new MyJdbcFrameException( “parameterCount is error!”) ;
49 }
50 //设置参数:
51 for ( int i = 0 ; i 《 obj.length ; i++) {
52 stmt.setObject(i+1, obj[i]) ;
53 }
54 }
55 //执行语句:
56 stmt.executeUpdate() ;
57
58 } catch(Exception e ) {
59 throw new MyJdbcFrameException(e.getMessage()) ;
60 } finally {
61 release(stmt, null, conn) ;
62 }
63 }
64
65 public Object query(String sql , Object[] obj , ResultSetHandler rsh) {
66 Connection conn = null ;
67 PreparedStatement stmt = null ;
68 ResultSet rs = null ;
69 try {
70 //获取Connection 对象
71 conn = ds.getConnection() ;
72 stmt = conn.prepareStatement(sql) ;
73
74 // 获取ParameterMetaData 元数据对象。
75 ParameterMetaData pmd = stmt.getParameterMetaData() ;
76
77 //获取SQL语句中需要设置的参数的个数
78 int parameterCount = pmd.getParameterCount() ;
79
80 if (obj.length != parameterCount) {
81 throw new MyJdbcFrameException( “‘” +sql +“’ : parameterCount is error!”) ;
82 }
83 //设置参数:
84 for ( int i = 0 ; i 《 obj.length ; i++) {
85 stmt.setObject(i+1, obj[i]) ;
86 }
87 //执行语句:
88 rs = stmt.executeQuery();
89
90 return rsh.handler(rs);
91 } catch(Exception e ) {
92 throw new MyJdbcFrameException(e.getMessage()) ;
93 } finally {
94 release(stmt, null, conn) ;
95 }
96 }
97 /**
98 * 释放资源
99 * @param stmt
100 * @param rs
101 * @param conn
102 */
103 public static void release(Statement stmt
104 , ResultSet rs
105 , Connection conn) {
106 if(rs != null) {
107 try {
108 rs.close() ;
109 } catch (SQLException e) {
110 e.printStackTrace();
111 }
112 rs = null ;
113 }
114 if (stmt != null) {
115 try {
116 stmt.close();
117 } catch (SQLException e) {
118 e.printStackTrace();
119 }
120 stmt = null ;
121 }
122 if (conn != null) {
123 try {
124 conn.close();
125 } catch (SQLException e) {
126 e.printStackTrace();
127 }
128 conn = null ;
129 }
130 }
131
132 }
2、接口:策略模式的接口:ResultSetHandler 。
1 import java.sql.ResultSet;
2
3 //抽象策略模式
4 public interface ResultSetHandler {
5 public Object handler(ResultSet rs) ;
6 }
这里对ResultSetHandler 接口实现一个BeanHandler 实例 :
1 import java.lang.reflect.Field;
2 import java.sql.ResultSet;
3 import java.sql.ResultSetMetaData;
4
5 /**
6 * 该类获取ResultSet 结果集中的第一个值,封装到JavaBean中
7 * @author 贺佐安
8 *
9 */
10 public class BeanHandler implements ResultSetHandler {
11 //获取要封装的JavaBean的字节码
12 private Class clazz ;
13 public BeanHandler (Class clazz) {
14 this.clazz = clazz ;
15 }
16
17 public Object handler(ResultSet rs) {
18 try {
19 if (rs.next()) {
20 //1、获取结果集的元数据。
21 ResultSetMetaData rsm = rs.getMetaData() ;
22 //2、创建JavaBean的实例:
23 Object obj = clazz.newInstance() ;
24 //3、将数据封装到JavaBean中。
25 for (int i = 0 ; i 《 rsm.getColumnCount() ; i ++) {
26 //获取属性名
27 String columnName = rsm.getColumnName(i+1) ;
28 //获取属性值
29 Object value = rs.getObject(i+1) ;
30
31 Field objField = obj.getClass().getDeclaredField(columnName) ;
32 objField.setAccessible(true) ;
33 objField.set(obj, value) ;
34 }
35 return obj ;
36 } else {
37 return null ;
38 }
39 } catch (Exception e) {
40 throw new RuntimeException(e) ;
41 }
42 }
43 }
3、自定义异常类:继承RuntimeException。如:
1 public class MyJdbcFrameException extends RuntimeException {
2 public MyJdbcFrameException() {
3 super() ;
4 }
5 public MyJdbcFrameException(String e) {
6 super(e) ;
7 }
8 }
然后就可以将其打包发布,在以后写数据库操作时就可以用自己的JDBC框架了,如果要完成查询多条语句什么的,则要实现ResultSetHandler 接口。来完成更多的功能。
全部0条评论
快来发表一下你的评论吧 !