日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

搞懂JDBC这一篇就够了!!!

發布時間:2023/12/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 搞懂JDBC这一篇就够了!!! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JDBC

    • 資源共享
    • 一、概念
    • 為什么要用JDBC連接池?
    • 二、快速入門
      • 2.1 實例
      • 2.2 詳解各個對象
        • 1.DriverManager :驅動管理對象
        • 2.connection :數據庫連接對象
        • 3.statement :執行sql的對象
        • 4.Resultset :結果集對象
          • 查詢練習:
            • Emp類
            • 查詢方法
      • 5.Preparedstatement :執行sql的對象
        • 1. SQL注入問題
        • 解決方案
    • 三、JDBC工具類
      • 目的
      • 分析
      • 抽取一個方法釋放資源
      • 使用工具類
      • 登陸練習
        • 數據庫
        • 代碼
    • 四、JDBC控制事務
      • 轉賬實例
    • 五、數據庫連接池
      • 概念
      • 好處
      • 實現
      • 一、C3P0:數據庫連接池技術
        • 1.導入jar包
        • 2.定義配置文件
        • 3.創建核心對象
        • 4.獲取連接
      • 二、Druid:數據庫連接池實現技術
        • 1.寫入jar包
        • 2.定義配置文件
        • 3.獲取數據庫連接池對象:通過工廠類來獲取
        • 4.獲取連接
        • 5.實例
      • 三、Druid工具類
        • 實例
        • 測試
        • 查看數據庫
      • 四、Spring JDBC
        • 概念
        • 什么是jar包?
        • 步驟
          • 1.導入jar包
          • 2.創建JdbcTemplate對象。
          • 3.調用JdbcTemplate的方法來完成CRUD的操作
        • 實例
        • 查看數據庫數據
        • DML練習
          • 代碼
        • DQL練習
        • RowMapper的使用實例
          • 1.RowMapper的基本使用
            • 1.1 BeanPropertyRowMapper
            • 代碼如下
          • 代碼
          • 輸出結果

資源共享

最新c3p0所有jar包(完整版)
百度網盤下載鏈接:https://pan.baidu.com/s/1o9cBkMVb_kZmAksZjjoZYg 密碼:c7pr

阿里druid數據連接池jar包(完整版)
百度網盤地址:https://pan.baidu.com/s/1U9v5c_DindqXva92JeRVJQ 密碼:nquq

一、概念

JDBC全程:

Java Database Connectivity java數據庫連接

JDBC本質:其實是官方(SUN公司)定義的一套操作所有關系型數據庫的規則,即接口。各個數據庫廠商去實現這套接口,提供數據庫驅動jar包。我們可以使用這套接口(JDBC)編程,真正執行的代碼是驅動jar包中的實現類

為什么要用JDBC連接池?

? 對數據庫進行頻繁連接、開啟和關閉操作,會造成數據庫資源的浪費,十分影像數據庫的性能。

**一般我們在項目中都會抽取出一些公共設置數據庫連接的配置。項目在修改的時就可以很方便的去修改而不需要在無盡的代碼中,去修改所有的代碼。提高了軟件的可重用性**

二、快速入門

