Live2d Test Env

JDBC笔记一

连接池原理

数据库连接池:1.提前创建好多个连接对象,放到缓存中(集合),客户端用时直接从缓存中获取连接 ,用完连接后一定要还回来。

目的:提高数据库访问效率。

 模拟代码

 1 package com.itheima.pool;
 2 
 3 import java.sql.Connection;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 
 7 import com.itheima.util.JdbcUtil;
 8 
 9 //模拟连接池的实现原理:帮助理解
10 public class SimpleConnectionPool {
11     private static List<Connection> pool = new ArrayList<Connection>();
12     static{
13         for(int i=0;i<10;i++){
14             //com.mysql.jdbc.Connection数据库的那个Connection实现类型
15             Connection conn = JdbcUtil.getConnection();
16             pool.add(conn);
17         }
18     }
19     //从池中获取的连接
20     public synchronized static Connection getConnection(){
21         if(pool.size()>0){
22             Connection conn = pool.remove(0);
23             return conn;
24         }else{
25             throw new RuntimeException("服务器真忙");
26         }
27     }
28     //归还连接
29     public static void release(Connection conn){
30         pool.add(conn);
31     }
32     public static List<Connection> getPool(){
33         return pool;
34     }
35 } 
View Code

 List的Remove方法在删除元素的时候总会保持下标连续。例如,删掉第一个元素的时候,后面的元素会依次往前覆盖。

 1 package com.itheima.util;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.sql.Connection;
 6 import java.sql.DriverManager;
 7 import java.sql.ResultSet;
 8 import java.sql.SQLException;
 9 import java.sql.Statement;
10 import java.util.Properties;
11 
12 public class JdbcUtil {
13     
14     private static String driverClass;
15     private static String url;
16     private static String user;
17     private static String password;
18     
19     
20     static{
21         try {
22             ClassLoader cl = JdbcUtil.class.getClassLoader();
23             InputStream in = cl.getResourceAsStream("dbcfg.properties");
24             Properties props = new Properties();
25             props.load(in);
26             driverClass = props.getProperty("driverClass");
27             url = props.getProperty("url");
28             user = props.getProperty("user");
29             password = props.getProperty("password");
30             in.close();
31         } catch (IOException e) {
32             throw new ExceptionInInitializerError("获取数据库配置文件信息失败");
33         }
34         try {
35             Class.forName(driverClass);
36         } catch (ClassNotFoundException e) {
37             throw new ExceptionInInitializerError("加载驱动失败");
38         }
39     }
40     
41     public static Connection getConnection(){
42         try {
43             Connection conn = DriverManager.getConnection(url,user,password);
44             return conn;
45         } catch (Exception e) {
46             throw new RuntimeException("链接数据库的url或用户名密码错误,请检查您的配置文件");
47         }
48     }
49     public static void release(ResultSet rs,Statement stmt,Connection conn){
50         if(rs!=null){
51             try {
52                 rs.close();
53             } catch (SQLException e) {
54                 e.printStackTrace();
55             }
56             rs = null;
57         }
58         if(stmt!=null){
59             try {
60                 stmt.close();
61             } catch (SQLException e) {
62                 e.printStackTrace();
63             }
64             stmt = null;
65         }
66         if(conn!=null){
67             try {
68                 conn.close();
69             } catch (SQLException e) {
70                 e.printStackTrace();
71             }
72             conn = null;
73         }
74     }
75 }
View Code
 1 import java.sql.Connection;
 2 
 3 public class Client {
 4 
 5     public static void main(String[] args) {
 6         
 7         System.out.println("开始时池中的连接有:");
 8         for(Connection conn:SimpleConnectionPool.getPool()){
 9             System.out.println(conn);
10         }
11         System.out.println("---------------");
12         Connection conn1 = SimpleConnectionPool.getConnection();
13         System.out.println("取走的连接是:"+conn1);
14         System.out.println("---------------");
15         System.out.println("池中的连接有:");
16         for(Connection conn:SimpleConnectionPool.getPool()){
17             System.out.println(conn);
18         }
19         System.out.println("---------------");
20         Connection conn2 = SimpleConnectionPool.getConnection();
21         System.out.println("取走的连接是:"+conn2);
22         System.out.println("---------------");
23         System.out.println("池中的连接有:");
24         for(Connection conn:SimpleConnectionPool.getPool()){
25             System.out.println(conn);
26         }
27         
28         System.out.println("开始归还---------------");
29         SimpleConnectionPool.release(conn1);
30         System.out.println("池中的连接有:");
31         for(Connection conn:SimpleConnectionPool.getPool()){
32             System.out.println(conn);
33         }
34         System.out.println("开始归还---------------");
35         SimpleConnectionPool.release(conn2);
36         System.out.println("池中的连接有:");
37         for(Connection conn:SimpleConnectionPool.getPool()){
38             System.out.println(conn);
39         }
40     }
41 
42 }
View Code

dbfg.properties:

1 #driver config for mysql
2 driverClass=com.mysql.jdbc.Driver
3 url=jdbc:mysql://localhost:3306/day16
4 user=root
5 password=sorry
View Code

编写标准的数据源

