搞懂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
注冊驅動
獲取數據庫連接對象
定義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
返回值:影響的行數,可以通過這個影響的行數判斷DML語句是否執行成功返回值>0的則執行成功,反之,則失敗。
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)
- query的參數:RowMapper
- ? 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練習
需求:
代碼
?
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这一篇就够了!!!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bootstrap框架的日历(boots
- 下一篇: 如何使用Erdas进行监督分类