• 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 = "
    ";  
     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("
    ==========华丽的分割线==========
    ");  
    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到Tomcatlib目录中 

    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、目的:简化代码,提高开发效率

    策略设计模式

    合群是堕落的开始 优秀的开始是孤行
  • 相关阅读:
    讯时新闻系统再探
    三顾讯时对讯时新闻发布系统的艰难突破
    MsSQL注入猜解数据库技术
    提取中国IP段信息
    翻译杂感 via刘未鹏
    学习密度与专注力
    Cross Compilation Toolchains
    RHEL/CentOS 6.0使用第三方软件库(EPEL与RPMForge、RPMFusion软件库)
    一个很好的shell配置文件
    Cloud Computing
  • 原文地址:https://www.cnblogs.com/biaogejiushibiao/p/9285810.html
Copyright © 2020-2023  润新知