1.Sun定义了一个标准:javax.sql.DataSource接口(数据源)

 1 //一班标准的数据源:一般都带有连接池
 2 public class MyDataSource1 implements DataSource {
 3     private static List<Connection> pool = Collections.synchronizedList(new ArrayList<Connection>());
 4     static{
 5         for(int i=0;i<10;i++){
 6             //com.mysql.jdbc.Connection数据库的那个Connection实现类型
 7             Connection conn = JdbcUtil.getConnection();
 8             pool.add(conn);
 9         }
10     }    
11     
12     public Connection getConnection() throws SQLException {
13         if(pool.size()>0){
14             Connection conn = pool.remove(0);//com.mysql.jdbc.Connection
15             MyConnection1 myconn = new MyConnection1(conn, pool);
16             return myconn;
17         }else{
18             throw new RuntimeException("服务器真忙");
19         }
20     }

专题编程难点

背景:义在池中获取连接后不需要使用了不能用close()方法进行处理,导致pool中连接对象就close了,数量就会减小

1.更改已知的某个或者某些方法(不能修改原有的代码,应该拓展)解决方案如下:

  1.继承:此处不行

  2.利用包装设计模式(装饰设计模式)

  3.利用动态代理

2.装饰设计模式:I/O  

  口诀:a.编写一个类实现与被包装类(com.mysql.jdbc.Connection)相同的接口

     b.定义一个变量,引用被包装类的实例

     c.定义构造方法,传入被包装类实例的引用

     d.对于要改变的方法,编写自己的代码即可

        e.对于不需要改变的方法,调用原有的对应方法

配上图解(防蒙):

Jdbcutil:

 1 import java.io.IOException;
 2 import java.io.InputStream;
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.ResultSet;
 6 import java.sql.SQLException;
 7 import java.sql.Statement;
 8 import java.util.Properties;
 9 
10 public class JdbcUtil {
11     
12     private static String driverClass;
13     private static String url;
14     private static String user;
15     private static String password;
16     
17     
18     static{
19         try {
20             ClassLoader cl = JdbcUtil.class.getClassLoader();
21             InputStream in = cl.getResourceAsStream("dbcfg.properties");
22             Properties props = new Properties();
23             props.load(in);
24             driverClass = props.getProperty("driverClass");
25             url = props.getProperty("url");
26             user = props.getProperty("user");
27             password = props.getProperty("password");
28             in.close();
29         } catch (IOException e) {
30             throw new ExceptionInInitializerError("获取数据库配置文件信息失败");
31         }
32         try {
33             Class.forName(driverClass);
34         } catch (ClassNotFoundException e) {
35             throw new ExceptionInInitializerError("加载驱动失败");
36         }
37     }
38     
39     public static Connection getConnection(){
40         try {
41             Connection conn = DriverManager.getConnection(url,user,password);
42             return conn;
43         } catch (Exception e) {
44             throw new RuntimeException("链接数据库的url或用户名密码错误,请检查您的配置文件");
45         }
46     }
47     public static void release(ResultSet rs,Statement stmt,Connection conn){
48         if(rs!=null){
49             try {
50                 rs.close();
51             } catch (SQLException e) {
52                 e.printStackTrace();
53             }
54             rs = null;
55         }
56         if(stmt!=null){
57             try {
58                 stmt.close();
59             } catch (SQLException e) {
60                 e.printStackTrace();
61             }
62             stmt = null;
63         }
64         if(conn!=null){
65             try {
66                 conn.close();
67             } catch (SQLException e) {
68                 e.printStackTrace();
69             }
70             conn = null;
71         }
72     }
73 }
View Code

 MyConnection:

  1 import java.sql.Array;
  2 import java.sql.Blob;
  3 import java.sql.CallableStatement;
  4 import java.sql.Clob;
  5 import java.sql.Connection;
  6 import java.sql.DatabaseMetaData;
  7 import java.sql.NClob;
  8 import java.sql.PreparedStatement;
  9 import java.sql.SQLClientInfoException;
 10 import java.sql.SQLException;
 11 import java.sql.SQLWarning;
 12 import java.sql.SQLXML;
 13 import java.sql.Savepoint;
 14 import java.sql.Statement;
 15 import java.sql.Struct;
 16 import java.util.List;
 17 import java.util.Map;
 18 import java.util.Properties;
 19 
 20 //a、编写一个类实现与被包装类(com.mysql.jdbc.Connection)相同的接口
 21 //b、定义一个变量,引用被包装类的实例
 22 //c、定义构造方法,传入被包装类实例的引用
 23 //d、对于要改变的方法,编写自己的代码即可
 24 //e、对于不需要改变的方法,调用原有对象的对应方法
 25 public class MyConnection1 implements Connection{//a、编写一个类实现与被包装类(com.mysql.jdbc.Connection)相同的接口
 26     
 27     private List<Connection> pool;
 28     
 29     private Connection oldConnection;//b、定义一个变量,引用被包装类的实例
 30     public MyConnection1(Connection oldConnection,List<Connection> pool){//c、定义构造方法,传入被包装类实例的引用
 31         this.oldConnection = oldConnection;
 32         this.pool = pool;//注入
 33     }
 34     
 35     //d、对于要改变的方法,编写自己的代码即可
 36     public void close() throws SQLException {
 37         pool.add(oldConnection);
 38     }
 39     //e、对于不需要改变的方法,调用原有对象的对应方法
 40     public <T> T unwrap(Class<T> iface) throws SQLException {
 41         return oldConnection.unwrap(iface);
 42     }
 43     @Override
 44     public boolean isWrapperFor(Class<?> iface) throws SQLException {
 45         return oldConnection.isWrapperFor(iface);
 46     }
 47     @Override
 48     public Statement createStatement() throws SQLException {
 49         return oldConnection.createStatement();
 50     }
 51     //后面省略不写
 52     @Override
 53     public PreparedStatement prepareStatement(String sql) throws SQLException {
 54         // TODO Auto-generated method stub
 55         return null;
 56     }
 57     @Override
 58     public CallableStatement prepareCall(String sql) throws SQLException {
 59         // TODO Auto-generated method stub
 60         return null;
 61     }
 62     @Override
 63     public String nativeSQL(String sql) throws SQLException {
 64         // TODO Auto-generated method stub
 65         return null;
 66     }
 67     @Override
 68     public void setAutoCommit(boolean autoCommit) throws SQLException {
 69         // TODO Auto-generated method stub
 70         
 71     }
 72     @Override
 73     public boolean getAutoCommit() throws SQLException {
 74         // TODO Auto-generated method stub
 75         return false;
 76     }
 77     @Override
 78     public void commit() throws SQLException {
 79         // TODO Auto-generated method stub
 80         
 81     }
 82     @Override
 83     public void rollback() throws SQLException {
 84         // TODO Auto-generated method stub
 85         
 86     }
 87     
 88     @Override
 89     public boolean isClosed() throws SQLException {
 90         // TODO Auto-generated method stub
 91         return false;
 92     }
 93     @Override
 94     public DatabaseMetaData getMetaData() throws SQLException {
 95         // TODO Auto-generated method stub
 96         return null;
 97     }
 98     @Override
 99     public void setReadOnly(boolean readOnly) throws SQLException {
100         // TODO Auto-generated method stub
101         
102     }
103     @Override
104     public boolean isReadOnly() throws SQLException {
105         // TODO Auto-generated method stub
106         return false;
107     }
108     @Override
109     public void setCatalog(String catalog) throws SQLException {
110         // TODO Auto-generated method stub
111         
112     }
113     @Override
114     public String getCatalog() throws SQLException {
115         // TODO Auto-generated method stub
116         return null;
117     }
118     @Override
119     public void setTransactionIsolation(int level) throws SQLException {
120         // TODO Auto-generated method stub
121         
122     }
123     @Override
124     public int getTransactionIsolation() throws SQLException {
125         // TODO Auto-generated method stub
126         return 0;
127     }
128     @Override
129     public SQLWarning getWarnings() throws SQLException {
130         // TODO Auto-generated method stub
131         return null;
132     }
133     @Override
134     public void clearWarnings() throws SQLException {
135         // TODO Auto-generated method stub
136         
137     }
138     @Override
139     public Statement createStatement(int resultSetType, int resultSetConcurrency)
140             throws SQLException {
141         // TODO Auto-generated method stub
142         return null;
143     }
144     @Override
145     public PreparedStatement prepareStatement(String sql, int resultSetType,
146             int resultSetConcurrency) throws SQLException {
147         // TODO Auto-generated method stub
148         return null;
149     }
150     @Override
151     public CallableStatement prepareCall(String sql, int resultSetType,
152             int resultSetConcurrency) throws SQLException {
153         // TODO Auto-generated method stub
154         return null;
155     }
156     @Override
157     public Map<String, Class<?>> getTypeMap() throws SQLException {
158         // TODO Auto-generated method stub
159         return null;
160     }
161     @Override
162     public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
163         // TODO Auto-generated method stub
164         
165     }
166     @Override
167     public void setHoldability(int holdability) throws SQLException {
168         // TODO Auto-generated method stub
169         
170     }
171     @Override
172     public int getHoldability() throws SQLException {
173         // TODO Auto-generated method stub
174         return 0;
175     }
176     @Override
177     public Savepoint setSavepoint() throws SQLException {
178         // TODO Auto-generated method stub
179         return null;
180     }
181     @Override
182     public Savepoint setSavepoint(String name) throws SQLException {
183         // TODO Auto-generated method stub
184         return null;
185     }
186     @Override
187     public void rollback(Savepoint savepoint) throws SQLException {
188         // TODO Auto-generated method stub
189         
190     }
191     @Override
192     public void releaseSavepoint(Savepoint savepoint) throws SQLException {
193         // TODO Auto-generated method stub
194         
195     }
196     @Override
197     public Statement createStatement(int resultSetType,
198             int resultSetConcurrency, int resultSetHoldability)
199             throws SQLException {
200         // TODO Auto-generated method stub
201         return null;
202     }
203     @Override
204     public PreparedStatement prepareStatement(String sql, int resultSetType,
205             int resultSetConcurrency, int resultSetHoldability)
206             throws SQLException {
207         // TODO Auto-generated method stub
208         return null;
209     }
210     @Override
211     public CallableStatement prepareCall(String sql, int resultSetType,
212             int resultSetConcurrency, int resultSetHoldability)
213             throws SQLException {
214         // TODO Auto-generated method stub
215         return null;
216     }
217     @Override
218     public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
219             throws SQLException {
220         // TODO Auto-generated method stub
221         return null;
222     }
223     @Override
224     public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
225             throws SQLException {
226         // TODO Auto-generated method stub
227         return null;
228     }
229     @Override
230     public PreparedStatement prepareStatement(String sql, String[] columnNames)
231             throws SQLException {
232         // TODO Auto-generated method stub
233         return null;
234     }
235     @Override
236     public Clob createClob() throws SQLException {
237         // TODO Auto-generated method stub
238         return null;
239     }
240     @Override
241     public Blob createBlob() throws SQLException {
242         // TODO Auto-generated method stub
243         return null;
244     }
245     @Override
246     public NClob createNClob() throws SQLException {
247         // TODO Auto-generated method stub
248         return null;
249     }
250     @Override
251     public SQLXML createSQLXML() throws SQLException {
252         // TODO Auto-generated method stub
253         return null;
254     }
255     @Override
256     public boolean isValid(int timeout) throws SQLException {
257         // TODO Auto-generated method stub
258         return false;
259     }
260     @Override
261     public void setClientInfo(String name, String value)
262             throws SQLClientInfoException {
263         // TODO Auto-generated method stub
264         
265     }
266     @Override
267     public void setClientInfo(Properties properties)
268             throws SQLClientInfoException {
269         // TODO Auto-generated method stub
270         
271     }
272     @Override
273     public String getClientInfo(String name) throws SQLException {
274         // TODO Auto-generated method stub
275         return null;
276     }
277     @Override
278     public Properties getClientInfo() throws SQLException {
279         // TODO Auto-generated method stub
280         return null;
281     }
282     @Override
283     public Array createArrayOf(String typeName, Object[] elements)
284             throws SQLException {
285         // TODO Auto-generated method stub
286         return null;
287     }
288     @Override
289     public Struct createStruct(String typeName, Object[] attributes)
290             throws SQLException {
291         // TODO Auto-generated method stub
292         return null;
293     }
294 }
View Code

 client:

 1 package com.itheima.ds;
 2 
 3 import java.sql.Connection;
 4 import java.sql.PreparedStatement;
 5 import java.sql.SQLException;
 6 import java.sql.Statement;
 7 
 8 public class Client {
 9 
10     public static void main(String[] args) {
11         MyDataSource2 ds = new MyDataSource2();
12         Connection conn = null;
13         Statement stmt = null;
14         try{
15             conn = ds.getConnection();//MyConnection1从池中获取一个连接
16             stmt = conn.createStatement();//调用的是MyConnection1中的createStatement(),调用驱动最原始的对应方法
17             //.....
18         }catch(Exception e){
19             e.printStackTrace();
20         }finally{
21             if(stmt!=null){
22                 try {
23                     stmt.close();
24                 } catch (SQLException e) {
25                     e.printStackTrace();
26                 }
27             }
28             if(conn!=null){
29                 try {
30                     conn.close();//关闭连接(com.mysql.jdbc.Connection)
31                                 //不要关闭,还回池中(更改已知类的某个方法的默认行为)
32                 } catch (SQLException e) {
33                     e.printStackTrace();
34                 }
35             }
36         }
37     }
38 
39 }
View Code

