Java通过JDBC对MySQL数据库表增删改查(初步总结)
作为初学者水平有限,如有错误还请批评指正!
注:
1、案例中的引用大多来自java.sql.*,不能引用为mysql下的jdbc包
2、实验使用的数据库为MySQL,连接数据库的mysql-connection-java-5-7-1.jar包可自行到MySQL官网下载,也可至我主页下载。
3、源码中用于存放登录信息的jdbc.properties文件放于src/目录下
4、在源码中我对增删改(preparedStatementUpdate(String sql, Object …args))、查(customerForQuery(String sql, Object …args))、连接数据库(getConnection())、关闭资源(closeResource())等函数进行了封装,使其模块化、通用化
5、源码中PreparedStatementTest()、PreparedStatementQueryTest()
6、代码末端Customers类用于封装查询结果数据
7、查询操作目前一次只能接受一条记录
8、阅读过程中如出现问题可参考尚硅谷宋红康老师的JDBC教程(尚硅谷JDBC核心技术视频教程(康师傅带你一站式搞定jdbc)_哔哩哔哩_bilibili)
一、该案例的运行环境与条件
1、文件目录结构
2、jdbc.properties文件
该文件中等号两边不能出现空格
user=root
password=abc123
url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useUnicode=true
driverClass=com.mysql.jdbc.Driver
3、MySQL中Test数据库的customers表
二、源码解析
package com.Etui3.preparedstatement.crud;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Properties;
import org.junit.Test;
public class rePractice {
// 获取数据库连接通用函数
public Connection getConnection() throws Exception{
// 1、读取登录信息
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
// 2、预编译
Properties prop = new Properties();
prop.load(is);
String user = prop.getProperty("user");
String password = prop.getProperty("password");
String url = prop.getProperty("url");
String driverClass = prop.getProperty("driverClass");
// 3、注册驱动
Class.forName(driverClass);
// 4、建立连接
Connection conn = DriverManager.getConnection(url, user, password);
return conn;
}
// 关闭connection与PreparedStatement
public static void closeResource(Connection conn, PreparedStatement ps) {
try {
if(conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(ps != null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
// 关闭connection、PreparedStatement、ResultSet
public static void closeResource(Connection conn, PreparedStatement ps, ResultSet rs) {
try {
if(conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(ps != null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(rs != null) {
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 通用的增删改操作
/**
*
* @param sql 需要进行操作的SQL语句
* @param args 填充的占位符的数据集
* @throws Exception
*/
public void preparedStatementUpdate(String sql, Object ...args) throws Exception {
// 获取连接
Connection conn = getConnection();
// 预编译SQL语句
PreparedStatement ps = conn.prepareStatement(sql);
// 填充占位符
for(int i=0; i<args.length; i++) {
// 此处为i+1的原因为填充占位符的位置从1开始
ps.setObject(i + 1, args[i]);
}
// 执行PreparedStatement
ps.execute();
}
// 增删改查测试函数
public void PreparedStatementTest() throws Exception {
// 创建SQL语句
// 插入语句测试
String insertSQL = "insert into customers (name, email) values (?,?)";
preparedStatementUpdate(insertSQL, "张三", "zhangsan@qq.com");
// 插入语句测试
String updateSQL = "update customers set name = ? where email = ?";
preparedStatementUpdate(updateSQL, "李四", "zhangsan@qq.com");
// 插入语句测试
String deleteSQL = "delete from customers where name = ?";
preparedStatementUpdate(deleteSQL, "李四");
}
// 针对customers表的查询操作
/**
*
* @param sql 需要进行操作的SQL语句
* @param args 填充的占位符的数据集
* @throws Exception
*/
public Customers customerForQuery(String sql, Object ...args) throws Exception {
// 获取连接
Connection conn = getConnection();
// 预编译SQL语句
PreparedStatement ps = conn.prepareStatement(sql);
// 填充占位符
for(int i=0; i<args.length; i++) {
// 此处为i+1的原因为填充占位符的位置从1开始
ps.setObject(i + 1, args[i]);
}
// 执行编译,并接收查询结果
ResultSet rs = ps.executeQuery();
ResultSetMetaData rsmd = ps.getMetaData();// 获取被查询语句中列的数据
int fields = rsmd.getColumnCount(); // 获取列的数量,即查询字段的数量
// 迭代返回的结果集,并通过Customers类进行封装
if(rs.next()) {// next():判断结果集的下一条是否有数据,如果有数据返回true,没有数据返回false
Customers cust = new Customers();
for(int i=0; i<fields; i++) {
// 获取对应列的数据
Object customerValue = rs.getObject(i + 1);
// 获取每个列的列名
String customerName = rsmd.getColumnName(i + 1);
// 给cust类指定的customerName赋值customerValue
// 通过映射的方式获取指定列的信息
Field field = Customers.class.getDeclaredField(customerName);
field.setAccessible(true); // 设置该反射对象可访问标志为true
field.set(cust, customerValue); // 对该反射对象赋值
}
return cust;
}
return null; // 如果没有查询到数据返回null
}
// 查询操作测试函数
@Test
public void PreparedStatementQueryTest() throws Exception {
// SQL
String sql = "select id, name, email, birth from customers where id = ?";
// 查询
Customers cust = customerForQuery(sql, 21);
System.out.println(cust);
}
}
// Customers类,用于封装接收到的数据(查询返回的数据)
class Customers{
private int id;
private String name;
private String email;
private Date birth;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
public String toString() {
return "Customers [id=" + id + ", name=" + name + ", email=" + email + ", birth=" + birth + "]";
}
public Customers(int id, String name, String email, Date birth) {
super();
this.id = id;
this.name = name;
this.email = email;
this.birth = birth;
}
public Customers() {
super();
}
}