《《JDBC》傳播智客著名講師李勇的得意之作》由會員分享,可在線閱讀,更多相關《《JDBC》傳播智客著名講師李勇的得意之作(28頁珍藏版)》請在裝配圖網上搜索。
1、高級軟件人才實作培訓專家高級軟件人才實作培訓專家!JDBC講師:講師:李勇北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!簡介簡介lJDBC(Java Data Base Connectivity,java數據庫連接),由一些接口和類構成的API。lJ2SE的一部分,由java.sql,javax.sql包組成。北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!簡介簡介l應用程序、JDBC API、數據庫驅動及數據庫之間的關系北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!連接數據的步驟連接數據的步驟l注冊驅動(只做一次)l建立連接(C
2、onnection)l創(chuàng)建執(zhí)行SQL的語句(Statement)l執(zhí)行語句l處理執(zhí)行結果(ResultSet)l釋放資源快速起步示例北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!注冊驅動lClass.forName(“com.mysql.jdbc.Driver”);推薦這種方式,不會對具體的驅動類產生依賴。lDriverManager.registerDriver(com.mysql.jdbc.Driver);會造成DriverManager中產生兩個一樣的驅動,并會對具體的驅動類產生依賴。lSystem.setProperty(“jdbc.drivers”,“drive
3、r1:driver2”);雖然不會對具體的驅動類產生依賴;但注冊不太方便,所以很少使用。l驅動類型(四種類型)北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!建立連接(Connection)lConnection conn=DriverManager.getConnection(url,user,password);lurl格式:JDBC:子協議:子名稱/主機名:端口/數據庫名?屬性名=屬性值&lUser,password可以用“屬性名=屬性值”方式告訴數據庫;l其他參數如:useUnicode=true&characterEncoding=GBK。北京傳智播客教育 高級軟
4、件人才實作培訓專家高級軟件人才實作培訓專家!創(chuàng)建執(zhí)行SQL的語句(Statement)lStatement Statement st=conn.createStatement();st.executeQuery(sql);lPreparedStatementString sql=“select*from table_name where col_name=?”;PreparedStatement ps=conn.preparedStatement(sql);ps.setString(1,“col_value”);ps.executeQuery();北京傳智播客教育 高級軟件人才實作培訓專家高級
5、軟件人才實作培訓專家!處理執(zhí)行結果(ResultSet)ResultSet rs=statement.executeQuery(sql);While(rs.next()rs.getString(“col_name”);rs.getInt(“col_name”);/北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!釋放資源l釋放ResultSet,Statement,Connection.l數據庫連接(Connection)是非常稀有的資源,用完后必須馬上釋放,如果Connection不能及時正確的關閉將導致系統(tǒng)宕機。Connection的使用原則是盡量晚創(chuàng)建,盡量早的釋放。北
6、京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!基本的基本的CRUD(創(chuàng)建、讀取、更新、刪除)(創(chuàng)建、讀取、更新、刪除)l模板代碼 Connection conn=null;Statement st=null;ResultSet rs=null;try/獲得Connection/創(chuàng)建Statement/處理查詢結果ResultSet finally/釋放資源ResultSet,Statement,Connection北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!創(chuàng)建創(chuàng)建l增加對應SQL的INSERT,返回增加成功的行(記錄)數 conn=getConne
7、ction();Statement st=conn.createStatement();String sql=“insert into user(name,age,regist_date)”+“values(name,10,now()”;int i=st.executeUpdate(sql);/i為插入的記錄數北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!讀取讀取l讀?。ú樵儯猄QL的SELECT,返回查詢結果conn=getConnection();st=conn.createStatement();String sql=select id,name,age,reg
8、ist_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();北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!更新更新l更新(修改)對應SQL的UPDATE,返回
9、被修改的行(記錄)數 conn=getConnection();Statement st=conn.createStatement();String sql=“update person set name=new name”;int i=st.executeUpdate(sql);/i為符合條件的記錄數北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!刪除刪除l刪除對應SQL的DELETE,返回被刪除的行(記錄)數 conn=getConnection();Statement st=conn.createStatement();String sql=“delete from
10、user where id=1”;int i=st.executeUpdate(sql);/i為刪掉的記錄數北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!CRUD總結總結l增、刪、改用Statement.executeUpdate來完成,返回整數(匹配的記錄數),這類操作相對簡單。l查詢用Statement.executeQuery來完成,返回的是ResultSet對象,ResultSet中包含了查詢的結果;查詢相對與增、刪、改要復雜一些,因為有查詢結果要處理。北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!SQL注入注入,PreparedStatem
11、ent和和Statement l在SQL中包含特殊字符或SQL的關鍵字(如:or 1 or)時Statement將出現不可預料的結果(出現異?;虿樵兊慕Y果不正確),可用PreparedStatement來解決。lPreperedStatement(從Statement擴展而來)相對Statement的優(yōu)點:1.沒有SQL注入的問題。2.Statement會使數據庫頻繁編譯SQL,可能造成數據庫緩沖區(qū)溢出。3.數據庫和驅動可以對PreperedStatement進行優(yōu)化(只有在相關聯的數據庫連接沒有關閉的情況下有效)。北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!數據類型數
12、據類型l詳細信息見java.sql.Typesl幾種特殊且比較常用的類型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.
13、getClob(i).getCharacterStream();string=rs.getString(i);3.BLOB blob 存:ps.setBinaryStream(i,inputStream,length);?。簉s.getBinaryStream(i);rs.getBlob(i).getBinaryStream();北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!一個簡單用戶相關的數據訪問層一個簡單用戶相關的數據訪問層 lJ2EE三層架構簡介表示層、業(yè)務邏輯層、數據訪問層,三層之間用接口隔離。l定義domain對象User,定義存取用戶的接口l用JDBC實現接
14、口l用配置文件(properties)和反射實現與具體類的耦合 北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!事務事務(ACID)l原子性(atomicity):組成事務處理的語句形成了一個邏輯單元,不能只執(zhí)行其中的一部分。l一致性(consistency):在事務處理執(zhí)行前后,數據庫是一致的(兩個賬戶要么都變,或者都不變)。l隔離性(isolcation):一個事務處理對另一個事務處理沒有影響。l持續(xù)性(durability):事務處理的效果能夠被永久保存下來。lconnection.setAutoCommit(false);/打開事務。mit();/提交事務。lcon
15、nection.rollback();/回滾事務。北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!隔離級別隔離級別多線程并發(fā)讀取數據時的正確性 lconnection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);lV:可能出現,X:不會出現隔離級別隔離級別 臟讀臟讀 不可重復讀不可重復讀 幻讀幻讀 讀未提交(Read uncommitted)VVV讀已提交(Read committed)xVV可重復讀(Repeatable read)xxV可串行化(Serializable)xxx北京傳智播客
16、教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!存儲過程l存儲過程CallableStatement(從PreperedStatement擴展來)cs=connection.prepareCall(“call psname(?,?,?)”);cs.registerOutParameter(index,Types.INTEGER);cs.setXXX(i,xxxx);cs.executeUpdate();int id=cs.getInt(index);北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!其他的幾個其他的幾個APIlStatement.getGenerate
17、dKeys()PreparedStatement ps=connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);ps.executeUpdate();ResultSet rs=st.getGeneratedKeys();rs.getInt(1);l批處理,可以大幅度提升大量增、刪、改的速度。PreparedStatement.addBatch();PreparedStatement.executeBatch();l可滾動的結果集Statement st=connection.createStatement(ResultS
18、et.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();北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!DatabaseMetaDatalDatabaseMetaData meta=connection.getMetaData();l
19、通過DatabaseMetaData可以獲得數據庫相關的信息如:數據庫版本、數據庫名、數據庫廠商信息、是否支持事務、是否支持某種事務隔離級別,是否支持滾動結果集等。北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!ResultSetMetaDatalResultSetMetaData meta=rs.getMetaData();l通過ResultSetMetaData可以獲得結果有幾列、各列名、各列別名、各列類型等。l可以將ResultSet放入Map(key:列名 value:列值)。l用反射ResultSetMetaData將查詢結果讀入對象中(簡單的O/RMapping
20、)1)讓SQL語句中列別名和要讀入的對象屬性名一樣;2)通過ResultSetMetaData獲得結果列數和列別名;3)通過反射將對象的所有setXxx方法找到;4)將3)找到的方法setXxx和2)找到的列別名進行匹配(即方法中的xxx于列別名相等);5)由上一步找到的方法和列別名對應關系進行賦值Method.invoke(obj,rs.getObject(columnAliasName);北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!數據源和連接池數據源和連接池lDataSource用來取代DriverManager來獲取Connection;l通過DataSourc
21、e獲得Connection速度很快;l通過DataSource獲得的Connection都是已經被包裹過的(不是驅動原來的連接),他的close方法已經被修改。l一般DataSource內部會用一個連接池來緩存Connection,這樣可以大幅度提高數據庫的訪問速度;l連接池可以理解成一個能夠存放Connection的Collection;l我們的程序只和DataSource打交道,不會直接訪問連接池;北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!一個簡單的數據源一個簡單的數據源實現l使用裝飾模式的Connection(核心代碼)class MyConnection im
22、plements Connectionprivate Connection realConn;private LinkedList connPool;MyConnection(Connection rConn,LinkedList cPool)this.realConn=rConn;this.connPool=cPool;public void close()this.connPool.addLast(this);/.北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!一個簡單的數據源一個簡單的數據源實現lDataSource(核心代碼)class MyDataSource i
23、mplements DataSourceprivate 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;/.北京傳智播客教育 高級軟件人才實作培訓專家高級軟件人才實作培訓專家!常用的開源實現DBCPl使用DBCP必須用的三個包:commons-dbcp-1.2.1.jar,commons-pool-1.2.jar,commons-collections-3.1.jar。lJava API:BasicDataSourceFactory.createDataSource(properties);北京傳智播客教育