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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

【Java数据库】使用JDBC操作MySQL数据库、Batch批处理 、事务的概念

發(fā)布時(shí)間:2024/2/28 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java数据库】使用JDBC操作MySQL数据库、Batch批处理 、事务的概念 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
MySQL 數(shù)據(jù)庫(kù)的命令行操作

登陸操作mysql -hlocalhost –uroot –p123456
退出操作exit
數(shù)據(jù)庫(kù)操作建庫(kù):create database 庫(kù)名;
卸載庫(kù):drop database 庫(kù)名;
顯示所有數(shù)據(jù)庫(kù):show databases;
選擇庫(kù):use testjdbc;

表操作建表的sql語(yǔ)句
顯示庫(kù)中所有表:show tables;
顯示某個(gè)表的結(jié)構(gòu):describe testjdbc;
SQL操作select語(yǔ)句;insert語(yǔ)句; update語(yǔ)句; delete語(yǔ)句;
表操作DDL語(yǔ)句(create, alter, drop等);


Java使用JDBC

先下載一個(gè)mysql-connector-java-8.0.16.jar,其他版本也行

把這個(gè)jar添加到Java Build Path中(我為了避免以后移動(dòng)jar的時(shí)候找不到,就直接復(fù)制到項(xiàng)目路徑下了)


JDBC常用接口

(1)Driver接口

– Driver接口由數(shù)據(jù)庫(kù)廠家提供,對(duì)于java開發(fā)者而言,只需要使用
Driver接口就可以了。
– 在編程中要連接數(shù)據(jù)庫(kù),必須先裝載特定廠商的數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序。不
同的數(shù)據(jù)庫(kù)有不同的裝載方法。
– 驅(qū)動(dòng):就是各個(gè)數(shù)據(jù)庫(kù)廠商實(shí)現(xiàn)的Sun公司提出的JDBC接口。 即對(duì)
Connection等接口的實(shí)現(xiàn)類的jar文件
– 裝載MySql驅(qū)動(dòng)
? Class.forName("com.mysql.jdbc.Driver");
– 裝載Oracle驅(qū)動(dòng)
? Class.forName("oracle.jdbc.driver.OracleDriver");

(2)DriverManager接口
– DriverManager是JDBC的管理層,作用于用戶和驅(qū)動(dòng)程序之間。
– DriverManager跟蹤可用的驅(qū)動(dòng)程序,并在數(shù)據(jù)庫(kù)和相應(yīng)的驅(qū)動(dòng)程序
之間建立連接。

(3)Connection接口
– Connection與特定數(shù)據(jù)庫(kù)的連接(會(huì)話),在連接上下文中執(zhí)行 SQL
語(yǔ)句并返回結(jié)果。
– DriverManager的getConnection()方法建立在JDBC URL中定義的數(shù)
據(jù)庫(kù)Connection連接上
– 連接MYSQL數(shù)據(jù)庫(kù):

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc?serverTimezone=UTC", "root", "123456");// sql包中的接口

– 連接ORACLE數(shù)據(jù)庫(kù):

Connection con = DriverManager.getConnection("jdbc:oracle:thin:@host:port:databse","user","password");

注意:建立connection是比較耗時(shí)、耗資源的,(連接對(duì)象內(nèi)部其實(shí)包含的Socket對(duì)象,是一個(gè)遠(yuǎn)程的連接,比較耗時(shí)!這是Connection對(duì)象管理的一個(gè)要點(diǎn)!)經(jīng)過(guò)測(cè)試,在本機(jī)上建立鏈接,耗時(shí)235ms。在真正的開發(fā)中,為了提高效率,都會(huì)使用連接池來(lái)管理連接對(duì)象!

(4)Statement接口:用于執(zhí)行SQL語(yǔ)句、返回結(jié)果,是查詢操作的核心
– 用于執(zhí)行靜態(tài) SQL 語(yǔ)句并返回它所生成結(jié)果的對(duì)象。