MyDataSource:

 1 package com.itheima.ds;
 2 
 3 import java.io.PrintWriter;
 4 import java.sql.Connection;
 5 import java.sql.SQLException;
 6 import java.util.ArrayList;
 7 import java.util.Collections;
 8 import java.util.List;
 9 
10 import javax.sql.DataSource;
11 
12 import com.itheima.util.JdbcUtil;
13 //一把标准的数据源:一般都带有连接池
14 public class MyDataSource1 implements DataSource {
15     private static List<Connection> pool = Collections.synchronizedList(new ArrayList<Connection>());
16     static{
17         for(int i=0;i<10;i++){
18             //com.mysql.jdbc.Connection数据库的那个Connection实现类型
19             Connection conn = JdbcUtil.getConnection();
20             pool.add(conn);
21         }
22     }    
23     
24     public Connection getConnection() throws SQLException {
25         if(pool.size()>0){
26             Connection conn = pool.remove(0);//com.mysql.jdbc.Connection
27             MyConnection1 myconn = new MyConnection1(conn, pool);
28             return myconn;
29         }else{
30             throw new RuntimeException("服务器真忙");
31         }
32     }
33 
34     
35     @Override
36     public PrintWriter getLogWriter() throws SQLException {
37         // TODO Auto-generated method stub
38         return null;
39     }
40 
41     @Override
42     public void setLogWriter(PrintWriter out) throws SQLException {
43         // TODO Auto-generated method stub
44 
45     }
46 
47     @Override
48     public void setLoginTimeout(int seconds) throws SQLException {
49         // TODO Auto-generated method stub
50 
51     }
52 
53     @Override
54     public int getLoginTimeout() throws SQLException {
55         // TODO Auto-generated method stub
56         return 0;
57     }
58 
59     @Override
60     public <T> T unwrap(Class<T> iface) throws SQLException {
61         // TODO Auto-generated method stub
62         return null;
63     }
64 
65     @Override
66     public boolean isWrapperFor(Class<?> iface) throws SQLException {
67         // TODO Auto-generated method stub
68         return false;
69     }
70 
71     
72     @Override
73     public Connection getConnection(String username, String password)
74             throws SQLException {
75         // TODO Auto-generated method stub
76         return null;
77     }
78 
79 }
View Code

