java中JDBC增刪改查操作詳解
前言
? ? ? ? 在上一篇博客我們介紹了JDBC的概念以及連接數(shù)據(jù)庫(kù)的五種方式JDBC概述及數(shù)據(jù)庫(kù)連接方式(數(shù)據(jù)庫(kù)連接方式推薦使用第五種),那么我們既然連接上數(shù)據(jù)庫(kù)了,那就要對(duì)數(shù)據(jù)進(jìn)行操作了,那么這一篇我們就來(lái)介紹常規(guī)的增刪改 查操作。
??
? ?
我們先看一遍步驟:? ??
這里不推薦使用Statement,兩個(gè)原因:
? ? ? ? ? ? ? ? 1.存在拼串操作,繁瑣。
? ? ? ? ? ? ? ? 2.存在sql注入問(wèn)題。
? ? ? ? 那我們使用誰(shuí)來(lái)代替Statement呢?
一、增刪改操作
? ? ? ? 操作前,我們先解決上面的問(wèn)題,我們使用PreparedStatement來(lái)代替Statement。
1.1 PreparedStatement介紹
可以通過(guò)調(diào)用 Connection 對(duì)象的 preparedStatement(String sql) 方法獲取 PreparedStatement 對(duì)象
PreparedStatement 接口是 Statement 的子接口,它表示一條預(yù)編譯過(guò)的 SQL 語(yǔ)句
PreparedStatement 對(duì)象所代表的 SQL 語(yǔ)句中的參數(shù)用問(wèn)號(hào)(?)來(lái)表示,調(diào)用 PreparedStatement 對(duì)象的 setXxx() 方法來(lái)設(shè)置這些參數(shù). setXxx() 方法有兩個(gè)參數(shù),第一個(gè)參數(shù)是要設(shè)置的 SQL 語(yǔ)句中的參數(shù)的索引(從 1 開(kāi)始),第二個(gè)是設(shè)置的 SQL 語(yǔ)句中的參數(shù)的值
?優(yōu)點(diǎn):
解決字符串拼串問(wèn)題,防止sql注入提高性能? ? ? ?
?1.2 增刪改操作
? ? ? ? 這里給出一個(gè)針對(duì)不同表的通用增刪改操作,拿著直接用就可以了。
//通用增刪改操作
public boolean updateInfo(String sql,Object...args){
Connection conn = null;
PreparedStatement ps = null;
boolean b = true;
try {
//1.建立連接
conn = JDBCUtils.getConnection();
//2.預(yù)編譯sql語(yǔ)句
ps = conn.prepareStatement(sql);
//3.填充占位符
for (int i = 0; i <args.length ; i++) {
ps.setObject(i+1,args[i]);
}
//4.執(zhí)行操作
b = ps.execute();
} catch (Exception e) {
e.printStackTrace();
} finally {
//5.關(guān)閉資源
JDBCUtils.close(conn,ps);
}
return b;
}
? ? ? ? ?是不是復(fù)制使用會(huì)報(bào)錯(cuò),這是因?yàn)椴┲靼褦?shù)據(jù)庫(kù)連接和關(guān)閉資源也封裝成了一個(gè)類JDBCUtils。
? ? ? ? 下面給出這個(gè)類的具體代碼:
? ? ? ? 配置文件就自己寫(xiě)吧,畢竟每個(gè)人的數(shù)據(jù)庫(kù)都不一樣。以及該導(dǎo)入的包自己動(dòng)動(dòng)手就行了。
public class JDBCUtils {
//連接
public static Connection getConnection(){
Connection conn = null;
try {
//1.加載配置文件
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
Properties prop = new Properties();
prop.load(is);
//2.讀取配置文件
String user = prop.getProperty("user");
String password = prop.getProperty("password");
String url = prop.getProperty("url");
String driverClass = prop.getProperty("driverClass");
//3.加載驅(qū)動(dòng)
Class.forName(driverClass);
//4.建立連接
conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
//關(guān)閉
public static void close(Connection conn, PreparedStatement ps){
try {
if (conn != null){
conn.close();
}
if (ps != null){
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//關(guān)閉帶resultset
public static void close(Connection conn, PreparedStatement ps , ResultSet rs){
try {
if (conn != null){
conn.close();
}
if (ps != null){
ps.close();
}
if (rs != null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
? 1.3 測(cè)試
? ? ? ? 我們來(lái)測(cè)試一下上面的代碼
? ? ? ? 這里有一張order表,里面有初始數(shù)據(jù):
???????????????????????
? ? ? ? ?然后我們通過(guò)上面提供的方法給他增加一條數(shù)據(jù):
public class Test {
public static void main(String[] args) {
Operation operation = new Operation();
String insertSql = "INSERT INTO `order`(order_id,order_name,order_date) VALUES (?,?,?)";
boolean b = operation.updateInfo(insertSql, 3, "CC", new Date(12312132));
if (!b){
System.out.println("操作成功!");
}else {
System.out.println("操作失??!");
}
}
}
? ? ? ? 控制臺(tái)打印輸出:
????????
? ? ? ? ?那么是不是已經(jīng)插入成功了呢,我們?nèi)?shù)據(jù)庫(kù)中看一下:
? ? ? ? ? 我們?SELECT * FROM `order`;
? ? ? ??
? ? ? ? 看來(lái)我們確實(shí)成功了!所以我們給出的方法還是沒(méi)有問(wèn)題。
二、查操作
? ? ? ? 接下來(lái)我們就是查操作了。
2.1?通用對(duì)不同表進(jìn)行一條數(shù)據(jù)查詢操作
public <T> T doQuery(Class<T> clazz,String sql,Object...args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//1.建立連接
conn = JDBCUtils.getConnection();
//2.預(yù)編譯sql語(yǔ)句
ps = conn.prepareStatement(sql);
//3.填充占位符
for (int i = 0; i <args.length ; i++) {
ps.setObject(i+1,args[i]);
}
//4.得到結(jié)果集ResultSet
rs = ps.executeQuery();
//5.得到結(jié)果集元數(shù)據(jù)
ResultSetMetaData rsdm = rs.getMetaData();
//6.通過(guò)rs得到列值,rsdm得到列名和列數(shù)
//得到列數(shù)
int columnCount = rsdm.getColumnCount();
if (rs.next()){
T t = clazz.getDeclaredConstructor().newInstance();
for (int i = 0; i <columnCount ; i++) {
//得到列值
Object columnvalue = rs.getObject(i + 1);
//得到列的別名
String columnLabel = rsdm.getColumnLabel(i + 1);
//通過(guò)反射給對(duì)象賦值
Field field = clazz.getDeclaredField(columnLabel);
//暴力反射
field.setAccessible(true);
field.set(t,columnvalue);
}
return t;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//關(guān)閉資源
JDBCUtils.close(conn,ps,rs);
}
return null;
}
? ? ? ? 老樣子,測(cè)試!
public class Test {
public static void main(String[] args) {
Operation operation = new Operation();
String sql = "SELECT order_id orderId,order_name orderName,order_date orderDate FROM `order` WHERE order_id = ?;";
Order order = operation.doQuery(Order.class, sql, 2);
System.out.println(order);
}
}
?控制臺(tái)輸出:
????????![]()
2.2?通用對(duì)不同表進(jìn)行多條數(shù)據(jù)查詢操作
public <T> List doQueryMore(Class<T> clazz,String sql,Object...args){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//1.建立連接
conn = JDBCUtils.getConnection();
//2.預(yù)編譯sql語(yǔ)句
ps = conn.prepareStatement(sql);
//3.填充占位符
for (int i = 0; i <args.length ; i++) {
ps.setObject(i+1,args[i]);
}
//4.得到結(jié)果集ResultSet
rs = ps.executeQuery();
//5.得到結(jié)果集元數(shù)據(jù)
ResultSetMetaData rsdm = rs.getMetaData();
//6.通過(guò)rs得到列值,rsdm得到列名和列數(shù)
//得到列數(shù)
int columnCount = rsdm.getColumnCount();
//創(chuàng)建集合
ArrayList<T> list = new ArrayList<>();
while (rs.next()){
T t = clazz.getDeclaredConstructor().newInstance();
for (int i = 0; i <columnCount ; i++) {
//得到列值
Object columnvalue = rs.getObject(i + 1);
//得到列的別名
String columnLabel = rsdm.getColumnLabel(i + 1);
//通過(guò)反射給對(duì)象賦值
Field field = clazz.getDeclaredField(columnLabel);
//暴力反射
field.setAccessible(true);
field.set(t,columnvalue);
}
list.add(t);
}
return list;
} catch (Exception e) {
e.printStackTrace();
} finally {
//關(guān)閉資源
JDBCUtils.close(conn,ps,rs);
}
return null;
}
? ? ? ? ?這一個(gè)測(cè)試就交給各位吧!
總結(jié)
到此這篇關(guān)于java中JDBC增刪改查操作詳解的文章就介紹到這了,更多相關(guān)java JDBC增刪改查內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java設(shè)計(jì)模式中組合模式應(yīng)用詳解
組合模式,又叫部分整體模式,它創(chuàng)建了對(duì)象組的數(shù)據(jù)結(jié)構(gòu)組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的訪問(wèn)具有一致性。本文將通過(guò)示例為大家詳細(xì)介紹一下組合模式,需要的可以參考一下2022-11-11
JDK8中的HashMap初始化和擴(kuò)容機(jī)制詳解
這篇文章主要介紹了JDK8中的HashMap初始化和擴(kuò)容機(jī)制,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
解決springboot與springcloud版本兼容問(wèn)題(附版本兼容表)
在基于spring boot搭建spring cloud時(shí),創(chuàng)建eureka后啟動(dòng)服務(wù)發(fā)生報(bào)錯(cuò),本文給大家介紹了解決springboot與springcloud版本兼容問(wèn)題的幾種方案,需要的朋友可以參考下2024-02-02
SpringBoot使用Validator進(jìn)行參數(shù)校驗(yàn)實(shí)戰(zhàn)教程(自定義校驗(yàn),分組校驗(yàn))
這篇文章主要介紹了SpringBoot使用Validator進(jìn)行參數(shù)校驗(yàn)(自定義校驗(yàn),分組校驗(yàn))的實(shí)戰(zhàn)教程,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2023-07-07
java利用mybatis攔截器統(tǒng)計(jì)sql執(zhí)行時(shí)間示例
這篇文章主要介紹了java利用mybatis攔截器統(tǒng)計(jì)sql執(zhí)行時(shí)間示例,該攔截器攔截mybatis的query和update操作,能統(tǒng)計(jì)sql執(zhí)行時(shí)間2014-03-03
SpringBoot項(xiàng)目使用slf4j的MDC日志打點(diǎn)功能(最新推薦)
這篇文章主要介紹了SpringBoot項(xiàng)目使用slf4j的MDC日志打點(diǎn)功能,本文通過(guò)示例代碼給大家介紹非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
實(shí)例解析Java的Jackson庫(kù)中的數(shù)據(jù)綁定
這篇文章主要介紹了Java的Jackson庫(kù)中的數(shù)據(jù)綁定,這里分為通常的簡(jiǎn)單數(shù)據(jù)綁定與全數(shù)據(jù)綁定兩種情況來(lái)講,需要的朋友可以參考下2016-01-01

