新年迈出Java后台服务器与数据库交互第一步2022最新通用Java8jdbc8连接mysql8数据库进行增删改查等基本操作详解(IDEA),jar包导入,图片等文件流,批量操作
文章目錄
- 一、JDBC下載與導入
- 二、獲取連接
- 三、PreparedStatement類操作數據庫
- 四、操作BLOB類型字段(圖片視頻等)
- 五、Batch批量插入
- 🙆🏻?♀?🙆🏻?♀?文末最新版jdbc jar包下載 🙆🏻?♀?🙆🏻?♀?
 
一、JDBC下載與導入
1、jar包下載
👇👇👇劃至文末有mysql-connector-java-8.0.27.jar的阿里云盤鏈接🔗,已經只留下有用的jar包文件了,下載即可用。
2、導入(IDEA)
①在工程下新建一個文件夾(可以命名為libs)
 
②將下載的jar包復制粘貼到該文件夾里面,然后右鍵該文件夾選擇"Add as Library"
 
二、獲取連接
1、創建配置文件jdbc.properties
配置信息如下:
user=用戶(root) password=數據庫密碼 url=jdbc:mysql://localhost:3306/test?useUnicode=true&character=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true driverClass=com.mysql.cj.jdbc.Driver說明:
url=jdbc:mysql://主機名稱:mysql服務端口號/數據庫名稱?參數=值&參數=值使用配置文件的好處:實現了代碼和數據的分離,如果需要修改配置信息,直接在配置文件中修改,不需要深入代碼;如果修改了配置信息,省去重新編譯的過程。
2、使用DriverManager獲取連接
import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.util.Properties;/*** @Author: Yeman* @Date: 2022-01-11-21:51* @Description:*/ public class jdbcLinked {public static void main(String[] args) throws Exception {//1、加載配置文件InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");Properties pros = new Properties();pros.load(is);//2、讀取配置信息String user = pros.getProperty("user");String password = pros.getProperty("password");String url = pros.getProperty("url");String driverClass = pros.getProperty("driverClass");//3、加載驅動Class.forName(driverClass);//4、獲取連接Connection conn = DriverManager.getConnection(url, user, password);System.out.println(conn);} }三、PreparedStatement類操作數據庫
1、PreparedStatement介紹
①通過調用獲取連接時生成的 Connection 對象的 preparedStatement(String sql) 方法獲取 PreparedStatement 對象。
②PreparedStatement 接口是 Statement 的子接口,它表示一條預編譯過的 SQL 語句。
③PreparedStatement 對象所代表的 SQL 語句中的參數用問號(?)來表示,調用PreparedStatement 對象的 setXxx() 方法來設置這些參數。setXxx() 方法有兩個參數,第一個參數是要設置的 SQL 語句中的參數的索引(從 1 開始),第二個是設置的 SQL 語句中的參數的值。
2、PreparedStatement vs Statement
①PreparedStatement 可以防止 SQL 注入問題,且提高代碼的可讀性和可維護性。
②PreparedStatement 能最大可能提高性能:
 DBServer會對預編譯語句提供性能優化。因為預編譯語句有可能被重復調用,所以語句在被DBServer的編譯器編譯后的執行代碼被緩存下來,那么下次調用時只要是相同的預編譯語句就不需要編譯,只要將參數直接傳入編譯過的語句執行代碼中就會得到執行。在statement語句中,即使是相同操作但因為數據內容不一樣,所以整個語句本身不能匹配,沒有緩存語句的意義,事實是沒有數據庫會對普通語句編譯后的執行代碼緩存。這樣每執行一次都要對傳入的語句編譯一次。(語法檢查,語義檢查,翻譯成二進制命令,緩存)
③PreparedStatement 便于操作BLOB類型字段(圖片視頻等文件數據)。
④PreparedStatement 更適于批量操作。
3、Java與SQL對應數據類型轉換表
4、使用PreparedStatement實現通用增、刪、改操作
這里所說的通用是針對于同一數據庫下的不同表或同一張表的不同DML。
①工具類(包括獲取連接,通用增刪改,關閉連接)
package utils;import java.io.InputStream; import java.sql.*; import java.util.Properties;/*** @Author: Yeman* @Date: 2022-01-12-14:34* @Description:操作數據庫的工具類*/public class jdbcUtils {/*** @Description 獲取數據庫連接* @Param []* @return java.sql.Connection**/public static Connection getSqlConnection() throws Exception{//1、加載配置文件InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");Properties pros = new Properties();pros.load(is);//2、讀取配置信息String user = pros.getProperty("user");String password = pros.getProperty("password");String url = pros.getProperty("url");String driverClass = pros.getProperty("driverClass");//3、加載驅動Class.forName(driverClass);//4、獲取連接Connection conn = DriverManager.getConnection(url, user, password);return conn;}/*** @Description 關閉連接和Statement資源* @Param [conn, ps]* @return void**/public static void closeResource(Connection conn, Statement ps){try {if (ps != null) ps.close();} catch (SQLException e) {e.printStackTrace();}try {if (conn != null) conn.close();} catch (SQLException e) {e.printStackTrace();}}//重載public static void closeResource(Connection conn, Statement ps, ResultSet res){try {if (ps != null) ps.close();} catch (SQLException e) {e.printStackTrace();}try {if (conn != null) conn.close();} catch (SQLException e) {e.printStackTrace();}try {if (res != null) res.close();} catch (SQLException e) {e.printStackTrace();}}/*** @Description 通用增刪改操作* @Param [sql, args]* @return void**/public static int updateDate(String sql, Object... args) {Connection conn = null;PreparedStatement ps = null;try {//獲取數據庫連接conn = getSqlConnection();//預編譯sql語句,獲取PreparedStatement實例ps = conn.prepareStatement(sql);//填充占位符for (int i = 0; i < args.length; i++) {ps.setObject(i + 1, args[i]);}//執行操作return ps.executeUpdate(); //返回操作的字段數,沒有則為0} catch (Exception e) {e.printStackTrace();}finally {//關閉資源closeResource(conn, ps);}return 0;} }②測試類
package jdbc;import utils.jdbcUtils;/*** @Author: Yeman* @Date: 2022-01-12-20:51* @Description:*/ public class comUpdate {public static void main(String[] args) {String sql = "update `order` set order_name = ? where order_id < ?";int bb = jdbcUtils.updateDate(sql, "BB", 4);System.out.println(bb);} }5、使用PreparedStatement實現通用查詢操作
這里所說的通用是針對同一數據庫下的不同表或者同一張表的不同查詢字段數。而要實現不同表的通用,則首先需要創建相應的不同Java類,即依據ORM思想。
/** ORM編程思想(object relational mapping)* 一個數據表對應一個Java類* 表中的一條記錄對應Java類的一個對象,一個字段對應Java類的一個屬性*/例如,我這里的數據庫中有一張customers表,因此我需要創建一個customers類。
package javabean;import java.sql.Date;/*** @Author: Yeman* @Date: 2022-01-12-21:08* @Description: customers表對應的Java類*/ public class Customers {private int id;private String name;private String email;private Date birth;public Customers() {}public Customers(int id, String name, String email, Date birth) {this.id = id;this.name = name;this.email = email;this.birth = birth;}public int getId() {return id;}public String getName() {return name;}public String getEmail() {return email;}public Date getBirth() {return birth;}@Overridepublic String toString() {return "Customers{" +"id=" + id +", name='" + name + '\'' +", email='" + email + '\'' +", birth=" + birth +'}';} }①工具類(連接與關閉),即調用上面的Utils
②通用查詢類
import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.util.ArrayList; import java.util.List;/*** @Author: Yeman* @Date: 2022-01-13-20:45* @Description:*/ public class Query {public static <T> List<T> Query(Class<T> clazz, String sql, Object... args) {ArrayList<T> ts = new ArrayList<>();Connection conn = null;PreparedStatement ps = null;ResultSet res = null;try {//獲取連接conn = jdbcUtils.getSqlConnection();//預編譯sql語句,獲取PreparedStatement實例ps = conn.prepareStatement(sql);//填充占位符for (int i = 0; i < args.length; i++) {ps.setObject(i + 1, args[i]);}//獲取結果集res = ps.executeQuery();//獲取結果集元數據ResultSetMetaData metaData = res.getMetaData();//獲取列數int columnCount = metaData.getColumnCount();//處理結果集數據while (res.next()){T t = clazz.newInstance();for (int i = 0; i < columnCount; i++) {Object value = res.getObject(i + 1); //獲取列值String columnLabel = metaData.getColumnLabel(i + 1); //獲取列的別名//通過反射實現Field field = clazz.getDeclaredField(columnLabel);field.setAccessible(true);field.set(t,value);}ts.add(t);}return ts;} catch (Exception e) {e.printStackTrace();}finally {//關閉資源jdbcUtils.closeResource(conn,ps,res);}return null;} }四、操作BLOB類型字段(圖片視頻等)
1、MySQL BLOB類型
MySQL中,BLOB是一個二進制大型對象,是一個可以存儲大量數據的容器,它能容納不同大小的數據。插入BLOB類型的數據必須使用PreparedStatement,因為BLOB類型的數據無法使用字符串拼接寫的。
MySQL的四種BLOB類型(除了在存儲的最大信息量上不同外,他們是等同的)
 
實際使用中根據需要存入的數據大小定義不同的BLOB類型。但需要注意的是,如果存儲的文件過大,數據庫的性能會下降。
如果在指定了相關的Blob類型以后,還報錯:xxx too large,那么需要在mysql的安裝目錄下,打開my.ini文件最后加上 max_allowed_packet=16M 。修改my.ini文件之后,需要重新啟動mysql服務才能生效。(找不到my.ini文件或者無法修改可以留言或者私信)
2、向數據表中增(改)大數據類型
package jdbc;import utils.jdbcUtils;import java.io.File; import java.io.FileInputStream; import java.sql.Connection; import java.sql.PreparedStatement;/*** @Author: Yeman* @Date: 2022-01-13-22:13* @Description:*/ public class Blob01 {public static void main(String[] args) throws Exception {//獲取連接Connection conn = jdbcUtils.getSqlConnection();//預編譯sql語句,獲取PreparedStatement實例String sql = "insert into customers(name,email,birth,photo) values(?,?,?,?)";PreparedStatement ps = conn.prepareStatement(sql);//填充占位符ps.setObject(1,"葉綠體");ps.setObject(2,"yelvti@163.com");ps.setObject(3,"2000-01-01");//即以流的形式讀取圖片文件后再添加到數據庫中(增和改類似)FileInputStream photo = new FileInputStream(new File("a.jpg"));ps.setObject(4,photo);//執行ps.execute();//關閉連接jdbcUtils.closeResource(conn,ps);} }3、從數據庫表中讀取大數據類型
package jdbc;import javabean.Customers; import utils.jdbcUtils; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.sql.*;/*** @Author: Yeman* @Date: 2022-01-13-22:34* @Description:這里以customer表為例,該表中有一photo圖片類型數據*/ public class Blob02 {public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;ResultSet res = null;InputStream is = null;FileOutputStream os = null;try {conn = jdbcUtils.getSqlConnection();String sql = "select id,name,email,birth,photo from customers where id = ?";ps = conn.prepareStatement(sql);ps.setObject(1,16);res = ps.executeQuery();while (res.next()){int id = res.getInt("id");String name = res.getString("name");String email = res.getString("email");Date birth = res.getDate("birth");Customers customers = new Customers(id, name, email, birth);System.out.println(customers);//以二進制流的形式讀取下來寫到本地Blob photo = res.getBlob("photo");is = photo.getBinaryStream();os = new FileOutputStream("zhuyin.jpg");byte[] buffer = new byte[1024];int len = 0;while ((len = is.read(buffer)) != -1){os.write(buffer,0,len);}}} catch (Exception e) {e.printStackTrace();}finally {try {if (is != null) is.close();} catch (IOException e) {e.printStackTrace();}try {if (os != null) os.close();} catch (IOException e) {e.printStackTrace();}jdbcUtils.closeResource(conn,ps,res);}} }五、Batch批量插入
1、批量執行SQL語句
當需要成批插入或者更新記錄時,可以采用Java的批量更新機制,這一機制允許多條語句一次性提交給數據庫批量處理。通常比單獨提交處理具有更高的效率。
JDBC 的批量處理語句包括下面三個方法:
 ①addBatch(String):添加需要批量處理的SQL語句或參數;
 ②executeBatch():執行批量處理語句;
 ③clearBatch():清空緩存的數據。
2、高效的批量插入
mysql服務器默認是關閉批量處理的,我們需要通過一個參數,讓mysql開啟批處理的支持。即將 ?rewriteBatchedStatements=true 補充在配置文件jdbc.properties的 url 的參數位置。
舉例:向數據表goods中插入20000條數據
package jdbc;import utils.jdbcUtils;import java.sql.Connection; import java.sql.PreparedStatement;/*** @Author: Yeman* @Date: 2022-01-14-12:09* @Description: 批量操作*/ public class goods {public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;try {long begin = System.currentTimeMillis();//獲取連接conn = jdbcUtils.getSqlConnection();//設置為不可自動提交conn.setAutoCommit(false);//預編譯sql語句,獲取PreparedStatement實例String sql = "insert into goods(name) value(?)";ps = conn.prepareStatement(sql);//填充占位符,使用Batch積攢要執行的sqlfor (int i = 1; i <= 1000000; i++) {ps.setString(1, "name" + i);//攢sqlps.addBatch();//執行(這里設置為每5000條執行一次)if (i % 5000 == 0){ps.executeBatch();//清空ps.clearBatch();}}//使其提交conn.commit();long end = System.currentTimeMillis();System.out.println("花費的時間為:" + (end - begin));} catch (Exception e) {e.printStackTrace();}finally {//關閉連接jdbcUtils.closeResource(conn,ps);}} }🙆🏻?♀?🙆🏻?♀?文末最新版jdbc jar包下載 🙆🏻?♀?🙆🏻?♀?
點擊最新版jdbc jar包下載(阿里云盤)
總結
以上是生活随笔為你收集整理的新年迈出Java后台服务器与数据库交互第一步2022最新通用Java8jdbc8连接mysql8数据库进行增删改查等基本操作详解(IDEA),jar包导入,图片等文件流,批量操作的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Canalys 报告:2023Q2 全球
- 下一篇: 消息称Meta重新开始招聘被裁员工 薪酬