默认适配器

背景:义在池中获取

1.适配器类:

//适配器,还是一个包装类
//a、编写一个类实现与被包装类(com.mysql.jdbc.Connection)相同的接口
//b、定义一个变量,引用被包装类的实例
//c、定义构造方法,传入被包装类实例的引用
//d、对于不需要改变的方法,调用原有对象的对应方法

  1 import java.sql.Array;
  2 import java.sql.Blob;
  3 import java.sql.CallableStatement;
  4 import java.sql.Clob;
  5 import java.sql.Connection;
  6 import java.sql.DatabaseMetaData;
  7 import java.sql.NClob;
  8 import java.sql.PreparedStatement;
  9 import java.sql.SQLClientInfoException;
 10 import java.sql.SQLException;
 11 import java.sql.SQLWarning;
 12 import java.sql.SQLXML;
 13 import java.sql.Savepoint;
 14 import java.sql.Statement;
 15 import java.sql.Struct;
 16 import java.util.Map;
 17 import java.util.Properties;
 18 
 19 //适配器,还是一个包装类
 20 //a、编写一个类实现与被包装类(com.mysql.jdbc.Connection)相同的接口
 21 //b、定义一个变量,引用被包装类的实例
 22 //c、定义构造方法,传入被包装类实例的引用
 23 //d、对于不需要改变的方法,调用原有对象的对应方法
 24 public class ConnectionAdapter implements Connection{
 25     private Connection oldConnection;
 26     public ConnectionAdapter(Connection oldConnection){
 27         this.oldConnection = oldConnection;
 28     }
 29     public <T> T unwrap(Class<T> iface) throws SQLException {
 30         return oldConnection.unwrap(iface);
 31     }
 32     @Override
 33     public boolean isWrapperFor(Class<?> iface) throws SQLException {
 34         return oldConnection.isWrapperFor(iface);
 35     }
 36     //省略
 37     @Override
 38     public Statement createStatement() throws SQLException {
 39         // TODO Auto-generated method stub
 40         return null;
 41     }
 42     @Override
 43     public PreparedStatement prepareStatement(String sql) throws SQLException {
 44         // TODO Auto-generated method stub
 45         return null;
 46     }
 47     @Override
 48     public CallableStatement prepareCall(String sql) throws SQLException {
 49         // TODO Auto-generated method stub
 50         return null;
 51     }
 52     @Override
 53     public String nativeSQL(String sql) throws SQLException {
 54         // TODO Auto-generated method stub
 55         return null;
 56     }
 57     @Override
 58     public void setAutoCommit(boolean autoCommit) throws SQLException {
 59         // TODO Auto-generated method stub
 60         
 61     }
 62     @Override
 63     public boolean getAutoCommit() throws SQLException {
 64         // TODO Auto-generated method stub
 65         return false;
 66     }
 67     @Override
 68     public void commit() throws SQLException {
 69         // TODO Auto-generated method stub
 70         
 71     }
 72     @Override
 73     public void rollback() throws SQLException {
 74         // TODO Auto-generated method stub
 75         
 76     }
 77     @Override
 78     public void close() throws SQLException {
 79         // TODO Auto-generated method stub
 80         
 81     }
 82     @Override
 83     public boolean isClosed() throws SQLException {
 84         // TODO Auto-generated method stub
 85         return false;
 86     }
 87     @Override
 88     public DatabaseMetaData getMetaData() throws SQLException {
 89         // TODO Auto-generated method stub
 90         return null;
 91     }
 92     @Override
 93     public void setReadOnly(boolean readOnly) throws SQLException {
 94         // TODO Auto-generated method stub
 95         
 96     }
 97     @Override
 98     public boolean isReadOnly() throws SQLException {
 99         // TODO Auto-generated method stub
100         return false;
101     }
102     @Override
103     public void setCatalog(String catalog) throws SQLException {
104         // TODO Auto-generated method stub
105         
106     }
107     @Override
108     public String getCatalog() throws SQLException {
109         // TODO Auto-generated method stub
110         return null;
111     }
112     @Override
113     public void setTransactionIsolation(int level) throws SQLException {
114         // TODO Auto-generated method stub
115         
116     }
117     @Override
118     public int getTransactionIsolation() throws SQLException {
119         // TODO Auto-generated method stub
120         return 0;
121     }
122     @Override
123     public SQLWarning getWarnings() throws SQLException {
124         // TODO Auto-generated method stub
125         return null;
126     }
127     @Override
128     public void clearWarnings() throws SQLException {
129         // TODO Auto-generated method stub
130         
131     }
132     @Override
133     public Statement createStatement(int resultSetType, int resultSetConcurrency)
134             throws SQLException {
135         // TODO Auto-generated method stub
136         return null;
137     }
138     @Override
139     public PreparedStatement prepareStatement(String sql, int resultSetType,
140             int resultSetConcurrency) throws SQLException {
141         // TODO Auto-generated method stub
142         return null;
143     }
144     @Override
145     public CallableStatement prepareCall(String sql, int resultSetType,
146             int resultSetConcurrency) throws SQLException {
147         // TODO Auto-generated method stub
148         return null;
149     }
150     @Override
151     public Map<String, Class<?>> getTypeMap() throws SQLException {
152         // TODO Auto-generated method stub
153         return null;
154     }
155     @Override
156     public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
157         // TODO Auto-generated method stub
158         
159     }
160     @Override
161     public void setHoldability(int holdability) throws SQLException {
162         // TODO Auto-generated method stub
163         
164     }
165     @Override
166     public int getHoldability() throws SQLException {
167         // TODO Auto-generated method stub
168         return 0;
169     }
170     @Override
171     public Savepoint setSavepoint() throws SQLException {
172         // TODO Auto-generated method stub
173         return null;
174     }
175     @Override
176     public Savepoint setSavepoint(String name) throws SQLException {
177         // TODO Auto-generated method stub
178         return null;
179     }
180     @Override
181     public void rollback(Savepoint savepoint) throws SQLException {
182         // TODO Auto-generated method stub
183         
184     }
185     @Override
186     public void releaseSavepoint(Savepoint savepoint) throws SQLException {
187         // TODO Auto-generated method stub
188         
189     }
190     @Override
191     public Statement createStatement(int resultSetType,
192             int resultSetConcurrency, int resultSetHoldability)
193             throws SQLException {
194         // TODO Auto-generated method stub
195         return null;
196     }
197     @Override
198     public PreparedStatement prepareStatement(String sql, int resultSetType,
199             int resultSetConcurrency, int resultSetHoldability)
200             throws SQLException {
201         // TODO Auto-generated method stub
202         return null;
203     }
204     @Override
205     public CallableStatement prepareCall(String sql, int resultSetType,
206             int resultSetConcurrency, int resultSetHoldability)
207             throws SQLException {
208         // TODO Auto-generated method stub
209         return null;
210     }
211     @Override
212     public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
213             throws SQLException {
214         // TODO Auto-generated method stub
215         return null;
216     }
217     @Override
218     public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
219             throws SQLException {
220         // TODO Auto-generated method stub
221         return null;
222     }
223     @Override
224     public PreparedStatement prepareStatement(String sql, String[] columnNames)
225             throws SQLException {
226         // TODO Auto-generated method stub
227         return null;
228     }
229     @Override
230     public Clob createClob() throws SQLException {
231         // TODO Auto-generated method stub
232         return null;
233     }
234     @Override
235     public Blob createBlob() throws SQLException {
236         // TODO Auto-generated method stub
237         return null;
238     }
239     @Override
240     public NClob createNClob() throws SQLException {
241         // TODO Auto-generated method stub
242         return null;
243     }
244     @Override
245     public SQLXML createSQLXML() throws SQLException {
246         // TODO Auto-generated method stub
247         return null;
248     }
249     @Override
250     public boolean isValid(int timeout) throws SQLException {
251         // TODO Auto-generated method stub
252         return false;
253     }
254     @Override
255     public void setClientInfo(String name, String value)
256             throws SQLClientInfoException {
257         // TODO Auto-generated method stub
258         
259     }
260     @Override
261     public void setClientInfo(Properties properties)
262             throws SQLClientInfoException {
263         // TODO Auto-generated method stub
264         
265     }
266     @Override
267     public String getClientInfo(String name) throws SQLException {
268         // TODO Auto-generated method stub
269         return null;
270     }
271     @Override
272     public Properties getClientInfo() throws SQLException {
273         // TODO Auto-generated method stub
274         return null;
275     }
276     @Override
277     public Array createArrayOf(String typeName, Object[] elements)
278             throws SQLException {
279         // TODO Auto-generated method stub
280         return null;
281     }
282     @Override
283     public Struct createStruct(String typeName, Object[] attributes)
284             throws SQLException {
285         // TODO Auto-generated method stub
286         return null;
287     }
288 }
View Code

