<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    學習園地

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      3 Posts :: 14 Stories :: 0 Comments :: 0 Trackbacks
    對spring JdbcTemplate的一個擴展(使其支持單Connection). 

    不怕大家笑話,以前一直沒怎么使用過spring jdbc template, 
    印象中只用過 
    public List queryForList(String sql, Object[] args) 
    public Map queryForMap(String sql, Object[] args) 
    和SqlFunction 

    在orm大行其道,spring誕生快一個實際的今天,再來探討jdbc的一些封裝實在不知道有沒有意義. 
    不過還是想把剛剛弄出來的一點東西和大家分享. 

    看了一下 JdbcTemplate, 
    發現起核心是那幾個 execute 方法. 
    而那幾個execute方法的機構大概是這樣(重點討論Connection,所以其他地方從簡) 

    Java代碼  收藏代碼
    1. execute方法開始  
    2.   
    3.   Connection con = DataSourceUtils.getConnection(getDataSource());  
    4.   
    5.   // 做一些數據庫操作  
    6.   
    7.   DataSourceUtils.releaseConnection(con, getDataSource());  
    8.   
    9. execute方法結束  


    當你要批量執行一些操作時(不是 每個操作使用不同的sql,或者是其他不適合 addBatch的情形). 

    如下: 
    Java代碼  收藏代碼
    1. JdbcTemplate jdbcTemplate=new JdbcTemplate(ds);  
    2. jdbcTemplate.query(sql_1, args_1,rch_1);  
    3. jdbcTemplate.query(sql_2, args_2,rch_2);  
    4. jdbcTemplate.query(sql_3, args_3,rch_3);  
    5. jdbcTemplate.query(sql_4, args_4,rch_4);  
    6. ......  


    此時,在內部實際上執行了,n次 getConnection,releaseConnection. 

    而這些操作,在很多時候,是可以通過一個Connection來完成的. 

    我的擴展就是實現了這個功能. 

    Java代碼  收藏代碼
    1. JdbcTemplatePlus jdbcTemplate=new JdbcTemplatePlus(ds);  
    2. // 內部使用一個唯一的Connection  
    3. jdbcTemplate.setUseOneConnection(true);  
    4. jdbcTemplate.query(sql_1, args_1,rch_1);  
    5. jdbcTemplate.query(sql_2, args_2,rch_2);  
    6. jdbcTemplate.query(sql_3, args_3,rch_3);  
    7. jdbcTemplate.query(sql_4, args_4,rch_4);  
    8. ......  
    9. // 最后調用該方法 釋放那個內部唯一的Connection  
    10. // 雖然我在finalize 里調用了,不過finalize畢竟不是總能在正確的時間被正確的調用  
    11. jdbcTemplate.releaseConnection();  



    我們系統中,有大量的嵌套查詢.使用該JdbcTemplatePlus的唯一Connection特性后,類似的操作速度提升明顯. 
    (不過可能我們原先的做法不對,也許 spring內部已經實現這個機制了 這些我就不明白了,歡迎大家來指正) 
    我們原先的做法(偽代碼): 
    Java代碼  收藏代碼
    1. public List queryNsubQueryUserList(Map param){  
    2.   
    3.     // 外層查詢  
    4.     final String bsql="select * from ......";  
    5.     final JdbcTemplate jdbcTemplate=createJdbcTemplate();  
    6.       
    7.     // 子查詢相關  
    8.     final String subSql="select ............ ";  
    9.     final JdbcTemplate subJdbcTemplate=createJdbcTemplate();  
    10.       
    11.     List rslist=jdbcTemplate.query(bsql.toString(),sqlArg,   
    12.         new ResultSetHandler(){  
    13.             public void processRow(ResultSet rs) throws SQLException {  
    14.                 final 一個VO recordObj=new 一個VO();  
    15.                 // 子查詢  
    16.                 subJdbcTemplate.query(subSql, subQueryArgs,   
    17.                     new ResultSetHandler(){  
    18.                         public void processRow(ResultSet rs) throws SQLException {  
    19.                             // 一些操作........  
    20.                         }  
    21.                     }  
    22.                 );  
    23.                     // 一些操作........  
    24.                     recordObj.setXXXXX(rs.getString("XXXXX"));  
    25.                     .........  
    26.                     // 將記錄放入集合  
    27.                     addRecord(recordObj);  
    28.             }  
    29.         }  
    30.     );  
    31.     return rslist;  
    32.     }  
    33. }  

    在使用 JdbcTemplatePlus 代替 JdbcTemplate,并設置.setUseOneConnection(true)后, 
    耗時變為原先的1/8左右. 


    擴展的 JdbcTemplatePlus 代碼如下,歡迎大家拍磚,挑錯. 
    對 execute方法的修改如下: 
    把所有的 this.ativeJdbcExtractor換成 getNativeJdbcExtractor(), 這個是必須的 呵呵. 

    把所有 Connection con = DataSourceUtils.getConnection(getDataSource()); 換成 
    Connection con = tryGetConnection(); 

    把所有 DataSourceUtils.releaseConnection(con, getDataSource());  換成 
    tryReleaseConnection(con); 

    Java代碼  收藏代碼
    1. package com.neusoft.tdframework.dao;  
    2.   
    3. import java.sql.CallableStatement;  
    4. import java.sql.Connection;  
    5. import java.sql.PreparedStatement;  
    6. import java.sql.SQLException;  
    7. import java.sql.Statement;  
    8.   
    9. import javax.sql.DataSource;  
    10.   
    11. import org.springframework.dao.DataAccessException;  
    12. import org.springframework.jdbc.core.CallableStatementCallback;  
    13. import org.springframework.jdbc.core.CallableStatementCreator;  
    14. import org.springframework.jdbc.core.ConnectionCallback;  
    15. import org.springframework.jdbc.core.JdbcTemplate;  
    16. import org.springframework.jdbc.core.ParameterDisposer;  
    17. import org.springframework.jdbc.core.PreparedStatementCallback;  
    18. import org.springframework.jdbc.core.PreparedStatementCreator;  
    19. import org.springframework.jdbc.core.SqlProvider;  
    20. import org.springframework.jdbc.core.StatementCallback;  
    21. import org.springframework.jdbc.datasource.DataSourceUtils;  
    22. import org.springframework.jdbc.support.JdbcUtils;  
    23. import org.springframework.util.Assert;  
    24.   
    25. public class JdbcTemplatePlus extends JdbcTemplate {  
    26.   
    27.     private Connection connection=null;  
    28.     private boolean useOneConnection=false;  
    29.   
    30.   
    31.     public JdbcTemplatePlus() {  
    32.         super();  
    33.     }  
    34.     public JdbcTemplatePlus(DataSource dataSource) {  
    35.         super(dataSource);  
    36.     }  
    37.     public JdbcTemplatePlus(DataSource dataSource, boolean lazyInit) {  
    38.         super(dataSource,lazyInit);  
    39.     }  
    40.       
    41.     private Connection tryGetConnection(){  
    42.         if (useOneConnection){  
    43.             if (connection==null){  
    44.                 connection= DataSourceUtils.getConnection(getDataSource());  
    45.             }  
    46.             return connection;  
    47.         }  
    48.         return DataSourceUtils.getConnection(getDataSource());  
    49.     }  
    50.       
    51.     private void tryReleaseConnection(Connection con){  
    52.         if (!useOneConnection){  
    53.             DataSourceUtils.releaseConnection(con, getDataSource());  
    54.         }  
    55.     }  
    56.       
    57.     public Connection getConnection(){  
    58.         return connection;  
    59.     }  
    60.       
    61.     public void setConnection(Connection connection){  
    62.         this.connection=connection;  
    63.     }  
    64.       
    65.     public boolean isUseOneConnection() {  
    66.         return useOneConnection;  
    67.     }  
    68.   
    69.     public void setUseOneConnection(boolean useOneConnection) {  
    70.         this.useOneConnection = useOneConnection;  
    71.     }  
    72.       
    73.     public void releaseConnection(){  
    74.         DataSourceUtils.releaseConnection(connection, getDataSource());  
    75.     }  
    76.       
    77.       
    78.     // 不明白這個方法為什么spring不把他弄成 protected 或 public,  
    79.     // 導致我要重寫execute方法時還必須要重寫這個方法  :(  
    80.     public static String getSql(Object sqlProvider) {  
    81.         if (sqlProvider instanceof SqlProvider) {  
    82.             return ((SqlProvider) sqlProvider).getSql();  
    83.         }  
    84.         else {  
    85.             return null;  
    86.         }  
    87.     }  
    88.       
    89.     /* 
    90.         對 execute方法的修改如下: 
    91.         把所有的 this.ativeJdbcExtractor換成 getNativeJdbcExtractor(), 這個是必須的 呵呵. 
    92.          
    93.         把所有 Connection con = DataSourceUtils.getConnection(getDataSource()); 換成 
    94.         Connection con = tryGetConnection(); 
    95.          
    96.         把所有 DataSourceUtils.releaseConnection(con, getDataSource());  換成 
    97.         tryReleaseConnection(con); 
    98.      */  
    99.       
    100.     public Object execute(ConnectionCallback action) throws DataAccessException {  
    101.         Assert.notNull(action, "Callback object must not be null");  
    102.   
    103.         Connection con = tryGetConnection();  
    104.         try {  
    105.             Connection conToUse = con;  
    106.             if (getNativeJdbcExtractor() != null) {  
    107.                 conToUse = getNativeJdbcExtractor().getNativeConnection(con);  
    108.             } else {  
    109.                 conToUse = createConnectionProxy(con);  
    110.             }  
    111.             return action.doInConnection(conToUse);  
    112.         } catch (SQLException ex) {  
    113.             tryReleaseConnection(con);  
    114.             con = null;  
    115.             throw getExceptionTranslator().translate("ConnectionCallback",  
    116.                     getSql(action), ex);  
    117.         } finally {  
    118.             tryReleaseConnection(con);  
    119.         }  
    120.     }  
    121.   
    122.     public Object execute(StatementCallback action) throws DataAccessException {  
    123.         Assert.notNull(action, "Callback object must not be null");  
    124.   
    125.         Connection con = tryGetConnection();  
    126.         Statement stmt = null;  
    127.         try {  
    128.             Connection conToUse = con;  
    129.             if (getNativeJdbcExtractor() != null  
    130.                     && getNativeJdbcExtractor()  
    131.                             .isNativeConnectionNecessaryForNativeStatements()) {  
    132.                 conToUse = getNativeJdbcExtractor().getNativeConnection(con);  
    133.             }  
    134.             stmt = conToUse.createStatement();  
    135.             applyStatementSettings(stmt);  
    136.             Statement stmtToUse = stmt;  
    137.             if (getNativeJdbcExtractor() != null) {  
    138.                 stmtToUse = getNativeJdbcExtractor().getNativeStatement(stmt);  
    139.             }  
    140.             Object result = action.doInStatement(stmtToUse);  
    141.             handleWarnings(stmt.getWarnings());  
    142.             return result;  
    143.         } catch (SQLException ex) {  
    144.             JdbcUtils.closeStatement(stmt);  
    145.             stmt = null;  
    146.             tryReleaseConnection(con);  
    147.             con = null;  
    148.             throw getExceptionTranslator().translate("StatementCallback",  
    149.                     getSql(action), ex);  
    150.         } finally {  
    151.             JdbcUtils.closeStatement(stmt);  
    152.             tryReleaseConnection(con);  
    153.         }  
    154.     }  
    155.   
    156.     public Object execute(PreparedStatementCreator psc,  
    157.             PreparedStatementCallback action) throws DataAccessException {  
    158.   
    159.         Assert.notNull(psc, "PreparedStatementCreator must not be null");  
    160.         Assert.notNull(action, "Callback object must not be null");  
    161.         if (logger.isDebugEnabled()) {  
    162.             String sql = getSql(psc);  
    163.             logger.debug("Executing prepared SQL statement"  
    164.                     + (sql != null ? " [" + sql + "]" : ""));  
    165.         }  
    166.   
    167.         Connection con = tryGetConnection();  
    168.         PreparedStatement ps = null;  
    169.         try {  
    170.             Connection conToUse = con;  
    171.             if (getNativeJdbcExtractor() != null  
    172.                     && getNativeJdbcExtractor()  
    173.                             .isNativeConnectionNecessaryForNativePreparedStatements()) {  
    174.                 conToUse = getNativeJdbcExtractor().getNativeConnection(con);  
    175.             }  
    176.             ps = psc.createPreparedStatement(conToUse);  
    177.             applyStatementSettings(ps);  
    178.             PreparedStatement psToUse = ps;  
    179.             if (getNativeJdbcExtractor() != null) {  
    180.                 psToUse = getNativeJdbcExtractor()  
    181.                         .getNativePreparedStatement(ps);  
    182.             }  
    183.             Object result = action.doInPreparedStatement(psToUse);  
    184.             handleWarnings(ps.getWarnings());  
    185.             return result;  
    186.         } catch (SQLException ex) {  
    187.             if (psc instanceof ParameterDisposer) {  
    188.                 ((ParameterDisposer) psc).cleanupParameters();  
    189.             }  
    190.             String sql = getSql(psc);  
    191.             psc = null;  
    192.             JdbcUtils.closeStatement(ps);  
    193.             ps = null;  
    194.             tryReleaseConnection(con);  
    195.             con = null;  
    196.             throw getExceptionTranslator().translate(  
    197.                     "PreparedStatementCallback", sql, ex);  
    198.         } finally {  
    199.             if (psc instanceof ParameterDisposer) {  
    200.                 ((ParameterDisposer) psc).cleanupParameters();  
    201.             }  
    202.             JdbcUtils.closeStatement(ps);  
    203.             tryReleaseConnection(con);  
    204.         }  
    205.     }  
    206.   
    207.     public Object execute(CallableStatementCreator csc,  
    208.             CallableStatementCallback action) throws DataAccessException {  
    209.   
    210.         Assert.notNull(csc, "CallableStatementCreator must not be null");  
    211.         Assert.notNull(action, "Callback object must not be null");  
    212.         if (logger.isDebugEnabled()) {  
    213.             String sql = getSql(csc);  
    214.             logger.debug("Calling stored procedure"  
    215.                     + (sql != null ? " [" + sql + "]" : ""));  
    216.         }  
    217.   
    218.         Connection con = tryGetConnection();  
    219.         CallableStatement cs = null;  
    220.         try {  
    221.             Connection conToUse = con;  
    222.             if (getNativeJdbcExtractor() != null) {  
    223.                 conToUse = getNativeJdbcExtractor().getNativeConnection(con);  
    224.             }  
    225.             cs = csc.createCallableStatement(conToUse);  
    226.             applyStatementSettings(cs);  
    227.             CallableStatement csToUse = cs;  
    228.             if (getNativeJdbcExtractor() != null) {  
    229.                 csToUse = getNativeJdbcExtractor()  
    230.                         .getNativeCallableStatement(cs);  
    231.             }  
    232.             Object result = action.doInCallableStatement(csToUse);  
    233.             handleWarnings(cs.getWarnings());  
    234.             return result;  
    235.         } catch (SQLException ex) {  
    236.             // Release Connection early, to avoid potential connection pool  
    237.             // deadlock  
    238.             // in the case when the exception translator hasn't been initialized  
    239.             // yet.  
    240.             if (csc instanceof ParameterDisposer) {  
    241.                 ((ParameterDisposer) csc).cleanupParameters();  
    242.             }  
    243.             String sql = getSql(csc);  
    244.             csc = null;  
    245.             JdbcUtils.closeStatement(cs);  
    246.             cs = null;  
    247.             tryReleaseConnection(con);  
    248.             con = null;  
    249.             throw getExceptionTranslator().translate(  
    250.                     "CallableStatementCallback", sql, ex);  
    251.         } finally {  
    252.             if (csc instanceof ParameterDisposer) {  
    253.                 ((ParameterDisposer) csc).cleanupParameters();  
    254.             }  
    255.             JdbcUtils.closeStatement(cs);  
    256.             tryReleaseConnection(con);  
    257.         }  
    258.     }  
    259.   
    260.   
    261.     protected void finalize() throws Throwable{  
    262.         super.finalize();  
    263.         releaseConnection();  
    264.     }  
    265.   
    266.   
    267.       
    268. }  
    posted on 2014-03-26 22:45 丘比特 閱讀(346) 評論(0)  編輯  收藏 所屬分類: Java
    主站蜘蛛池模板: 中国国产高清免费av片| 内射无码专区久久亚洲| a级毛片在线免费| 春暖花开亚洲性无区一区二区| 久久久久亚洲Av无码专| 亚洲日本乱码在线观看| 亚洲av成人一区二区三区在线观看 | 亚洲国产成人久久精品大牛影视| 亚洲小视频在线观看| 亚洲视频在线一区二区| 四虎影库久免费视频| 狼友av永久网站免费观看| 国产精品久久久久久久久久免费 | 亚洲韩国—中文字幕| 在线A亚洲老鸭窝天堂| 狠狠色婷婷狠狠狠亚洲综合| 又爽又黄无遮挡高清免费视频| 成人免费在线视频| 好男人视频在线观看免费看片| AV片在线观看免费| 岛国大片免费在线观看| 成人午夜性A级毛片免费| www.999精品视频观看免费| 69堂人成无码免费视频果冻传媒| 久久国产高潮流白浆免费观看| 无码A级毛片免费视频内谢| 无码av免费网站| 久久ww精品w免费人成| 久久久久av无码免费网| 色se01短视频永久免费| 久久久久久国产a免费观看黄色大片 | 最近中文字幕完整版免费高清| 亚洲精品免费视频| 最刺激黄a大片免费网站| 99精品在线免费观看| 免费看片在线观看| 日韩精品无码区免费专区| 四色在线精品免费观看| 日本免费电影一区| 亚洲精品国产精品乱码不卞 | 久操免费在线观看|