一、JDBC
1.簡介
JDBC本身是java連接數據庫的一個標準,是進行數據庫連接的抽象層,由java編寫的一組類和接口組成,接口的實現由各個數據庫廠商來完成
各大數據庫廠商對JDBC的API的接口提供實現,即驅動包。
二、JDBC操作
1.加載註冊驅動 Class.forName(""); 2.獲取數據庫連接 Connection conn=DriverManager.getConnection(String url,String user,String password); 3.創建語句對象 Statement st=conn.creatStatement(); 4.執行sql語句 st.executeUpdate(String sql); 或者 ResultSet rs =st.executeQuery(String sql); 5.獲取結果集 while(rs.next()){ rs.getObject(列名); } 或者 if(rs.next()){ rs.getObject(列名); } 6.釋放資源
jdbc連接oracle、mysql等主流數據庫的驅動類和url
----------------------------------------------------------- oracle driverClass:oracle.jdbc.driver.OracleDriver url:jdbc:oracle:thin:@127.0.0.1:1521:dbname ----------------------------------------------------------- mysql driverClass:com.mysql.jdbc.Driver url:jdbc:mysql://localhost:3306/mydbr。 ----------------------------------------------------------- DB2 driverClass:com.ibm.db2.jcc.DB2Driver url:jdbc:db2://127.0.0.1:50000/dbname ----------------------------------------------------------- syBase driverClass:com.sybase.jdbc.SybDriver url:jdbc:sybase:Tds:localhost:5007/dbname ----------------------------------------------------------- PostgreSQL driverClass:org.postgresql.Driver url:jdbc:postgresql://localhost/dbname ----------------------------------------------------------- Sql Server2000 driverClass:com.microsoft.jdbc.sqlserver.SQLServerDriver url:jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=dbname ----------------------------------------------------------- Sql Server2005 driverClass:com.microsoft.sqlserver.jdbc.SQLServerDriver url:jdbc:sqlserver://localhost:1433; DatabaseName=dbname -----------------------------------------------------------
三、DAO設計思想(不直接操作數據庫,而是在數據庫和業務層之間)
DAO的實現類實現數據庫操作,
先將數據封裝到domain中,在調用dao的方法,把domain作爲參數傳遞過去
四、代碼重構
1.數據庫連接對象的操作重複,抽取到JDBCUtil工具類
2.註冊驅動抽取到靜態代碼塊中
3.釋放資源抽取到JDBCUtil
4.將操作數據庫相關字符串抽取到資源文件db.properties
提取到db.properties文件
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql:///jdbcdemo username=root password=admin
JDBCUtil
public class JDBCUtil { private JDBCUtil(){} private static Properties p = new Properties(); static{ try { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); InputStream in = classLoader.getResourceAsStream("db.properties"); p.load(in); Class.forName(p.getProperty("driverClassName")); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConn(){ try { return DriverManager.getConnection(p.getProperty("url"), p.getProperty("username"), p.getProperty("password")); } catch (Exception e) { throw new RuntimeException("親,獲取數據庫連接失敗",e); } } public static void close(Connection conn,Statement st,ResultSet rs){ try { if (rs != null) { rs.close(); } } catch (Exception e2) { e2.printStackTrace(); } finally { try { if (st != null) { st.close(); } } catch (SQLException e1) { e1.printStackTrace(); } finally { try { if (conn != null) { conn.close(); } } catch (SQLException e2) { e2.printStackTrace(); } } } } }
五、預編譯語句對象
Statement: 表示靜態SQL語句對象.
PreparedStatement:Statement的子接口,表示預編譯SQL語句對象. 通過佔位符(?)來拼SQL.
1.創建預編譯語句對象 PreparedStatement ps=conn.preparedStatement(sql); 2.設置佔位符 ps.setString(1,""); 3.執行sql語句 int executeUpdate() ResultSet executeQuery()
六、Statement和PreparedStatement的區別:
1).PreparedStatement 代碼的可讀性和可維護性. (SQL模板,使用佔位符表示參數) 2).PreparedStatement 能最大可能提高性能. MySQL不支持. 3).PreparedStatement 能保證安全性. 可以防止SQL注入: name='' or 1=1 or ''
七、事務(Transaction 簡寫爲tx)
1.事務的ACID屬性
1.原子性(Atomicity)原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。 (一榮俱榮,一損俱損) 2. 一致性(Consistency)事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態。(數據不被破壞) 3. 隔離性(Isolation) 事務的隔離性是指一個事務的執行不能被其他事務干擾,即一個事務內部的操作及使用的數據對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。 4. 持久性(Durability)持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來的其他操作和數據庫故障不應該對其有任何影響
2.如何在代碼中去處理事務:
1.在JDBC中,事務是默認提交的. 必須先設置事務爲手動提交. connection對象.setAutoCommit(false);//設置事務爲手動提交. 2.手動的提交事務. connection對象.commit(); 3.若出現異常必須回滾事務: 不回滾事務,總餘額依然是正確的. 若不回滾事務,不會釋放數據庫資源. connection對象.rollback();
3.JDBC獲取自動生成的主鍵
如何在JDBC中保存數據的時候獲取自動生成的主鍵呢?
----------------------------------------------------------------------
Statement: int executeUpdate(String sql,int autoGeneratedKeys):執行SQL: 參數:autoGeneratedKeys,是否需要返回自動生成的主鍵. 常量值:Statement.RETURN_GENERATED_KEYS ResultSet getGeneratedKeys():獲取自動生成的主鍵 PreparedStatement: PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) :創建PreparedStatement對象,並指定是否需要返回生成的主鍵. 參數的常量值:Statement.RETURN_GENERATED_KEYS
八、連接池(也叫數據源)(除了獲取數據庫連接不一樣,其他操作和jdbc一樣)
1.導入jar包
commons-dbcp-1.4.jar
commons-pool-1.5.6.jar
數據庫驅動包
2.在Java中,連接池使用javax.sql.DataSource接口來表示連接池.
注意:DataSource僅僅只是一個接口,由各大服務器廠商來實現(Tomcat.JBoss).
常用的DataSource的實現:
DBCP: Spring推薦的
C3P0: Hibernate推薦的
3.獲取連接池對象(DataSource)
方法1:手動配置連接池配置 DataSource ds=new BasicDataSource(); ds.setDriverClassNmae(""); ds.setUrl(""); ds.setUsername(""); ds.setPassword(""); 方式2:通過連接池工廠類創建連接池對象 DataSource ds= BasicDataSourceFactory.createDataSource(p);
DBCPUtil
public class DBCPUtil { private DBCPUtil(){} private static Properties p = new Properties(); private static DataSource dataSource=null; static{ try { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); InputStream in = classLoader.getResourceAsStream("dbcp.properties"); p.load(in); //通過連接池工程類創建連接池對象 dataSource = BasicDataSourceFactory.createDataSource(p); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConn(){ try { return dataSource.getConnection(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("親,獲取數據庫連接失敗",e); } } public static void close(Connection conn,Statement st,ResultSet rs){ try { if (rs != null) { rs.close(); } } catch (Exception e2) { e2.printStackTrace(); } finally { try { if (st != null) { st.close(); } } catch (SQLException e1) { e1.printStackTrace(); } finally { try { if (conn != null) { conn.close(); } } catch (SQLException e2) { e2.printStackTrace(); } } } } }
4.獲取數據庫連接
DataSource對象.getConnection();
5.使用連接池的時候: 釋放資源: Connection對象.close():
是把Connection放回給連接池,而不是和數據庫斷開.