2.继承包装类:

//a、编写一个类继承已经实现了被包装类(com.mysql.jdbc.Connection)相同的接口的类
//b、定义一个变量,引用被包装类的实例
//c、定义构造方法,传入被包装类实例的引用
//d、对于要改变的方法,覆盖即可

 1 import java.sql.Connection;
 2 import java.sql.SQLException;
 3 import java.util.List;
 4 
 5 //a、编写一个类继承已经实现了被包装类(com.mysql.jdbc.Connection)相同的接口的类
 6 //b、定义一个变量,引用被包装类的实例
 7 //c、定义构造方法,传入被包装类实例的引用
 8 //d、对于要改变的方法,覆盖即可
 9 public class MyConnection2 extends ConnectionAdapter{
10     private Connection oldConnection;
11     private List<Connection> pool;
12     public MyConnection2(Connection oldConnection,List<Connection> pool){
13         super(oldConnection);
14         this.oldConnection = oldConnection;
15         this.pool = pool;
16     }
17     public void close() throws SQLException {
18         pool.add(oldConnection);
19     }
20     
21 }
View Code

 动态代理:

示例代码

1.接口:

1 package com.itheima.proxy1;
2 
3 public interface Human {
4     void sing(float money);
5     void dance(float money);
6     void eat();
7 }
View Code

2. 实现接口类:

 1 public class SpringBrother implements Human {
 2 
 3     public void sing(float money) {
 4         System.out.println("拿到钱:"+money+"开唱");
 5     }
 6 
 7     public void dance(float money) {
 8         System.out.println("拿到钱:"+money+"开跳");
 9     }
10 
11     public void eat() {
12         System.out.println("狼吞虎咽的吃");
13     }
14 
15 }
实现接口类

 3.代理类:

 1 package com.itheima.proxy1;
 2 //静态代理:代理类写好了
 3 public class ProxyMan implements Human{
 4     private Human oldHuman;
 5     public ProxyMan(Human oldHuman){
 6         this.oldHuman = oldHuman;
 7     }
 8     public void sing(float money) {
 9         if(money<10000)
10             throw new RuntimeException("不干");
11         oldHuman.sing(money/2);
12     }
13 
14     public void dance(float money) {
15         if(money<20000)
16             throw new RuntimeException("不干");
17         oldHuman.dance(money/2);
18     }
19     public void eat() {
20         oldHuman.eat();
21     }
22     
23 }
代理类(静态代理)

