天天看點

JDBC/Druid/JdbcTemplate操作資料庫前言jdbc操作資料庫druid操作資料庫

前言

本文重在展示jdbc、druid、jdbcTemplate三種方式操作資料庫(Mysql)。

搭配其他文章與自己實際操作為佳。如有錯誤還請指正

jdbc操作資料庫

jdbc是java語言操作資料庫,即對資料庫資料做增删查改操作,事務操作等。

使用步驟

1. 導入jar包
	mysql-connector-java-5.1.37-bin.jar
2. 注冊驅動
3. 擷取資料庫連接配接對象 Connection
4. 定義sql
5. 擷取執行sql語句的對象 Statement
6. 執行sql,接收傳回結果
7. 釋放資源
           

 具體實作執行個體

//1. 導入驅動jar包
//2.注冊驅動
Class.forName("com.mysql.jdbc.Driver");
//3.擷取資料庫連接配接對象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/One", "root", "pass");
//4.定義sql語句
String sql = "update account set balance = 500 where id = 1";
//5.擷取執行sql的對象 Statement
Statement stmt = conn.createStatement();
//6.執行sql
int count = stmt.executeUpdate(sql);
//7.處理結果
System.out.println(count);
//8.釋放資源
stmt.close();
conn.close();
           

 詳解對象

1. DriverManager:驅動管理對象
	* 功能:
	1. 注冊驅動:告訴程式該使用哪一個資料庫驅動jar
		static void registerDriver(Driver driver) :注冊與給定的驅動程式 DriverManager 。 
		寫代碼使用:  Class.forName("com.mysql.jdbc.Driver");
		通過檢視源碼發現:在com.mysql.jdbc.Driver類中存在靜态代碼塊
		static {
			try {
				java.sql.DriverManager.registerDriver(new Driver());
			} catch (SQLException E) {
				throw new RuntimeException("Can't register driver!");
			}
		}
		注意:mysql5之後的驅動jar包可以省略注冊驅動的步驟。
	2. 擷取資料庫連接配接:
		* 方法:static Connection getConnection(String url, String user, String password) 
		* 參數:
			url:指定連接配接的路徑
				* 文法:jdbc:mysql://ip位址(域名):端口号/資料庫名稱
				* 例子:jdbc:mysql://localhost:3306/db3
				* 細節:如果連接配接的是本機mysql伺服器,并且mysql服務預設端口是3306,則url可以簡寫為:jdbc:mysql:///資料庫名稱
			user:使用者名
			password:密碼 
2. Connection:資料庫連接配接對象
	1. 功能:
		1. 擷取執行sql 的對象
			* Statement createStatement()
			* PreparedStatement prepareStatement(String sql)  
		2. 管理事務:
			* 開啟事務:setAutoCommit(boolean autoCommit) :調用該方法設定參數為false,即開啟事務
			* 送出事務:commit() 
			* 復原事務:rollback() 
3. Statement:執行sql的對象
	1. 執行sql
		1. boolean execute(String sql) :可以執行任意的sql 了解 
		2. int executeUpdate(String sql) :執行DML(insert、update、delete)語句、DDL(create,alter、drop)語句
			* 傳回值:影響的行數,可以通過這個影響的行數判斷DML語句是否執行成功 傳回值>0的則執行成功,反之,則失敗。
		3. ResultSet executeQuery(String sql)  :執行DQL(select)語句
		
4. ResultSet:結果集對象,封裝查詢結果
		* boolean next(): 遊标向下移動一行,判斷目前行是否是最後一行末尾(是否有資料),如果是,則傳回false,如果不是則傳回true
		* getXxx(參數):擷取資料
			* Xxx:代表資料類型   如: int getInt() ,	String getString()
			* 參數:
				1. int:代表列的編号,從1開始   如: getString(1)
				2. String:代表列名稱。 如: getDouble("balance")
		
		* 注意:
			* 使用步驟:
				1. 遊标向下移動一行
				2. 判斷是否有資料
				3. 擷取資料
5. PreparedStatement:執行sql的對象
		1. SQL注入問題:在拼接sql時,有一些sql的特殊關鍵字參與字元串的拼接。會造成安全性問題
			1. 輸入使用者随便,輸入密碼:a' or 'a' = 'a
			2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a' 

		2. 解決sql注入問題:使用PreparedStatement對象來解決
		3. 預編譯的SQL:參數使用?作為占位符
		4. 步驟:
			1. 導入驅動jar包 mysql-connector-java-5.1.37-bin.jar
			2. 注冊驅動
			3. 擷取資料庫連接配接對象 Connection
			4. 定義sql
				* 注意:sql的參數使用?作為占位符。 如:select * from user where username = ? and password = ?;
			5. 擷取執行sql語句的對象 PreparedStatement  Connection.prepareStatement(String sql) 
			6. 給?指派:
				* 方法: setXxx(參數1,參數2)
					* 參數1:?的位置編号 從1 開始
					* 參數2:?的值
					如:pstmt.setString(1,"username");
			7. 執行sql,接受傳回結果,不需要傳遞sql語句
			8. 處理結果
			9. 釋放資源

		5. 注意:後期都會使用PreparedStatement來完成增删改查的所有操作
			1. 可以防止SQL注入
			2. 效率更高
           

使用JDBC操作資料庫

檢視jdbc庫中的user表資料:

//導包
        //注冊驅動
        Class.forName("com.mysql.cj.jdbc.Driver");
        //擷取資料庫連接配接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC","root","pass");
        //定義sql
        String sql = "select id,name from user";
        //擷取sql的執行對象Statement
        Statement stmt = conn.createStatement();
        //執行sql
        ResultSet rs = stmt.executeQuery(sql);
        while(rs.next()){
            String id = rs.getString("id");
            String name = rs.getString("name");
            System.out.println(id + " - " + name);
        }
        //關閉連接配接
        rs.close();
        stmt.close();
        conn.close();
           