– 三種Statement類:
? Statement:
– 由createStatement創(chuàng)建,用于發(fā)送簡(jiǎn)單的SQL語(yǔ)句。(不帶參數(shù)的)
? PreparedStatement:
– 繼承自Statement接口,由prepareStatement創(chuàng)建,用于發(fā)送含有一個(gè)或多個(gè)輸入?yún)?shù)的sql語(yǔ)句。PreparedStatement對(duì)象比Statement對(duì)象的效率更高,并且可以防止SQL注入。我們一般都用PreparedStatement.
? CallableStatement:
– 繼承自PreparedStatement 。由方法prePareCall創(chuàng)建,用于調(diào)用存儲(chǔ)過(guò)程。

– 常用的Statement方法:
? execute():運(yùn)行語(yǔ)句,返回是否有結(jié)果集。
? executeQuery():運(yùn)行select語(yǔ)句,返回ResultSet結(jié)果集。
? executeUpdate():運(yùn)行insert/update/delete操作,返回更新的行數(shù)。


Java中連接數(shù)據(jù)庫(kù)的使用示例

// 測(cè)試MySQL的連接 package cn.hanquan.jdbcTest;import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException;public class JDBCTest {public static void main(String[] args) {try {// 加載驅(qū)動(dòng)類Class.forName("com.mysql.cj.jdbc.Driver");// 建立鏈接Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc?serverTimezone=UTC", "root", "123456");// sql包中的接口System.out.println(conn);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}} }
  • 常見問(wèn)題(1)

The server time zone value ‘?й???’ is unrecognized or represents more than one time zone.

  • 解決方式

使用的數(shù)據(jù)庫(kù)是MySQL,驅(qū)動(dòng)是8.0.16,這是由于數(shù)據(jù)庫(kù)和系統(tǒng)時(shí)區(qū)差異所造成的。

在jdbc連接的url后面加上serverTimezone=GMT即可解決問(wèn)題:

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc?serverTimezone=UTC", "root", "123456");// sql包中的接口

如果需要使用gmt+8時(shí)區(qū),需要寫成GMT%2B8,否則會(huì)被解析為空。

再一個(gè)解決辦法就是:使用低版本的MySQL jdbc驅(qū)動(dòng),5.1.28不會(huì)存在時(shí)區(qū)的問(wèn)題。


  • 常見問(wèn)題(2)

Loading class ‘com.mysql.jdbc.Driver’. This is deprecated. The new driver class is ‘com.mysql.cj.jdbc.Driver’. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

  • 解決方式
    將Class.forName("com.mysql.jdbc.Driver");替換成Class.forName("com.mysql.cj.jdbc.Driver");即可

執(zhí)行SQL語(yǔ)句示例

  • 向表中插入一條數(shù)據(jù)