4.动态代理及测试:

 1 import java.lang.reflect.InvocationHandler;
 2 import java.lang.reflect.Method;
 3 import java.lang.reflect.Proxy;
 4 //如果被代理对象没有实现任何接口,Proxy代理不能用。基于接口的动态代理
 5 public class Boss {
 6 
 7     public static void main(String[] args) {
 8         final Human h = new SpringBrother();//被代理对象
 9 //        Human proxyMan = new ProxyMan(h);//静态代理
10         //动态代理
11         /*
12          * public static Object newProxyInstance(ClassLoader loader,
13                                       Class<?>[] interfaces,
14                                       InvocationHandler h)
15             返回值:代理对象的引用
16             参数:
17                 loader:代理对象用的类加载器。固定写法:和被代理对象一致
18                 interfaces:代理对象实现的接口。固定写法:代理对象实现什么接口它就实现什么接口(保持代理对象和被代理对象有相同的行为)
19                 h:如何代理,怎么代理,代理什么?策略设计模式(InvocationHandler是一个接口)
20          */
21         Human proxyMan = (Human)Proxy.newProxyInstance(h.getClass().getClassLoader(), 
22                 h.getClass().getInterfaces(), new InvocationHandler() {
23                     //如何代理啊:具体策略
24                     //调用代理对象的任何方法,都会经过该方法
25                     /*
26                      * 返回值:当前方法的返回值
27                      * proxy:代理对象的引用
28                      * method:当前调用的代理的哪个方法
29                      * args:当前方法需要的参数
30                      */
31                     public Object invoke(Object proxy, Method method, Object[] args)
32                             throws Throwable {
33                         if("sing".equals(method.getName())){
34                             float money = (Float)args[0];
35                             if(money>10000){
36                                 return method.invoke(h, money/2);
37                             }
38                         }else if("dance".equals(method.getName())){
39                             float money = (Float)args[0];
40                             if(money>20000){
41                                 return  method.invoke(h, money/2);
42                             }
43                         }else{
44                             return method.invoke(h, args);
45                         }
46                         return null;
47                     }
48                 });
49         proxyMan.sing(100000);
50         proxyMan.dance(200000);
51         proxyMan.eat();
52     }
53 
54 }
View Code

 2.基于动态代理更改驱动close()方法:

 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.SQLException;
 7 import java.util.ArrayList;
 8 import java.util.Collections;
 9 import java.util.List;
10 
11 import javax.sql.DataSource;
12 
13 import com.itheima.util.JdbcUtil;
14 //一把标准的数据源:一般都带有连接池。使用动态代理来做
15 public class MyDataSource2 implements DataSource {
16     private static List<Connection> pool = Collections.synchronizedList(new ArrayList<Connection>());
17     static{
18         for(int i=0;i<10;i++){
19             //com.mysql.jdbc.Connection数据库的那个Connection实现类型
20             Connection conn = JdbcUtil.getConnection();
21             pool.add(conn);
22         }
23     }    
24     
25     public Connection getConnection() throws SQLException {
26         if(pool.size()>0){
27             final Connection conn = pool.remove(0);//com.mysql.jdbc.Connection
28             return (Connection)Proxy.newProxyInstance(conn.getClass().getClassLoader(), 
29                     conn.getClass().getInterfaces(), 
30                     new InvocationHandler() {
31                         public Object invoke(Object proxy, Method method, Object[] args)
32                                 throws Throwable {
33                             if("close".equals(method.getName())){
34                                 return pool.add(conn);
35                             }else{
36                                 return method.invoke(conn, args);
37                             }
38                         }
39                     });
40         }else{
41             throw new RuntimeException("服务器真忙");
42         }
43     }
44 
45     
46     @Override
47     public PrintWriter getLogWriter() throws SQLException {
48         // TODO Auto-generated method stub
49         return null;
50     }
51 
52     @Override
53     public void setLogWriter(PrintWriter out) throws SQLException {
54         // TODO Auto-generated method stub
55 
56     }
57 
58     @Override
59     public void setLoginTimeout(int seconds) throws SQLException {
60         // TODO Auto-generated method stub
61 
62     }
63 
64     @Override
65     public int getLoginTimeout() throws SQLException {
66         // TODO Auto-generated method stub
67         return 0;
68     }
69 
70     @Override
71     public <T> T unwrap(Class<T> iface) throws SQLException {
72         // TODO Auto-generated method stub
73         return null;
74     }
75 
76     @Override
77     public boolean isWrapperFor(Class<?> iface) throws SQLException {
78         // TODO Auto-generated method stub
79         return false;
80     }
81 
82     
83     @Override
84     public Connection getConnection(String username, String password)
85             throws SQLException {
86         // TODO Auto-generated method stub
87         return null;
88     }
89 
90 }
示例代码

  3.CGLIB生成代理 对象:

 (代理类是被代理的子类)

被代理类要求:

a.必须是public

b.必须不是final

1.导入架包:cglib-nodep-2.1_3.jar

2:被代理类:

 1 //没有实现任何接口。domain包中的普通的JavaBean,有时并没有实现任何接口,需要他的代理类怎么办?
 2 //借助第三方的开发:CGLIB
 3 public class SpringBrother{
 4 
 5     public void sing(float money) {
 6         System.out.println("拿到钱:"+money+"开唱");
 7     }
 8 
 9     public void dance(float money) {
10         System.out.println("拿到钱:"+money+"开跳");
11     }
12 
13     public void eat() {
14         System.out.println("狼吞虎咽的吃");
15     }
16 
17 }
View Code