往jdbc庫中的user表插入資料如“XXX”,“123”:

Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC", "root", "pass");
		//插入資料
        String sql = "insert into user values('XXX','123')";
		//更新資料
		//String sql = "update user set name = '456' where id = 'XXX'";
		//删除資料
		//String sql = "delete from user where id = 'XXX'";
        Statement stmt = conn.createStatement();
        int i = stmt.executeUpdate(sql);
        System.out.println(i);
        stmt.close();
        conn.close();
           

修改jdbc庫中user表的id = “XXX”對應的name為“456”:增删改的執行操作都是executeUpdate(),差別在sql語句而已,傳回的是修改行數;

而查的執行操作是executeQuery(),傳回的是一個結果集resultSet

jdbc操作事務

使用Connection對象來管理事務

        開啟事務:setAutoCommit(boolean autoCommit) :調用該方法設定參數為false,即開啟事務

        在執行sql之前開啟事務

        送出事務:commit() 當所有sql都執行完送出事務

        復原事務:rollback() 在catch中復原事務

/**
 * aaa向bbb轉賬 
 */
public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt1 = null;
        PreparedStatement pstmt2 = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC", "root", "pass");
            //開啟事務
            conn.setAutoCommit(false);
            String sql1 = "update balance set balance = ? where username = ?";
            String sql2 = "update balance set balance = ? where username = ?";
            pstmt1 = conn.prepareStatement(sql1);
            pstmt2 = conn.prepareStatement(sql2);
            pstmt1.setInt(1,500);
            pstmt1.setString(2,"aaa");
            pstmt2.setInt(1,1500);
            pstmt2.setString(2,"bbb");
            pstmt1.executeUpdate();
            pstmt2.executeUpdate();
        } catch (ClassNotFoundException | SQLException e) {
            try {
                //復原事務
                conn.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try {
                //送出事務
                conn.commit();
                pstmt1.close();
                pstmt2.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
           

druid操作資料庫

druid資料庫連接配接池,避免了jdbc頻繁建立關閉連接配接的過程。

使用步驟

//導包:druid-1.2.5.jar 、mysql-connector-java-8.0.22.jar
//定義配置
//加載配置
Properties properties = new Properties();
InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(is);
//擷取資料庫連接配接池
dataSource = DruidDataSourceFactory.createDataSource(properties);
//擷取連接配接
conn = dataSource.getConnection();
//往下與jdbc一樣
           

讀取jdbc庫中balance表的資料:

public static DataSource dataSource;
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try{
            //定義配置
            Properties properties = new Properties();
            InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
            //加載配置
            properties.load(is);
            //建立資料庫連接配接池
            dataSource = DruidDataSourceFactory.createDataSource(properties);
            //擷取連接配接
            conn = dataSource.getConnection();
            //定義sql
            String sql = "select username,balance from balance";
            //擷取執行對象
            pstmt = conn.prepareStatement(sql);
            //擷取結果集
            rs = pstmt.executeQuery();
            while(rs.next()){
                String username = rs.getString("username");
                String balance = rs.getString("balance");
                System.out.println(username + " " + balance);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                rs.close();
                pstmt.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
           

 往jdbc庫中的balance表插入資料行”ddd“,1000:

private static DataSource dataSource;
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        try{
            Properties pro = new Properties();
            InputStream is = DruidDemo2.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);
            dataSource = DruidDataSourceFactory.createDataSource(pro);
            conn = dataSource.getConnection();
            String sql = "insert into balance values(?,?)";
            ps = conn.prepareStatement(sql);
            ps.setString(1,"ddd");
            ps.setInt(2,1000);
            int i = ps.executeUpdate();
            System.out.println(i);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try{
                ps.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
           

增删查改跟jdbc大同小異,其思想就是對資料庫連接配接的池化。

druid處理事務

跟jdbc操作事務基本相似。

jdbcTemplate操作資料庫

使用步驟

//導包
commons-logging-1.2.jar
spring-beans-5.0.0.RELEASE.jar
spring-core-5.0.0.RELEASE.jar
spring-jdbc-5.0.0.RELEASE.jar
spring-tx-5.0.0.RELEASE.jar
           

 使用jdbcTemplate查詢資料庫資料:

private static DataSource dataSource;
    public static void main(String[] args) {
        try{
            //定義配置
            Properties pro = new Properties();
            InputStream is = JdbcTemplate1.class.getClassLoader().getResourceAsStream("druid.properties");
            //加載配置
            pro.load(is);
            //建立資料池連接配接
            dataSource = DruidDataSourceFactory.createDataSource(pro);
            //建立jdbcTemplate執行個體對象
            JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
            String sql = "select * from balance";
            //擷取結果集
            List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
            for (Map<String, Object> stringObjectMap : list) {
                System.out.println(stringObjectMap);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
           

 使用jdbcTemplate增删改資料:

private static DataSource dataSource;
    public static void main(String[] args) {
        try{
            Properties pro = new Properties();
            InputStream is = JdbcTemplate2.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);
            dataSource = DruidDataSourceFactory.createDataSource(pro);
            JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
            String sql = "insert into balance values(?,?)";
            int update = jdbcTemplate.update(sql,"eee",1000);
            //String sql = "update balance set balance = ? where username = ?";
            //int update = jdbcTemplate.update(sql, 100, "eee");
            //String sql = "delete from balance where username = ?";
            //int update = jdbcTemplate.update(sql, "eee");
            System.out.println(update);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
           

不需要手動關閉連接配接。