




已閱讀5頁,還剩33頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
北京傳智播客教育 ,JDBC,講師: 李勇,北京傳智播客教育 ,簡介,JDBC(Java Data Base Connectivity,java數(shù)據(jù)庫連接),由一些接口和類構(gòu)成的API。 J2SE的一部分,由java.sql,javax.sql包組成。,北京傳智播客教育 ,簡介,應(yīng)用程序、JDBC API、數(shù)據(jù)庫驅(qū)動(dòng)及數(shù)據(jù)庫之間的關(guān)系,北京傳智播客教育 ,連接數(shù)據(jù)的步驟,注冊(cè)驅(qū)動(dòng) (只做一次) 建立連接(Connection) 創(chuàng)建執(zhí)行SQL的語句(Statement) 執(zhí)行語句 處理執(zhí)行結(jié)果(ResultSet) 釋放資源 快速起步示例,北京傳智播客教育 ,注冊(cè)驅(qū)動(dòng),Class.forName(“com.mysql.jdbc.Driver”); 推薦這種方式,不會(huì)對(duì)具體的驅(qū)動(dòng)類產(chǎn)生依賴。 DriverManager.registerDriver(com.mysql.jdbc.Driver); 會(huì)造成DriverManager中產(chǎn)生兩個(gè)一樣的驅(qū)動(dòng),并會(huì)對(duì)具體的驅(qū)動(dòng)類產(chǎn)生依賴。 System.setProperty(“jdbc.drivers”, “driver1:driver2”); 雖然不會(huì)對(duì)具體的驅(qū)動(dòng)類產(chǎn)生依賴;但注冊(cè)不太方便,所以很少使用。 驅(qū)動(dòng)類型(四種類型),北京傳智播客教育 ,建立連接(Connection),Connection conn = DriverManager.getConnection(url, user, password); url格式: JDBC:子協(xié)議:子名稱/主機(jī)名:端口/數(shù)據(jù)庫名?屬性名=屬性值& User,password可以用“屬性名=屬性值”方式告訴數(shù)據(jù)庫; 其他參數(shù)如:useUnicode=true&characterEncoding=GBK。,北京傳智播客教育 ,創(chuàng)建執(zhí)行SQL的語句(Statement),Statement Statement st = conn.createStatement(); st.executeQuery(sql); PreparedStatement String sql = “select * from table_name where col_name=?”; PreparedStatement ps = conn.preparedStatement(sql); ps.setString(1, “col_value”); ps.executeQuery();,北京傳智播客教育 ,處理執(zhí)行結(jié)果(ResultSet),ResultSet rs = statement.executeQuery(sql); While(rs.next() rs.getString(“col_name”); rs.getInt(“col_name”); / ,北京傳智播客教育 ,釋放資源,釋放ResultSet, Statement,Connection. 數(shù)據(jù)庫連接(Connection)是非常稀有的資源,用完后必須馬上釋放,如果Connection不能及時(shí)正確的關(guān)閉將導(dǎo)致系統(tǒng)宕機(jī)。Connection的使用原則是盡量晚創(chuàng)建,盡量早的釋放。,北京傳智播客教育 ,基本的CRUD(創(chuàng)建、讀取、更新、刪除),模板代碼 Connection conn = null; Statement st=null; ResultSet rs = null; try /獲得Connection /創(chuàng)建Statement /處理查詢結(jié)果ResultSet finally /釋放資源ResultSet, Statement,Connection ,北京傳智播客教育 ,創(chuàng)建,增加對(duì)應(yīng)SQL的INSERT,返回增加成功的行(記錄)數(shù) conn = getConnection(); Statement st = conn.createStatement(); String sql=“insert into user(name, age,regist_date )” + “values(name, 10, now()”; int i = st.executeUpdate(sql); /i為插入的記錄數(shù),北京傳智播客教育 ,讀取,讀取(查詢)對(duì)應(yīng)SQL的SELECT,返回查詢結(jié)果 conn = getConnection(); st = conn.createStatement(); String sql = “select id, name, age,regist_date from user“; rs = st.executeQuery(sql); while (rs.next() System.out.print(rs.getInt(“id“) + “ tt “); System.out.print(rs.getString(“name“) + “ tt “); System.out.print(rs.getInt(“age“) + “ tt “); System.out.print(rs.getTimestamp(“regist_date“) + “ tt “); System.out.println(); ,北京傳智播客教育 ,更新,更新(修改)對(duì)應(yīng)SQL的UPDATE,返回被修改的行(記錄)數(shù) conn = getConnection(); Statement st = conn.createStatement(); String sql=“update person set name=new name”; int i = st.executeUpdate(sql); /i為符合條件的記錄數(shù),北京傳智播客教育 ,刪除,刪除對(duì)應(yīng)SQL的DELETE,返回被刪除的行(記錄)數(shù) conn = getConnection(); Statement st = conn.createStatement(); String sql=“delete from user where id=1”; int i = st.executeUpdate(sql); /i為刪掉的記錄數(shù),北京傳智播客教育 ,CRUD總結(jié),增、刪、改用Statement.executeUpdate來完成,返回整數(shù)(匹配的記錄數(shù)),這類操作相對(duì)簡單。 查詢用Statement.executeQuery來完成,返回的是ResultSet對(duì)象,ResultSet中包含了查詢的結(jié)果;查詢相對(duì)與增、刪、改要復(fù)雜一些,因?yàn)橛胁樵兘Y(jié)果要處理。,北京傳智播客教育 ,SQL注入,PreparedStatement和Statement,在SQL中包含特殊字符或SQL的關(guān)鍵字(如: or 1 or )時(shí)Statement將出現(xiàn)不可預(yù)料的結(jié)果(出現(xiàn)異?;虿樵兊慕Y(jié)果不正確),可用PreparedStatement來解決。 PreperedStatement(從Statement擴(kuò)展而來)相對(duì)Statement的優(yōu)點(diǎn): 1.沒有SQL注入的問題。 2.Statement會(huì)使數(shù)據(jù)庫頻繁編譯SQL,可能造成數(shù)據(jù)庫緩沖區(qū)溢出。 3.數(shù)據(jù)庫和驅(qū)動(dòng)可以對(duì)PreperedStatement進(jìn)行優(yōu)化(只有在相關(guān)聯(lián)的數(shù)據(jù)庫連接沒有關(guān)閉的情況下有效)。,北京傳智播客教育 ,數(shù)據(jù)類型,詳細(xì)信息見java.sql.Types 幾種特殊且比較常用的類型 1.DATA,TIME,TIMESTAMP date,time,datetime 存:ps.setDate(i,d); ps.setTime(i,t); ps.setTimestamp(i, ts); 取:rs.getDate(i); rs.getTime(i); rs.getTimestamp(i); 2.CLOB text 存:ps.setCharacterStream(index, reader, length); ps.setString(i, s); ?。簉eader = rs. getCharacterStream(i); reader = rs.getClob(i).getCharacterStream(); string = rs.getString(i); 3.BLOB blob 存:ps.setBinaryStream(i, inputStream, length); 取:rs.getBinaryStream(i); rs.getBlob(i).getBinaryStream();,北京傳智播客教育 ,一個(gè)簡單用戶相關(guān)的數(shù)據(jù)訪問層,J2EE三層架構(gòu)簡介 表示層 、業(yè)務(wù)邏輯層、數(shù)據(jù)訪問層,三層之間用接口隔離。 定義domain對(duì)象User,定義存取用戶的接口 用JDBC實(shí)現(xiàn)接口 用配置文件(properties)和反射實(shí)現(xiàn)與具體類的耦合,北京傳智播客教育 ,事務(wù)(ACID),原子性(atomicity):組成事務(wù)處理的語句形成了一個(gè)邏輯單元,不能只執(zhí)行其中的一部分。 一致性(consistency):在事務(wù)處理執(zhí)行前后,數(shù)據(jù)庫是一致的(數(shù)據(jù)庫數(shù)據(jù)完整性約束)。 隔離性(isolcation):一個(gè)事務(wù)處理對(duì)另一個(gè)事務(wù)處理的影響。 持續(xù)性(durability):事務(wù)處理的效果能夠被永久保存下來 。 connection.setAutoCommit(false);/打開事務(wù)。 mit();/提交事務(wù)。 connection.rollback();/回滾事務(wù)。,北京傳智播客教育 ,事務(wù)(SavePoint),當(dāng)只想撤銷事務(wù)中的部分操作時(shí)可使用SavePoint SavePoint sp = connection.setSavepoint(); connection.rollerbak(sp);mit();,北京傳智播客教育 ,事務(wù)(JTA),跨越多個(gè)數(shù)據(jù)源的事務(wù),使用JTA容器實(shí)現(xiàn)事務(wù)。 分成兩階段提交。 javax.transaction.UserTransaction tx = (UserTransaction)ctx.lookup(“jndiName“); tx.begin(); /connection1 connection2 (可能來自不同的數(shù)據(jù)庫) mit();/tx.rollback();,北京傳智播客教育 ,隔離級(jí)別多線程并發(fā)讀取數(shù)據(jù)時(shí)的正確性,connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); V:可能出現(xiàn),X:不會(huì)出現(xiàn),北京傳智播客教育 ,存儲(chǔ)過程,存儲(chǔ)過程 CallableStatement(從PreperedStatement擴(kuò)展來) cs = connection.prepareCall(“call psname(?,?,?)”); cs.registerOutParameter(index, Types.INTEGER); cs.setXXX(i, xxxx); cs.executeUpdate(); int id=cs.getInt(index);,北京傳智播客教育 ,其他的幾個(gè)API,PreparedStatement.getGeneratedKeys() PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); ps.executeUpdate(); ResultSet rs = st.getGeneratedKeys();rs.getInt(1); 批處理,可以大幅度提升大量增、刪、改的速度。 PreparedStatement.addBatch(); PreparedStatement.executeBatch();,北京傳智播客教育 ,其他的幾個(gè)API,可滾動(dòng)的結(jié)果集 Statement st = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet rs = st.executeQuery(sql); rs.beforeFirst(); rs.afterLast();rs.first();rs.isFirst();rs.last();rs.isLast(); rs.absolute(9);rs.moveToInsertRow(); 可更新的結(jié)果集 conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); rs.updateString(“col name“, “new value“); rs.updateRow();,北京傳智播客教育 ,DatabaseMetaData和ParameterMetaData,DatabaseMetaData meta = connection.getMetaData(); 通過DatabaseMetaData可以獲得數(shù)據(jù)庫相關(guān)的信息如:數(shù)據(jù)庫版本、數(shù)據(jù)庫名、數(shù)據(jù)庫廠商信息、是否支持事務(wù)、是否支持某種事務(wù)隔離級(jí)別,是否支持滾動(dòng)結(jié)果集等。 ParameterMetaData pmd = preparedStatement.getParameterMetaData(); 通過 ParameterMetaData可以獲得參數(shù)信息。,北京傳智播客教育 ,ResultSetMetaData,ResultSetMetaData meta = rs.getMetaData(); 通過ResultSetMetaData可以獲得結(jié)果有幾列、各列名、各列別名、各列類型等。 可以將ResultSet放入Map(key:列名 value:列值)。 用反射ResultSetMetaData將查詢結(jié)果讀入對(duì)象中(簡單的O/RMapping) 1)讓SQL語句中列別名和要讀入的對(duì)象屬性名一樣; 2)通過ResultSetMetaData獲得結(jié)果列數(shù)和列別名; 3)通過反射將對(duì)象的所有setXxx方法找到; 4)將3)找到的方法setXxx和2)找到的列別名進(jìn)行匹配(即方法中的xxx于列別名相等); 5)由上一步找到的方法和列別名對(duì)應(yīng)關(guān)系進(jìn)行賦值 Method.invoke(obj, rs.getObject(columnAliasName);,北京傳智播客教育 ,數(shù)據(jù)源和連接池,DataSource用來取代DriverManager來獲取Connection; 通過DataSource獲得Connection速度很快; 通過DataSource獲得的Connection都是已經(jīng)被包裹過的(不是驅(qū)動(dòng)原來的連接),他的close方法已經(jīng)被修改。 一般DataSource內(nèi)部會(huì)用一個(gè)連接池來緩存Connection,這樣可以大幅度提高數(shù)據(jù)庫的訪問速度; 連接池可以理解成一個(gè)能夠存放Connection的Collection; 我們的程序只和DataSource打交道,不會(huì)直接訪問連接池;,北京傳智播客教育 ,一個(gè)簡單的數(shù)據(jù)源實(shí)現(xiàn),使用代理模式的Connection(核心代碼) class MyConnection implements Connection private Connection realConn; private LinkedList connPool; MyConnection(Connection rConn, LinkedList cPool) this.realConn=rConn; this.connPool=cPool; public void close() this.connPool.addLast(this); /. ,北京傳智播客教育 ,一個(gè)簡單的數(shù)據(jù)源實(shí)現(xiàn),DataSource(核心代碼) class MyDataSource implements DataSource private LinkedList connPool = new Vector(); public Connection getConneciton () if(this.connPool.size()0) return this.connPool.removeFirst(0); return createConnection(); private Connection createConnection() Connection realConn = DriverManager.getConnection(); Connection myConn = new MyConnection(realConn,this.connPool); return myConn; /. ,北京傳智播客教育 ,常用的開源實(shí)現(xiàn)DBCP,使用DBCP必須用的三個(gè)包: commons-dbcp-1.2.1.jar, commons-pool-1.2.jar, commons-collections-3.1.jar。 配置參數(shù)。 Java API: BasicDataSourceFactory.createDataSource( properties);,北京傳智播客教育 ,使用繼承優(yōu)化JDBC代碼(模板模式),優(yōu)化查詢操作,區(qū)分開變化和不變的部分: sql和ResultSet的處理是變化部分,創(chuàng)建和釋放資源部分是不變部分。 提取超類,將不變部分放入超類,變化部分留給子類實(shí)現(xiàn)。 超類的主要代碼: public Object find(String sql, Object args) rs = ps.executeQuery(); if (rs.next() return rowMapper(rs); protected abstract Object rowMapper(ResultSet rs);,北京傳智播客教育 ,使用組合優(yōu)化JDBC代碼(策略模式),優(yōu)化查詢操作,區(qū)分開變化和不變的部分: sql和ResultSet的處理是變化部分,創(chuàng)建和釋放資源部分是不變部分。 提取接口封裝變化部分。 JDBC操作主要代碼: public Object find(String sql, Object args, RowMapper rowMapper) rs = ps.executeQuery(); if (rs.next()return rowMapper.mapRow(rs); 回調(diào)接口: public interface RowMapper public Object mapRow(ResultSet rs) throws SQLException; ,北京傳智播客教育 ,Spring的JdbcTemplate,查詢帶有參數(shù),和行映射方法: public Object queryForObject(String sql, Object args, RowMapper rowMapper),使用自定義的UserRowMapper完成映射。 一個(gè)RowMapper的常用實(shí)現(xiàn)BeanPropertyRowMapper,該實(shí)現(xiàn)可將結(jié)果集轉(zhuǎn)換成一個(gè)Java Bean(字段名與Java Bean屬性名不符合規(guī)范,可用別名處理)。 public List query(String sql, Object args, RowMapper rowMapper)返回多個(gè)結(jié)果。 public int queryForInt(String sql)(如:select count(*) from user),其他結(jié)果比如String可用queryForObject方法向下轉(zhuǎn)型。 public Map queryForMap(String sql, Object args)返回若類型的Map(key:字段名或別名,value:列值)。 public List queryForList(String sql, Object args)返回多Map。,北京傳智播客教育 ,Spring的JdbcTemplate,更新public int update(String sql, Object args)。 插入數(shù)據(jù)并獲得結(jié)果: public Object execute(ConnectionCallback action) 其他方法簡介,北京傳智播客教育 ,Spring的NamedParameterJdbcTemplate,NamedParameterJdbcTemplate內(nèi)部包含了一個(gè)JdbcTemplate,所以JdbcTemplate能做的事情NamedParameterJdbcTemplate都能干; NamedParameterJdbcTemplate相對(duì)于JdbcTemplate主要增加了參數(shù)可以命名的功能。 public Object queryForObject(String sql, Map par
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 樹之歌教學(xué)課件一等獎(jiǎng)
- 山西小學(xué)三年級(jí)教學(xué)課件
- 教學(xué)課件結(jié)尾 結(jié)語
- 2025年長沙市中考物理試卷真題(含答案)
- 體育設(shè)施信托產(chǎn)品與消費(fèi)者權(quán)益保護(hù)分析考核試卷
- 兒童玩具行業(yè)消費(fèi)者購買決策因素研究考核試卷
- 公證員跨文化談判技巧培訓(xùn)考核試卷
- java繼承與多態(tài)面試題及答案
- 浙江省pcr上崗證考試試題及答案
- 環(huán)境成本會(huì)計(jì)在企業(yè)管理中的應(yīng)用探討考核試卷
- 2025年中國樂器網(wǎng)數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 西方文化導(dǎo)論試題及答案
- 2025-2030中國毛衣市場調(diào)研及重點(diǎn)企業(yè)投資評(píng)估規(guī)劃分析研究報(bào)告
- 2025江蘇省惠隆資產(chǎn)管理限公司招聘30人易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 試車員安全培訓(xùn)
- ARK年度重磅報(bào)告:2024年重大創(chuàng)新-BIGIDEAS2024(中文)
- 危重病例管理制度和報(bào)告制度
- 除臭系統(tǒng)操作培訓(xùn)
- 2025年南外小升初測(cè)試題及答案
- 幼兒園一日活動(dòng)保教細(xì)則培訓(xùn)
- GB/T 45236-2025化工園區(qū)危險(xiǎn)品運(yùn)輸車輛停車場建設(shè)規(guī)范
評(píng)論
0/150
提交評(píng)論