3.代理:

 1 import java.lang.reflect.Method;
 2 
 3 import net.sf.cglib.proxy.Enhancer;
 4 import net.sf.cglib.proxy.InvocationHandler;
 5 //如果被代理对象没有实现任何接口,Proxy代理不能用。基于接口的动态代理
 6 //CGLIB:基于子类的动态代理
 7 public class Boss {
 8 
 9     public static void main(String[] args) {
10         final SpringBrother h = new SpringBrother();//被代理对象
11         /*
12          * Enhancer.create(type, callback)
13          *     type:代理类的父类型
14          *  callback:如何代理
15          */
16         SpringBrother proxyMan = (SpringBrother)Enhancer.create(SpringBrother.class, new InvocationHandler(){
17 
18             public Object invoke(Object proxy, Method method, Object[] args)
19                     throws Throwable {
20                 if("sing".equals(method.getName())){
21                     float money = (Float)args[0];
22                     if(money>10000){
23                         return method.invoke(h, money/2);
24                     }
25                 }else if("dance".equals(method.getName())){
26                     float money = (Float)args[0];  
27                     if(money>20000){
28                         return  method.invoke(h, money/2);
29                     }
30                 }else{
31                     return method.invoke(h, args);
32                 }
33                 return null;
34             }
35             
36         });
37         proxyMan.sing(100000);
38         proxyMan.dance(200000);
39         proxyMan.eat();
40     }
41 
42 }
View Code 

  AOP面向切向思想: 

  1 之前写了一篇关于IOC的博客——《Spring容器IOC解析及简单实现》,今天再来聊聊AOP。大家都知道Spring的两大特性是IOC和AOP。
  2 IOC负责将对象动态的注入到容器,从而达到一种需要谁就注入谁,什么时候需要就什么时候注入的效果,可谓是招之则来,挥之则去。想想都觉得爽,如果现实生活中也有这本事那就爽歪歪了,至于有多爽,各位自己脑补吧;而AOP呢,它实现的就是容器的另一大好处了,就是可以让容器中的对象都享有容器中的公共服务。那么容器是怎么做到的呢?它怎么就能让在它里面的对象自动拥有它提供的公共性服务呢?答案就是我们今天要讨论的内容——动态代理。
  3 动态代理其实并不是什么新鲜的东西,学过设计模式的人都应该知道代理模式,代理模式是一种静态代理,而动态代理就是利用反射和动态编译将代理模式变成动态的。原理跟动态注入一样,代理模式在编译的时候就已经确定代理类将要代理谁,而动态代理在运行的时候才知道自己要代理谁。
  4 Spring的动态代理有两种:一是JDK的动态代理;另一个是cglib动态代理(通过修改字节码来实现代理)。今天咱们主要讨论JDK动态代理的方式。JDK的代理方式主要就是通过反射跟动态编译来实现的,下面咱们就通过代码来看看它具体是怎么实现的。
  5 假设我们要对下面这个用户管理进行代理:
  6 //用户管理接口  
  7 package com.tgb.proxy;  
  8 
  9 public interface UserMgr {  
 10     void addUser();  
 11     void delUser();  
 12 }  
 13 
 14 //用户管理的实现  
 15 package com.tgb.proxy;  
 16 
 17 public class UserMgrImpl implements UserMgr {  
 18 
 19     @Override  
 20     public void addUser() {  
 21         System.out.println("添加用户.....");  
 22     }  
 23 
 24     @Override  
 25     public void delUser() {  
 26         System.out.println("删除用户.....");  
 27     }  
 28 
 29 }  
 30 按照代理模式的实现方式,肯定是用一个代理类,让它也实现UserMgr接口,然后在其内部声明一个UserMgrImpl,然后分别调用addUser和delUser方法,并在调用前后加上我们需要的其他操作。但是这样很显然都是写死的,我们怎么做到动态呢?别急,接着看。 我们知道,要实现代理,那么我们的代理类跟被代理类都要实现同一接口,但是动态代理的话我们根本不知道我们将要代理谁,也就不知道我们要实现哪个接口,那么要怎么办呢?我们只有知道要代理谁以后,才能给出相应的代理类,那么我们何不等知道要代理谁以后再去生成一个代理类呢?想到这里,我们好像找到了解决的办法,就是动态生成代理类!
 31 这时候我们亲爱的反射又有了用武之地,我们可以写一个方法来接收被代理类,这样我们就可以通过反射知道它的一切信息——包括它的类型、它的方法等等(如果你不知道怎么得到,请先去看看我写的反射的博客《反射一》《反射二》)。
 32 JDK动态代理的两个核心分别是InvocationHandler和Proxy,下面我们就用简单的代码来模拟一下它们是怎么实现的:
 33 InvocationHandler接口:
 34 package com.tgb.proxy;  
 35 
 36 import java.lang.reflect.Method;  
 37 
 38 public interface InvocationHandler {  
 39     public void invoke(Object o, Method m);  
 40 }  
 41 实现动态代理的关键部分,通过Proxy动态生成我们具体的代理类:
 42 package com.tgb.proxy;  
 43 
 44 import java.io.File;  
 45 import java.io.FileWriter;  
 46 import java.lang.reflect.Constructor;  
 47 import java.lang.reflect.Method;  
 48 import java.net.URL;  
 49 import java.net.URLClassLoader;  
 50 import javax.tools.JavaCompiler;  
 51 import javax.tools.StandardJavaFileManager;  
 52 import javax.tools.ToolProvider;  
 53 import javax.tools.JavaCompiler.CompilationTask;  
 54 
 55 public class Proxy {  
 56     /** 
 57      *  
 58      * @param infce 被代理类的接口 
 59      * @param h 代理类 
 60      * @return 
 61      * @throws Exception 
 62      */  
 63     public static Object newProxyInstance(Class infce, InvocationHandler h) throws Exception {   
 64         String methodStr = "";  
 65         String rt = "\r\n";  
 66 
 67         //利用反射得到infce的所有方法,并重新组装  
 68         Method[] methods = infce.getMethods();    
 69         for(Method m : methods) {  
 70             methodStr += "    @Override" + rt +   
 71                          "    public  "+m.getReturnType()+" " + m.getName() + "() {" + rt +  
 72                          "        try {" + rt +  
 73                          "        Method md = " + infce.getName() + ".class.getMethod(\"" + m.getName() + "\");" + rt +  
 74                          "        h.invoke(this, md);" + rt +  
 75                          "        }catch(Exception e) {e.printStackTrace();}" + rt +                          
 76                          "    }" + rt ;  
 77         }  
 78 
 79         //生成Java源文件  
 80         String srcCode =   
 81             "package com.tgb.proxy;" +  rt +  
 82             "import java.lang.reflect.Method;" + rt +  
 83             "public class $Proxy1 implements " + infce.getName() + "{" + rt +  
 84             "    public $Proxy1(InvocationHandler h) {" + rt +  
 85             "        this.h = h;" + rt +  
 86             "    }" + rt +            
 87             "    com.tgb.proxy.InvocationHandler h;" + rt +                           
 88             methodStr + rt +  
 89             "}";  
 90         String fileName =   
 91             "d:/src/com/tgb/proxy/$Proxy1.java";  
 92         File f = new File(fileName);  
 93         FileWriter fw = new FileWriter(f);  
 94         fw.write(srcCode);  
 95         fw.flush();  
 96         fw.close();  
 97 
 98         //将Java文件编译成class文件  
 99         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();  
100         StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);  
101         Iterable units = fileMgr.getJavaFileObjects(fileName);  
102         CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);  
103         t.call();  
104         fileMgr.close();  
105 
106         //加载到内存,并实例化  
107         URL[] urls = new URL[] {new URL("file:/" + "d:/src/")};  
108         URLClassLoader ul = new URLClassLoader(urls);  
109         Class c = ul.loadClass("com.tgb.proxy.$Proxy1");  
110 
111         Constructor ctr = c.getConstructor(InvocationHandler.class);  
112         Object m = ctr.newInstance(h);  
113 
114         return m;  
115     }  
116 
117 }  
118 这个类的主要功能就是,根据被代理对象的信息,动态组装一个代理类,生成$Proxy1.java文件,然后将其编译成$Proxy1.class。这样我们就可以在运行的时候,根据我们具体的被代理对象生成我们想要的代理类了。这样一来,我们就不需要提前知道我们要代理谁。也就是说,你想代理谁,想要什么样的代理,我们就给你生成一个什么样的代理类。
119 然后,在客户端我们就可以随意的进行代理了。
120 package com.tgb.proxy;  
121 
122 public class Client {  
123     public static void main(String[] args) throws Exception {  
124         UserMgr mgr = new UserMgrImpl();  
125 
126         //为用户管理添加事务处理  
127         InvocationHandler h = new TransactionHandler(mgr);  
128         UserMgr u = (UserMgr)Proxy.newProxyInstance(UserMgr.class,h);  
129 
130         //为用户管理添加显示方法执行时间的功能  
131         TimeHandler h2 = new TimeHandler(u);  
132         u = (UserMgr)Proxy.newProxyInstance(UserMgr.class,h2);  
133 
134         u.addUser();  
135         System.out.println("\r\n==========华丽的分割线==========\r\n");  
136         u.delUser();  
137     }  
138 }  
139 运行结果:
140 开始时间:2014年-07月-15日 15时:48分:54秒  
141 开启事务.....  
142 添加用户.....  
143 提交事务.....  
144 结束时间:2014年-07月-15日 15时:48分:57秒  
145 耗时:3秒  
146 
147 ==========华丽的分割线==========  
148 
149 开始时间:2014年-07月-15日 15时:48分:57秒  
150 开启事务.....  
151 删除用户.....  
152 提交事务.....  
153 结束时间:2014年-07月-15日 15时:49分:00秒  
154 耗时:3秒  
155 这里我写了两个代理的功能,一个是事务处理,一个是显示方法执行时间的代理,当然都是非常简单的写法,只是为了说明这个原理。当然,我们可以想Spring那样将这些AOP写到配置文件,因为之前那篇已经写了怎么通过配置文件注入了,这里就不重复贴了。 到这里,你可能会有一个疑问:你上面说,只要放到容器里的对象,都会有容器的公共服务,我怎么没看出来呢?好,那我们就继续看一下我们的代理功能:
156 事务处理:
157 package com.tgb.proxy;  
158 
159 import java.lang.reflect.Method;  
160 
161 public class TransactionHandler implements InvocationHandler {  
162 
163     private Object target;  
164 
165     public TransactionHandler(Object target) {  
166         super();  
167         this.target = target;  
168     }  
169 
170     @Override  
171     public void invoke(Object o, Method m) {  
172         System.out.println("开启事务.....");  
173         try {  
174             m.invoke(target);  
175         } catch (Exception e) {  
176             e.printStackTrace();  
177         }  
178         System.out.println("提交事务.....");  
179     }  
180 
181 }  
182 从代码中不难看出,我们代理的功能里没有涉及到任何被代理对象的具体信息,这样有什么好处呢?这样的好处就是将代理要做的事情跟被代理的对象完全分开,这样一来我们就可以在代理和被代理之间随意的进行组合了。也就是说同一个功能我们只需要一个。同样的功能只有一个,那么这个功能不就是公共的功能吗?不管容器中有多少给对象,都可以享受容器提供的服务了。这就是容器的好处。
183 不知道我讲的够不够清楚,欢迎大家积极交流、讨论。
转载

  开源数据源的使用(实际开发中用):