package cn.hanquan.jdbcTest;import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement;public class JDBCTest {public static void main(String[] args) {try {// 加載驅(qū)動(dòng)類Class.forName("com.mysql.cj.jdbc.Driver");// 建立鏈接Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc?serverTimezone=UTC","root", "123456");// 執(zhí)行語(yǔ)句Statement stat = conn.createStatement();String sql = "INSERT INTO user (id, pwd) VALUES ('testName', '666666');";stat.execute(sql);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}} }

實(shí)際開發(fā)中,使用Statement比較少,因?yàn)閰?shù)需要拼接字符串來(lái)做。處理參數(shù)不方便。
另外,使用Statement容易發(fā)生SQL注入的危險(xiǎn)。

為了避免注入,我們使用PreparedStatement

? execute():運(yùn)行語(yǔ)句,返回是否有結(jié)果集。
? executeQuery():運(yùn)行select語(yǔ)句,返回ResultSet結(jié)果集。
? executeUpdate():運(yùn)行insert/update/delete操作,返回更新的行數(shù)。

package cn.hanquan.jdbcTest;import java.sql.Connection; import java.sql.Date; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException;public class JDBCTest {public static void main(String[] args) {try {// 加載驅(qū)動(dòng)類Class.forName("com.mysql.cj.jdbc.Driver");// 建立鏈接Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc?serverTimezone=UTC","root", "123456");// 執(zhí)行語(yǔ)句String sql = "INSERT INTO user (id, pwd,date) VALUES (?,?,?);";// ?占位符 避免拼接字符串時(shí)SQL注入PreparedStatement ps = conn.prepareStatement(sql);ps.setString(1, "高淇");// 可以設(shè)置數(shù)據(jù)類型 參數(shù)索引從1開始計(jì)算ps.setString(2, "888888");ps.setDate(3, new Date(System.currentTimeMillis()));// import java.sql.Date;ps.execute();// 返回是否有結(jié)果集ps.setObject(1, "老高");// 不關(guān)心數(shù)據(jù)類型ps.setObject(2, "222222");ps.setObject(3, new Date(System.currentTimeMillis()));int count = ps.executeUpdate();// 返回影響的數(shù)據(jù)條數(shù)System.out.println(count);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}} }

  • 查找數(shù)據(jù),返回結(jié)果集

關(guān)于rs.next()的說(shuō)明

代碼

package cn.hanquan.jdbcTest;import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;public class JDBCTest {public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;try {// 加載驅(qū)動(dòng)類Class.forName("com.mysql.cj.jdbc.Driver");// 建立鏈接conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc?serverTimezone=UTC", "root","123456");// 執(zhí)行語(yǔ)句String sql = "select * from user";ps = conn.prepareStatement(sql);ResultSet rs = ps.executeQuery();// 返回結(jié)果集while (rs.next()) {// 游標(biāo) 返回trueSystem.out.print(rs.getObject(1) + " ");// 取出第1列System.out.print(rs.getObject(2) + " ");// 取出第2列System.out.print(rs.getObject(3) + " ");// 取出第3列System.out.println(rs.getObject(4) + " ");// 取出第4列}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();} finally {// 關(guān)閉順序:resultset->statement->connection 三個(gè)try catch一定要分開寫 否則一個(gè)異常后面都不執(zhí)行了try {if (ps != null) {ps.close();}} catch (SQLException e) {e.printStackTrace();}try {if (conn != null) {conn.close();}} catch (SQLException e) {e.printStackTrace();}}} }

輸出

老高 222222 110 2019-08-11 高淇 888888 119 2019-08-11
批處理 Batch:20000條數(shù)據(jù)大約2秒

對(duì)于大量的批處理,建議使用Statement,因?yàn)镻reparedStatement的預(yù)編譯空間有限,當(dāng)數(shù)據(jù)量特別大時(shí),會(huì)發(fā)生異常。

package cn.hanquan.jdbcTest;import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement;public class JDBCTest {public static void main(String[] args) {Connection conn = null;Statement stat = null;try {// 加載驅(qū)動(dòng)類Class.forName("com.mysql.cj.jdbc.Driver");conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc?serverTimezone=UTC", "root","123456");conn.setAutoCommit(false);// 把事務(wù)設(shè)置為手動(dòng)提交stat = conn.createStatement();for (int i = 0; i < 100; i++) {stat.addBatch("INSERT INTO user (id, pwd, phone, date) VALUES ('批量" + i + "', 'password', 100000, now());");}stat.executeBatch();conn.commit();// 提交事務(wù)} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();} finally {try {if (stat != null) {stat.close();}} catch (SQLException e) {e.printStackTrace();}try {if (conn != null) {conn.close();}} catch (SQLException e) {e.printStackTrace();}}} }


事務(wù)的概念

一組事務(wù)要么同時(shí)執(zhí)行成功,要么同時(shí)執(zhí)行失敗的SQL語(yǔ)句。是數(shù)據(jù)庫(kù)操作的一個(gè)執(zhí)行單元!

– 事務(wù)開始于:
? 連接到數(shù)據(jù)庫(kù)上,并執(zhí)行一條DML語(yǔ)句(INSERT、UPDATE或DELETE)。
? 前一個(gè)事務(wù)結(jié)束后,又輸入了另外一條DML語(yǔ)句。

– 事務(wù)結(jié)束于:
? 執(zhí)行COMMIT或ROLLBACK語(yǔ)句。
? 執(zhí)行一條DDL語(yǔ)句,例如CREATE TABLE語(yǔ)句;在這種情況下,會(huì)自動(dòng)執(zhí)行COMMIT語(yǔ)句。
? 執(zhí)行一條DCL語(yǔ)句,例如GRANT語(yǔ)句;在這種情況下,會(huì)自動(dòng)執(zhí)行COMMIT語(yǔ)句。
? 斷開與數(shù)據(jù)庫(kù)的連接。
? 執(zhí)行了一條DML語(yǔ)句,該語(yǔ)句卻失敗了;在這種情況中,會(huì)為這個(gè)無(wú)效的DML語(yǔ)句執(zhí)行ROLLBACK語(yǔ)句。

事務(wù)的四大特點(diǎn)(ACID)

– atomicity(原子性)
? 表示一個(gè)事務(wù)內(nèi)的所有操作是一個(gè)整體,要 么全部成功,要么全失敗;

– consistency(一致性)
? 表示一個(gè)事務(wù)內(nèi)有一個(gè)操作失敗時(shí),所有的更改過(guò)的數(shù)據(jù)都必須回滾到修改前的狀態(tài);

– isolation(隔離性)
? 事務(wù)查看數(shù)據(jù)時(shí)數(shù)據(jù)所處的狀態(tài),要么是另一并發(fā)事務(wù)修改它之前的狀態(tài),要么是另一事務(wù)修改它之后的狀態(tài),事務(wù)不會(huì)查看中間狀態(tài)的數(shù)據(jù)。

– durability(持久性)
? 持久性事務(wù)完成之后,它對(duì)于系統(tǒng)的影響是永久性的。

事務(wù)隔離級(jí)別從低到高:
– 讀取未提交(Read Uncommitted)
– 讀取已提交(Read Committed)
– 可重復(fù)讀(Repeatable Read)
– 序列化(serializable)

代碼示例:使用事務(wù),如果某一條語(yǔ)句執(zhí)行失敗,自動(dòng)回滾conn.rollback()

package cn.hanquan.jdbcTest;import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException;public class JDBCTest {public static void main(String[] args) throws SQLException {Connection conn = null;PreparedStatement ps1 = null;try {// 加載驅(qū)動(dòng)類Class.forName("com.mysql.cj.jdbc.Driver");conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc?serverTimezone=UTC", "root","123456");conn.setAutoCommit(false);// 將事務(wù)設(shè)置為手動(dòng)提交for (int i = 0; i < 10; i++) {ps1 = conn.prepareStatement("INSERT INTO user (id, pwd, phone, date) VALUES (?, ?, ?, now());");ps1.setObject(1, "auto" + i);ps1.setObject(2, "000000" + i);ps1.setObject(3, "10000" + i);ps1.execute();}conn.commit();// 提交事務(wù)} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();conn.rollback();// 執(zhí)行失敗 回滾 我測(cè)試了一下 如果不加這句話 也會(huì)自動(dòng)回滾 不知道為啥} finally {try {if (ps1 != null) {ps1.close();}} catch (SQLException e) {e.printStackTrace();}try {if (conn != null) {conn.close();}} catch (SQLException e) {e.printStackTrace();}}} }

總結(jié)

以上是生活随笔為你收集整理的【Java数据库】使用JDBC操作MySQL数据库、Batch批处理 、事务的概念的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。