步驟:

  • 導入驅動jar包 mysql-connector-java-5.1.37-bin.jar

  • 右鍵 --> Add As Library
  • 注冊驅動

  • 獲取數據庫連接對象

  • 定義sql

  • ? 5.獲取執行sql語句的對象statement

    ? 6.執行sql,接收返回的結果

    ? 7.處理結果

    ? 8.釋放資源

    jar包資源

    https://cdn.mysql.com/archives/mysql-connector-java-5.1/mysql-connector-java-5.1.37.zip)

    2.1 實例

    package cn.caq.jdbc;import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement;public class JdbcDemo01 {public static void main(String[] args) throws Exception {//1.導入驅動jar包//2.注冊驅動Class.forName("com.mysql.jdbc.Driver");//3.獲取數據庫連接對象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db2", "root", "root");//4.定義sql語句String sql = "update account set balance = 1000 where id = 1";//5.獲取執行sql語句的對象 StatementStatement statement = connection.createStatement();//6.執行sqlint i = statement.executeUpdate(sql);//7.處理結果System.out.println(i);//8.釋放資源statement.close();connection.close();} }

    2.2 詳解各個對象

    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!”);
    ? }
    注意: mysq15之后的驅動jar包可以省略注冊驅動的步驟。

    ? 2.獲取數據庫連接

    Connection conn = DriverManager.getConnection(“jdbc:mysql://localhost:3306/db2”, “root”, “root”);

    url:指定連接的路徑

    細節∶如果連接的是本機mysql服務器,并且mysql服務默認端口是3306,則url可以簡寫為:jdbc:mysql///數據庫名

    user:用戶名

    password:密碼

    2.connection :數據庫連接對象

    功能:
    1.獲取執行sql 的對象
    statement createstatement()
    Preparedstatement preparestatement(string sql)

    ? 2.管理事務∶

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

    ? 提交事務: commit()

    ? 回滾事務:rollback()

    3.statement :執行sql的對象

    1.執行sql

  • boolean execute(String sql) : 可以執行任意的sql,了解即可
  • int executeUpdate(String sql) : 執行DML (insert、 update、 delete) 語句、DDL(create, alter、 drop)語句
    返回值:影響的行數,可以通過這個影響的行數判斷DML語句是否執行成功返回值>0的則執行成功,反之,則失敗。
  • ResultSet executeQuery(String sql) : 執行DQL (select)語句
  • 2.練習

    1.添加一條記錄

    2.修改記錄

    3.刪除記錄

    為了代碼健壯性,進行捕獲異常

    String sql = "update account set balance = 40 where id = 1"; String sql = "insert into account values(3,'ws',1002)"; String sql = "delete from account where id = 3";

    修改后的代碼

    package cn.caq.jdbc;import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement;public class JdbcDemo03 {public static void main(String[] args) {Connection conn = null;Statement stmt = null;try {//1.注冊驅動Class.forName("com.mysql.jdbc.Driver");//2.獲取連接對象conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "root");//3.定義sqlString sql = "insert into account values(3,'ws',1002)";//4.獲取執行sql對象stmt = conn.createStatement();//5.執行sqlint count = stmt.executeUpdate(sql);//6.處理結果System.out.println(count);if (count > 0){System.out.println("修改成功");}else {System.out.println("修改失敗");}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException throwables) {throwables.printStackTrace();} finally {if (stmt != null){try {stmt.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn != null){try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}} }

    4.Resultset :結果集對象

    結果集對象,封裝查詢結果

    ? 1.next();游標向下移動一行,判斷當前行是否是最后一行末尾

    它的返回值是布爾值

    ? 2.getXXX:獲取數據,XXX代表數據類型int getInt() String getString()

    ...//int :代表列的編號,從1開始 如:getString(1)//string: 代表列的名稱 如:getString("name") int id = res.getInt(1); String name = res.getString("name"); double balance = res.getDouble(3); System.out.println(id + "---" + name + "---" + balance); 結果為: 1---zs---40.0

    使用步驟:

    • 游標向下移動一行
    • 判斷是否有數據
    • 獲取數據

    正確用法

    while (res.next()){int id = res.getInt(1);String name = res.getString("name");double balance = res.getDouble(3);System.out.println(id + "---" + name + "---" + balance); }
    查詢練習:

    查詢表的數據封裝為對象,返回一個列表打印處理

    思路:

    ? 定義一個方法,查詢emp表的數據將其封裝為對象,然后裝載集合,返回

    ? 1.根據表的結構定義一個emp類

    ? 2.查詢的結果封裝為emp類的對象

    ? 3.定義方法public list findAll(){}查詢表中數據并封裝為集合

    Emp類
    package cn.caq.domain;import java.util.Date;/*** 封裝Emp表數據的Java Bean*/public class Emp {private int id;private String ename;private int job_id;private int mgr;private Date joindate;private double salary;private double bounds;private int dept_id;public int getId() {return id;}public String getEname() {return ename;}public void setEname(String ename) {this.ename = ename;}public void setId(int id) {this.id = id;}public int getJob_id() {return job_id;}public void setJob_id(int job_id) {this.job_id = job_id;}public int getMgr() {return mgr;}public void setMgr(int mgr) {this.mgr = mgr;}public Date getJoindate() {return joindate;}public void setJoindate(Date joindate) {this.joindate = joindate;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}public double getBounds() {return bounds;}public void setBounds(double bounds) {this.bounds = bounds;}public int getDept_id() {return dept_id;}public void setDept_id(int dept_id) {this.dept_id = dept_id;}@Overridepublic String toString() {return "Emp{" +"id=" + id +", ename='" + ename + '\'' +", job_id=" + job_id +'}';} }
    查詢方法
    package cn.caq.jdbc;import cn.caq.domain.Emp;import java.sql.*; import java.util.ArrayList; import java.util.List;/*** 定義一個方法,查詢emp表的數據將其封裝為對象,然后裝載集合,返回*/public class JdbcDemo06 {public static void main(String[]args){List<Emp> list = new JdbcDemo06().findall();System.out.println(list);}public List<Emp> findall() {Connection conn = null;Statement stmt = null;ResultSet res = null;ArrayList<Emp> list = null;try {//1.注冊驅動Class.forName("com.mysql.jdbc.Driver");//2.獲取連接對象conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "root");//3.定義sqlString sql = "select * from emp";//4.獲取執行sql對象stmt = conn.createStatement();//5.執行sqlres = stmt.executeQuery(sql);//6.處理結果Emp emp = null;list = new ArrayList<>();while (res.next()) {int id = res.getInt("id");String ename = res.getString("ename");int job_id = res.getInt("job_id");//創建emp對象,并賦值emp = new Emp();emp.setId(id);emp.setEname(ename);emp.setJob_id(job_id);//裝載集合list.add(emp);}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException throwables) {throwables.printStackTrace();} finally {if (stmt != null) {try {stmt.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (res != null) {try {res.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}return list;} }輸出結果為:[Emp{id=1001, ename='孫悟空', job_id=4}, Emp{id=1002, ename='盧俊義', job_id=3}, Emp{id=1003, ename='林沖', job_id=3}, Emp{id=1004, ename='唐僧', job_id=2}, Emp{id=1005, ename='李逵', job_id=4}, Emp{id=1006, ename='宋江', job_id=2}, Emp{id=1007, ename='劉備', job_id=2}, Emp{id=1008, ename='豬八戒', job_id=4}, Emp{id=1009, ename='羅貫中', job_id=1}, Emp{id=1010, ename='吳用', job_id=3}, Emp{id=1011, ename='沙僧', job_id=4}, Emp{id=1012, ename='李逵', job_id=4}, Emp{id=1013, ename='小白龍', job_id=4}, Emp{id=1014, ename='關羽', job_id=4}]

    5.Preparedstatement :執行sql的對象

    1. SQL注入問題

    用戶隨便輸入密碼:a’ or ‘a’ = 'a

    String sql = "select * from user where username = '"+username+"' and password = '"+password+"'"; System.out.println(sql);

    拼接后的sql:select * from user where username = ‘dafsdfda’ and password = ‘a’ or ‘a’ = 'a’

    請輸入username:
    fassag
    請輸入password
    a’ or ‘a’ = 'a
    Success!!!

    解決方案

    通過Preparedstatement :執行sql

    它是預編譯的SQL( 一次編譯、多次運行,省去了解析優化等過程,此外預編譯語句能防止sql注入 。)

    參數使用?作為占位符

    全部的流程為:

    步驃:
    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:?的值

    7、執行sql,接受返回結果,不需要傳遞sql語句

    8.處理結果

    9.釋放資源

    三、JDBC工具類

    目的

    簡化書寫

    分析

    ? 1.注冊驅動也抽取

    ? 2.抽取一個方法獲取連接對象

    ? 需求:不想傳遞參數(麻煩),還帶保證工具類的通用新

    ? 解決:properties配置文件

    url=jdbc:mysql:///db2 user=root password=root driver=com.mysql.jdbc.Driver

    ?

    抽取一個方法釋放資源

    package cn.caq.utils;import java.io.FileReader; import java.io.IOException; import java.net.URL; import java.sql.*; import java.util.Properties;/*** JDBC工具類*/ public class JDBCutils {private static String url;private static String user;private static String password;private static String driver;/*** 文件的讀取,只需要讀取一次即可拿到這些值。使用靜態代碼塊*/static {try {//讀取資源文件,獲取值//1.創建Properties集合類Properties pro = new Properties();//獲取src路徑下的文件方式--->ClassLoader 類加載器ClassLoader classLoader = JDBCutils.class.getClassLoader();URL res = classLoader.getResource("jdbc.properties");//得到文件的絕對路徑String path = res.getPath();//將絕對路徑轉化為字符串形式//FileReader用來讀用戶本地的文件pro.load(new FileReader(path));//2.加載文件//pro.load(new FileReader("src/jdbc.properties"));//3.獲取數據,賦值url = pro.getProperty("url");user = pro.getProperty("user");password = pro.getProperty("password");driver = pro.getProperty("driver");//4.注冊驅動Class.forName(driver);} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}/*** 獲取連接的方法*/public static Connection getConnection() throws SQLException {return DriverManager.getConnection(url, user, password);}/*** 釋放資源的方法*/public static void close(ResultSet rs, Statement stmt, Connection conn) {if (rs != null) {try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (stmt != null) {try {stmt.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}} }

    使用工具類

    package cn.caq.jdbc;import cn.caq.domain.Emp; import cn.caq.utils.JDBCutils;import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List;public class JdbcDemo07 {public static void main(String[] args) {List<Emp> list = new JdbcDemo07().findall2();System.out.println(list);}/*** 演示JDBC工具類*/public List<Emp> findall2() {Connection conn = null;Statement stmt = null;ResultSet res = null;ArrayList<Emp> list = null;try { // //1.注冊驅動 // Class.forName("com.mysql.jdbc.Driver"); // //2.獲取連接對象 // conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "root");conn = JDBCutils.getConnection();//3.定義sqlString sql = "select * from emp";//4.獲取執行sql對象stmt = conn.createStatement();//5.執行sqlres = stmt.executeQuery(sql);//6.處理結果Emp emp = null;list = new ArrayList<>();while (res.next()) {int id = res.getInt("id");String ename = res.getString("ename");int job_id = res.getInt("job_id");//創建emp對象,并賦值emp = new Emp();emp.setId(id);emp.setEname(ename);emp.setJob_id(job_id);//裝載集合list.add(emp);}} catch (SQLException throwables) {throwables.printStackTrace();} finally {JDBCutils.close(res,stmt,conn);}return list;} }

    登陸練習

    需求:

    ? 1.通過鍵盤錄入用戶名和密碼

    ? 2.判斷用戶是否登錄成功

    select * from user where username = “” and password = “”;

    如果這個sql有查詢結果,則成功反之失敗

    數據庫

    更改配置文件即可

    代碼

    package cn.caq.jdbc;import cn.caq.utils.JDBCutils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Scanner;/*** 需求:* 1.通過鍵盤錄入用戶名和密碼* 2.判斷用戶是否登錄成功*/public class JDBCDemo08 {public static void main(String[]args){//1.鍵盤錄入,接受用戶名和密碼Scanner scanner = new Scanner(System.in);System.out.println("請輸入username:");String username = scanner.nextLine();System.out.println("請輸入password");String password = scanner.nextLine();//2.調用方法 // JDBCDemo08 jdbcDemo08 = new JDBCDemo08(); // boolean login = jdbcDemo08.login(username, password);boolean flag = new JDBCDemo08().login(username, password);//3.判斷結果,輸出不同語句if (flag){System.out.println("Success!!!!!!");}else {System.out.println("username or passwd False!!!!!!!!");}}//登錄方法public boolean login(String username,String password){if (username == null || password == null){return false;}Connection conn = null;Statement stmt = null;ResultSet rs = null;//1.連接數據庫try {conn = JDBCutils.getConnection();//2.定義sqlString sql = "select * from user where username = '"+username+"' and password = '"+password+"'";//3.獲取執行sql的對象stmt = conn.createStatement();//4.執行sql語句rs = stmt.executeQuery(sql);//5.判斷return rs.next();//有下一行返回true} catch (SQLException throwables) {throwables.printStackTrace();} finally {JDBCutils.close(rs,stmt,conn);}return false;//如果出現異常返回false} }輸出結果為: 請輸入username: zs 請輸入password 123 Success!!!!!!請輸入username: sadfa 請輸入password 24323 username or passwd False!!!!!!!!

    四、JDBC控制事務

    1.事務:一個包含多個步驟的業務操作。如果這個業務操作被事務管理,則這多個步驟要么同時成功,要么同時失敗。

    2.操作:

    1.開后事務

    2.提交事務

    3.回滾事務

    3.使用connection對象來管理事務

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

    ? 在執行sql之前開啟事務

    ? 提交事務: commit()

    當所有sql都執行完提交事務

    ? 回滾事務: rollback()

    在catch中回滾事務

    轉賬實例

    package cn.caq.jdbc;import cn.caq.utils.JDBCutils;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException;/*** 事務操作*/public class JDBCDemo10 {public static void main(String[] args) {Connection conn = null;PreparedStatement pstmt1 = null;PreparedStatement pstmt2 = null;//1.獲取連接try {conn = JDBCutils.getConnection();//開啟事務conn.setAutoCommit(false);//2.定義sql//2.1張三 - 500String sql1 = "update account set balance = balance - ? where id = ?";//2.1李四 + 500String sql2 = "update account set balance = balance + ? where id = ?";//3.獲取執行sql對象pstmt1 = conn.prepareStatement(sql1);pstmt2 = conn.prepareStatement(sql2);//4.設置參數pstmt1.setDouble(1, 500);pstmt1.setInt(2, 1);pstmt2.setDouble(1, 500);pstmt2.setInt(2, 2);//5.執行sqlpstmt1.executeUpdate();//手動制造異常int i = 3 / 0;pstmt2.executeUpdate();//提交事務conn.commit();} catch (Exception throwables) {try {if (conn != null) {conn.rollback();}} catch (SQLException e) {e.printStackTrace();}throwables.printStackTrace();}} }如果中途出現任何異常,則觸發回滾操作!輸出結果為:java.lang.ArithmeticException: / by zeroat cn.caq.jdbc.JDBCDemo10.main(JDBCDemo10.java:43)

    金額沒有發生變化

    五、數據庫連接池

    概念

    其實就是一個容器(集合),存放數據庫連接的容器

    ? 當系統初始化好后,容器被初始化,容器中會申請一些連接對象,當用戶來訪問數據庫時,從容器中獲取連接對象,用戶訪問完后,會將連接對象返回給容器

    好處

    ? 節約資源

    ? 高效

    實現

    標準的接口:DataSource javax.sql包下的

    方法:

    獲取連接:getConnection()

    歸還連接:Connection.close().如果連接對象Connection是從連接池中獲取的,那么調用Connection.close()不在是關閉連接,而是歸還連接

    2.這個接口,一般不由人為實現,而是有數據庫廠商來實現

    ? C3P0:數據庫連接池技術

    ? Druid:數據庫連接池實現技術,由阿里提供

    一、C3P0:數據庫連接池技術

    步驟:

    1.導入jar包

    c3p0-0.9.5.2.jar

    mchange-commons-java-0.2.12.jar

    還有驅動jar包

    2.定義配置文件

    名稱:c3p0.properties或者c3p0-config.xml

    路徑:直接將文件放在src目錄下即可

    3.創建核心對象

    數據庫連接池對象 ComboPoolDataSource

    4.獲取連接

    getConnection

    了解即可

    二、Druid:數據庫連接池實現技術

    1.寫入jar包

    druid-1.e.9.jar

    2.定義配置文件

    是properties形式的(properties 性能)
    可以叫任意名稱,可以放在任意目錄下

    3.獲取數據庫連接池對象:通過工廠類來獲取

    DruidDataSourceFactory

    4.獲取連接

    getConnection

    5.實例

    package com.caq.datasource.druid; import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource; import java.io.InputStream; import java.sql.Connection; import java.util.Properties;public class DruidDemo01 {public static void main(String[] args) throws Exception {//1.導入Jar包//2.定義配置文件//3.加載配置文件Properties pro = new Properties();InputStream is = DruidDemo01.class.getClassLoader().getResourceAsStream("druid.properties");//得到輸出流pro.load(is);//獲取文件的路徑//4.獲取連接池對象DataSource ds = DruidDataSourceFactory.createDataSource(pro);//5.獲取連接Connection conn = ds.getConnection();System.out.println(conn);} }輸出結果為: 十月 20, 2021 10:32:02 下午 com.alibaba.druid.pool.DruidAbstractDataSource error 嚴重: maxIdle is deprecated 十月 20, 2021 10:32:03 下午 com.alibaba.druid.pool.DruidDataSource info 信息: {dataSource-1} inited com.mysql.jdbc.JDBC4Connection@6956de9

    三、Druid工具類

    1.定義一個類JDBCUtils

    2.提供靜態代碼塊加載配置文件,初始化連接池對象

    3.提供方法

    ? 1.獲取連接方法:通過數據庫連接池獲取

    ? 2.釋放資源

    ? 3.獲取連接池的方法

    實例

    詳細的注釋都寫在代碼中了!

    package com.caq.datasource.utils;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties;/*** Druid連接池工具類*/ public class JDBCUtils {//1.定義成員變量 DataSourceprivate static DataSource ds;static {try {//1.加載配置文件Properties pro = new Properties();pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));//2.獲取DataSourceds = DruidDataSourceFactory.createDataSource(pro);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}/*** 獲取連接*/public static Connection getConnection() throws SQLException {return ds.getConnection();}/*** 釋放資源*///第一種情況,執行DML語句,需要釋放connection數據庫連接對象和statementsql語句執行對象public static void close(Statement stmt, Connection conn) {if (stmt != null) {try {stmt.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn != null) {try {conn.close(); //歸還連接,不在是釋放了} catch (SQLException throwables) {throwables.printStackTrace();}}}//第二種情況,執行DQL語句,釋放三個資源,conn,stmt和resultSet結果集對象//這里寫一個方法重載即可public static void close(ResultSet rs, Statement stmt, Connection conn) {if (stmt != null) {try {stmt.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn != null) {try {conn.close(); //歸還連接,不在是釋放了} catch (SQLException throwables) {throwables.printStackTrace();}}}/*** 獲取連接池的方法*/public static DataSource getDataSource(){return ds;}}

    測試

    package com.caq.datasource.druid;import com.caq.datasource.utils.JDBCUtils;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException;/*** 使用新的工具類*/ public class DruidDemo02 {public static void main(String[] args) {/*完成添加的操作 給account表添加一條記錄*/Connection conn = null;PreparedStatement pstmt = null;try {//1.獲取連接conn = JDBCUtils.getConnection();//2.定義sqlString sql = "insert into account values(null,?,?)";//3.獲取pstmt對象pstmt = conn.prepareStatement(sql);//4.給sql賦值pstmt.setString(1, "王五");//給第一個參數賦值為王五pstmt.setDouble(2, 3000);//給第二個參數賦值為3000//5.執行sqlint count = pstmt.executeUpdate();System.out.println(count);} catch (SQLException throwables) {throwables.printStackTrace();} finally {//6.釋放資源JDBCUtils.close(pstmt,conn);}} }輸出結果為 十月 21, 2021 8:40:18 下午 com.alibaba.druid.pool.DruidAbstractDataSource error 嚴重: maxIdle is deprecated 十月 21, 2021 8:40:19 下午 com.alibaba.druid.pool.DruidDataSource info 信息: {dataSource-1} inited 1

    查看數據庫

    人直接傻掉,太強了,太tmd的好用了啊!!!!

    四、Spring JDBC

    概念

    Spring框架對JDBC的簡單封裝。提供了一個JDBCTemplate對象簡化JDBC的開發

    什么是jar包?

    學了這么久要是不知道什么是jar包那就尷尬了啊

    jar包就是別人已經寫好的一些類,然后將這些類進行打包,你可以將這些jar包引入你的項目中,然后就可以直接使用這些jar包中的類和屬性以及方法。 so ga!!!

    沒錯我現在才知道!!![🤦?]

    步驟

    1.導入jar包
    2.創建JdbcTemplate對象。

    它依賴于數據源DataSource

    JdbcTemplate template = new JdbcTemplate(ds);

    3.調用JdbcTemplate的方法來完成CRUD的操作
    • ? update():執行DML語句
    • ? queryforMap():查詢結果將結果集封裝為map集合,將列名作為key,將值作為value,將這條記錄封裝為一個map集合
      • 注意:這個方法查詢的結果集長度只能是1**
    • ? queryforList():查詢結果將結果集封裝為list集合
      • 注意:將每一條記錄封裝為一個Map集合,再將Map集合裝載到List集合中
    • ? query():查詢結果,將結果封裝為JavaBean對象
      • query的參數:RowMapper
        一般我們使用BeanPropertyRowMapper實現類。可以完成數據到JavaBean的自動封裝
      • new BeanPropertyRowiMapper<類型>(類型.class)
    • ? queryForObject:查詢結果,將結果封裝為對象
      • 一般用于聚合函數的查詢

    實例

    package com.caq.datasource.jdbctemplate;import com.caq.datasource.utils.JDBCUtils; import org.springframework.jdbc.core.JdbcTemplate;public class JdbctemplateDemo01 {public static void main(String[] args) {//1.導入jar包//2.創建jdbctemplate對象JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());//3.調用方法String sql = "update account set balance = 5000 where id = ?";int count = template.update(sql, 3);System.out.println(count);} }

    注意這個方法的使用,第一個參數是sql語句,第二個是經過preparedstatement封裝后的sql語句中的?的值

    查看數據庫數據

    DML練習

    需求:

  • 修改1號數據的salary 為1000
  • 添加一條記錄
  • 刪除剛才添加的記錄
  • 查詢id為1的記錄,將其封裝為Map集合
  • 查詢所有記錄,將其封裝為List
  • 查詢所有記錄,將其封裝為Emp對象的List集合
  • 查詢總記錄數
  • 代碼

    ?

    package com.caq.datasource.jdbctemplate; import com.caq.datasource.utils.JDBCUtils; import org.junit.Test; import org.springframework.jdbc.core.JdbcTemplate;public class JdbctemplateDemo02 {//Junit單元測試,可以讓方法獨立執行//1.獲取JDBCTemplate對象private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());/*** 1.修改1號數據的salary為10000*/@Testpublic void test1(){//2.定義sqlString sql = "update emp set salary = 10000 where id = 1001";//3.執行sqlint count = template.update(sql);System.out.println(count);}/*** 添加一條記錄*/@Testpublic void test2(){String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";//雙引只能嵌套單引int count = template.update(sql, 1015, "gj", 10);System.out.println(count);}/*** 刪除剛才添加的記錄*/@Testpublic void test3(){String sql = "delete from emp where id = ?";int count = template.update(sql, 1015);System.out.println(count);}}

    分別對三個單元進行測試

    結果如下:

    DQL練習

    JavaBeans是Java中一種特殊的類,可以將多個對象封裝到一個對象(bean)中。 特點是可序列化,提供無參構造器,提供getter方法和setter方法訪問對象的屬性

    RowMapper的使用實例

    1.RowMapper的基本使用

    從數據庫查詢出來的記錄全都被保存在ResultSet結果集中,我們需要將結果集中的數據一條條地獲取并設置到具體的實體類上,如此,該實體類才能在接下來的程序中使用。然而問題是,每次都要這么操作實在是太麻煩了,Spring就不應該提供什么功能來替我們做這些事情嗎?RowMapper就是實現這個功能的

    1.1 BeanPropertyRowMapper

    當查詢數據庫返回的是多列數據,且你需要將這些多列數據映射到某個具體的實體類上

    代碼如下
    @Overridepublic Student getStudentByName2(String name) {String sql = "select name, gender from test_student where name = ?";return this.jdbcTemplate.queryForObject(sql, new Object[]{name},new BeanPropertyRowMapper<>(Student.class));}@Overridepublic List<Student> getStudentsByName2(String name) {String sql = "select name, gender from test_student where name = ?";return this.jdbcTemplate.query(sql, new Object[]{name},new BeanPropertyRowMapper<>(Student.class));}
    代碼
    package com.caq.datasource.jdbctemplate; import com.caq.datasource.utils.JDBCUtils; import com.caq.datasource.domain.Emp; import org.junit.Test; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import java.util.List; import java.util.Map;public class JdbctemplateDemo02 {//Junit單元測試,可以讓方法獨立執行//1.獲取JDBCTemplate對象private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());/*** 1.修改1號數據的salary為10000*/@Testpublic void test1(){//2.定義sqlString sql = "update emp set salary = 10000 where id = 1001";//3.執行sqlint count = template.update(sql);System.out.println(count);}/*** 添加一條記錄*/@Testpublic void test2(){String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";//雙引只能嵌套單引int count = template.update(sql, 1015, "gj", 10);System.out.println(count);}/*** 刪除剛才添加的記錄*/@Testpublic void test3(){String sql = "delete from emp where id = ?";int count = template.update(sql, 1015);System.out.println(count);}/*** 4.查詢id為1001的記錄,將其封裝為Map集合* 注意:這個方法查詢的結果集長度只能是一*/@Testpublic void test4(){String sql = "select * from emp where id = ?";Map<String, Object> map = template.queryForMap(sql, 1001);System.out.println(map);//{id=1001, ename=孫悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}}/*** 5.查詢所有記錄,將其封裝為List*/@Testpublic void test5(){String sql = "select * from emp";List<Map<String, Object>> list = template.queryForList(sql);//iter快捷鍵可快速生成循環for (Map<String, Object> stringObjectMap : list) {System.out.println(stringObjectMap);}}/*** 6.查詢所有記錄,將其封裝為Emp對象的List集合*/@Testpublic void test6(){String sql = "select * from emp";//可以自己實現接口,也可以用別人實現號的類BeanPropertyRowMapperList<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));for (Emp emp:list){System.out.println(emp);}}/*** 7.查詢總記錄數*/@Testpublic void test7(){String sql = "select count(id) from emp";Long total = template.queryForObject(sql, Long.class);System.out.println(total);//14} }
    輸出結果
    com.caq.datasource.jdbctemplate.JdbctemplateDemo02,test6 十月 21, 2021 10:51:47 下午 com.alibaba.druid.pool.DruidAbstractDataSource error 嚴重: maxIdle is deprecated 十月 21, 2021 10:51:48 下午 com.alibaba.druid.pool.DruidDataSource info 信息: {dataSource-1} inited Emp{id=1001, ename='孫悟空', job_id=4, mgr=1004, joindate=2000-12-17 00:00:00.0, salary=10000.0, bounds=null, dept_id=20} Emp{id=1002, ename='盧俊義', job_id=3, mgr=1006, joindate=2001-02-20 00:00:00.0, salary=16000.0, bounds=null, dept_id=30} Emp{id=1003, ename='林沖', job_id=3, mgr=1006, joindate=2001-02-22 00:00:00.0, salary=12500.0, bounds=null, dept_id=30} Emp{id=1004, ename='唐僧', job_id=2, mgr=1009, joindate=2001-04-02 00:00:00.0, salary=29750.0, bounds=null, dept_id=20} Emp{id=1005, ename='李逵', job_id=4, mgr=1006, joindate=2001-09-28 00:00:00.0, salary=12500.0, bounds=null, dept_id=30} Emp{id=1006, ename='宋江', job_id=2, mgr=1009, joindate=2001-05-01 00:00:00.0, salary=28500.0, bounds=null, dept_id=30} Emp{id=1007, ename='劉備', job_id=2, mgr=1009, joindate=2001-09-01 00:00:00.0, salary=24500.0, bounds=null, dept_id=10} Emp{id=1008, ename='豬八戒', job_id=4, mgr=1004, joindate=2007-04-19 00:00:00.0, salary=30000.0, bounds=null, dept_id=20} Emp{id=1009, ename='羅貫中', job_id=1, mgr=null, joindate=2001-11-17 00:00:00.0, salary=50000.0, bounds=null, dept_id=10} Emp{id=1010, ename='吳用', job_id=3, mgr=1006, joindate=2001-09-08 00:00:00.0, salary=15000.0, bounds=null, dept_id=30} Emp{id=1011, ename='沙僧', job_id=4, mgr=1004, joindate=2007-05-23 00:00:00.0, salary=11000.0, bounds=null, dept_id=20} Emp{id=1012, ename='李逵', job_id=4, mgr=1006, joindate=2001-12-03 00:00:00.0, salary=9500.0, bounds=null, dept_id=30} Emp{id=1013, ename='小白龍', job_id=4, mgr=1004, joindate=2001-12-03 00:00:00.0, salary=30000.0, bounds=null, dept_id=20} Emp{id=1014, ename='關羽', job_id=4, mgr=1007, joindate=2002-01-23 00:00:00.0, salary=13000.0, bounds=null, dept_id=10}Process finished with exit code 0

    總結

    以上是生活随笔為你收集整理的搞懂JDBC这一篇就够了!!!的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。