DBCP

a、简介:DBCP DataBase Connection Pool

b、Apache组织搞的开源的数据源(DataSource)实现

c、使用:

    1、拷贝jar包:数据库的驱动jar;commons-dbcp-1.4.jar;commons-pool-1.5.6.jar

    2、在构建路径的顶层,建立一个配置文件,内容如下:dbcpconfig.properties:

    3、编写工具类:

 1 #连接设置
 2 driverClassName=com.mysql.jdbc.Driver
 3 url=jdbc:mysql://localhost:3306/day17
 4 username=root
 5 password=sorry
 6 
 7 #<!-- 初始化连接 -->
 8 initialSize=10
 9 
10 #最大连接数量
11 maxActive=50
12 
13 #<!-- 最大空闲连接 -->
14 maxIdle=20
15 
16 #<!-- 最小空闲连接 -->
17 minIdle=5
18 
19 #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
20 maxWait=60000
21 
22 
23 #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] 
24 #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
25 connectionProperties=useUnicode=true;characterEncoding=utf8
26 
27 #指定由连接池所创建的连接的自动提交(auto-commit)状态。
28 defaultAutoCommit=true
29 
30 #driver default 指定由连接池所创建的连接的只读(read-only)状态。
31 #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
32 defaultReadOnly=
33 
34 #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
35 #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
36 defaultTransactionIsolation=REPEATABLE_READ
dbcpconfig.properties

 

 1 package com.Util;
 2 
 3 import java.sql.Connection;
 4 import java.sql.SQLException;
 5 
 6 import org.junit.Test;
 7 
 8 public class Client {
 9 
10     public Client() {
11         // TODO Auto-generated constructor stub
12     }
13     @Test
14     public void test1(){
15         Connection conn=DbcpUtil.getConnection();
16         try {
17             conn.close();
18         } catch (SQLException e) {
19             // TODO Auto-generated catch block
20             e.printStackTrace();
21         }
22     }
23 
24 }
Client

 二:C3p0

a.简介:非常优秀的开源的数据

b,使用方法:

  1、拷贝jar包:c3p0-0.9.1.2.jar;c3p0-0.9.1.2-jdk1.3.jar(JDK版本低);c3p0-oracle-thin-extras-0.9.1.2.jar(为oracle服务)

 

  2、编写配置文件:参考发行包中的文档

 

  3、编写工具类:

4.3利用Tomcat管理数据源

1、JavaWeb服务器一般都提供数据源的实现,一般只需要做一些简单的配置即可。 

2、配置Tomcat的数据源 

Tomcat一旦配置了数据源,在启动时利用JNDI技术(JavaEE技术之一),把数据源放在JNDI容器中。

JNDI:Java Naming and Directory Interface(Java命名和目录接口) 

简单理解:JNDI是一个Map<String,Object>结构的容器,类似window系统的注册表。

key:String

value:Object

HEY_SOFTWARE/Microsoft/Ports

 

HEY_MATHINCES/Microsoft/Ports

 

java:/comp/env/jdbc/day17

DataSource对象

3、配置步骤:

a、拷贝数据库驱动jar到Tomcat\lib目录中 

b、在应用的META-INF目录下配置一个名称为context.xml的配置文件

c、从JNDI容器中取出创建好的数据源

 

使用JNDI的API来取:(javax.naming.*)

数据库元信息的获取(编写JDBC框架)

1、什么数据库元信息 

指数据库、表等的定义信息

2、元信息:

 

l  数据库的元信息:DatabaseMetaData dmd = conn.getMetaData();//数据库的元信息。全部都是getter方法

l  参数元信息:执行的SQL语句中的占位符元信息 

l  结果集元信息:

编写属于自己的JDBC框架

1、目的:简化代码,提高开发效率

策略设计模式

posted @ 2018-07-10 16:36  麦奇  阅读(214)  评论(0编辑  收藏  举报