package com.xiao;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* @Author:令狐冲
* @Version:1.0
* @DateTime:2024/7/7 13:13
* @Since:jdk1.8
* @Description:
*/
public class Test {
public static void main(String[] args) {
Connection conn = null;
try {
// 1. 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2. 在Driver类中的static静态代码块中已经将驱动注册到驱动管理器中, 所以不需要重复注册
// 直接使用DriverManager拿到数据库连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/practice?useSSL=false", "root", "admin123");
System.out.println(conn);
// 3. 使用java对象作为数据载体增删改查
// 3.1 增
StuInfo stuInfo = new StuInfo();
stuInfo.setStuName("杰瑞");
stuInfo.setStuNum("100001");
stuInfo.setGender("男");
insert(conn, stuInfo);
// 3.2 删 -> 根据id删
deleteById(conn, 2);
// 3.3 改
updateById(conn, "tom", 1);
// 3.4 查
StuInfo si = findById(conn, 1);
System.out.println(si);
} catch (ClassNotFoundException | SQLException e) {
throw new RuntimeException(e);
} finally {
close(conn);
}
}
// 增
public static void insert(Connection connection, StuInfo stuInfo) {
// 1. 定义sql
String sql = "insert into stu_info values (?, ?, ?, ?)";
PreparedStatement ps = null;
try {
// 2. 获取预编译语句
ps = connection.prepareStatement(sql);
ps.setObject(1, stuInfo.getId());
ps.setObject(2, stuInfo.getStuName());
ps.setObject(3, stuInfo.getStuNum());
ps.setObject(4, stuInfo.getGender());
// 3. 执行sql
ps.execute();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
close(ps);
}
}
// 删
public static void deleteById(Connection connection, Integer id) {
String sql = "delete from stu_info where id = ?";
PreparedStatement ps = null;
try {
ps = connection.prepareStatement(sql);
ps.setObject(1, id);
ps.execute();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
close(ps);
}
}
// 改
public static void updateById(Connection connection, Object... args) {
String sql = "update stu_info set stu_name = ? where id = ?";
PreparedStatement ps = null;
try {
ps = connection.prepareStatement(sql);
ps.setObject(1, args[0]);
ps.setObject(2, args[1]);
ps.execute();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
close(ps);
}
}
// 查
public static StuInfo findById(Connection connection, Integer id) {
String sql = "select * from stu_info where id = ?";
PreparedStatement ps = null;
try {
ps = connection.prepareStatement(sql);
ps.setObject(1, id);
ResultSet resultSet = ps.executeQuery();
// 将结果集封装成一个StuInfo对象
List<StuInfo> stuInfos = getObjs(StuInfo.class, resultSet);
// 因为是根据唯一字段查的, 所以将集合中第一个stuInfo返回即可
return stuInfos.isEmpty() ? null : stuInfos.get(0);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
close(ps);
}
}
// 表与java对象的映射
public static <T> List<T> getObjs(Class<T> clazz, ResultSet resultSet) {
// 1. 要想把数据库记录和java对象做映射, java类的属性定义必须遵守规则; 数据库 stu_num -> 属性 stuNum
try {
// 2. 拿到结果集的列信息
ResultSetMetaData metaData = resultSet.getMetaData();
// 3. 拿到一共多少列
int columnCount = metaData.getColumnCount();
// 4. 定义一个集合, 用于存储映射出来的对象
List<T> ts = new ArrayList<>();
// 5. 遍历结果集
while (resultSet.next()) {
// 6. 定义一个T类型对象, 用于存储当前记录
T t = clazz.newInstance();
// 7. 遍历列
for (int i = 1; i <= columnCount; i++) {
// 8. 获得列名和列值
String columnName = metaData.getColumnName(i);
Object value = resultSet.getObject(i);
// 9. 将列名转化成属性名格式
String fieldName = tableColNameToFieldName(columnName);
// 10. 查找类对象的fieldName为属性名的属性
Field field = clazz.getDeclaredField(fieldName);
// 11. 开启访问权限
field.setAccessible(true);
// 12. 为t对象设置改属性的值
field.set(t, value);
}
// 13. 没一行遍历完成后得到一个完整的T对象, 将他放入集合之中
ts.add(t);
}
return ts;
} catch (SQLException | InstantiationException | IllegalAccessException | NoSuchFieldException e) {
throw new RuntimeException(e);
} finally {
close(resultSet);
}
}
// stu_name -> stuName
public static String tableColNameToFieldName(String colName) {
StringBuilder sb = new StringBuilder();
String[] sp = colName.split("_");
// 将第一个字符串先加进来
sb.append(sp[0]);
for (int i = 1; i < sp.length; i++) {
char firstChar = sp[i].charAt(0);
// 将除第一个字符的首字母大写
String s = sp[i].replaceFirst(firstChar + "", Character.toUpperCase(sp[i].charAt(0)) + "");
sb.append(s);
}
return sb.toString();
}
// 关闭资源
public static void close(AutoCloseable res) {
try {
res.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
使用原生JDBC方式实现对数据库的增删改查, 查询时能够将数据库记录映射到实体对象上
于 2024-07-07 14:50:22 首次发布