JdbcUtils类
通过用户输入的数据库链接,用户名,密码,对象的类型,查询语句
通过反射,jdbc创建出对象,并给对象的属性赋值,存入集合,返回这个集合给用户!
Student类
可以不在一个包,但是必须确保Student类型能传入JdbcUtils类
package com.situ.JDBC;
import java.sql.Date;
import java.time.LocalDate;
/**
* @author : 一只小海猪
* @date : 17:32 2021/11/10
*/
public class Student {
private String id ;
private String name;
private String sex;
private String classname;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", classname='" + classname + '\'' +
'}';
}
}
JdbcUtils类
package com.situ.JDBC;
import java.sql.*;
/**
* @author : 一只小海猪
* @date : 14:25 2021/11/10
*/
public class JdbcUtils {
public static final String driver = "com.mysql.cj.jdbc.Driver";
//获取连接数据库的对象
public static final Connection getConnection( String driver,String url, String user,String password) {
try {
Class.forName(driver);
Connection conn = DriverManager.getConnection(url,user,password);
return conn;
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
throw new RuntimeException("数据库连接失败!");
}
//重载获取连接数据库的对象
public static final Connection getConnection(String url, String user,String password){
return getConnection(driver,url,user,password);
}
//通过用户输入的查询sql语句,执行这个语句,返回查询结果集
public static final ResultSet selectFromSQL(Connection conn , String sql,Object[] args){
try {
PreparedStatement ps = conn.prepareStatement(sql);
if(args != null){
//给PreperedStatement实例设置参数
for(int i = 0 ; i<args.length ;i++){
ps.setObject(i+1,args[i]);
}
}
return ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
throw new RuntimeException("数据库查询失败!");
}
//更新函数,支持增删改
public static final int updateToSQL(Connection conn,String sql ,Object[] args){
try {
PreparedStatement ps = conn.prepareStatement(sql);
if(args != null){
//给PreperedStatement实例设置参数
for(int i = 0 ; i < args.length ; i++){
ps.setObject(i+1,args[i]);
}
}
return ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
throw new RuntimeException("操作数据失败!");
}
//通过用户输入的插入sql语句,执行这个语句,返回插入行数
public static final int insertToSQL(Connection conn, String sql,Object[] args){
//调用更新数据库函数
return updateToSQL(conn,sql,args);
}
//通过用户输入的sql语句,执行这个修改sql语句,返回修改行数
public static final int editToSQL(Connection conn, String sql,Object[] args){
//调用更新数据库函数
return updateToSQL(conn,sql,args);
}
//通过用户输入的删除sql语句,执行sql语句,返回删除结果
public static final int deleteFromSQL(Connection conn,String sql,Object[] args){
//调用更新数据库函数
return updateToSQL(conn,sql,args);
}
//获取用户输入的对象类型,将数据库中获取的数据封装成对象加入对象集合中,返回这个集合
public static <T> T query(Connection conn ,ResultSetHandler<T> handler, String sql , Object[] args){
ResultSet rs = selectFromSQL(conn,sql,args);
// if(rs!=null) {
// try {
// while (rs.next()) {
// Student s = new Student();
// s.setId(rs.getInt("id"));
// s.setName(rs.getString("name"));
// s.setSex(rs.getString("sex"));
// s.setBirthday(rs.getDate("birthday"));
// s.setClassname(rs.getString("classname"));
// System.out.println("成功读取 "+s);
// }
// } catch (SQLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
return handler.handle(rs);
}
public static final void closeConnection(Connection conn){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
BeanListHandler类
package com.situ.JDBC;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author : 一只小海猪
* @date : 18:43 2021/11/10
*/
public class BeanListHandler<T> implements ResultSetHandler<List<T>> {
private Class<T> clazz;
//获取用户输入的对象映射
public BeanListHandler(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public List<T> handle(ResultSet rs) {
int flag = 0 ;
List<T> list = new ArrayList<>();//存储对象
List<String> columnNames = new ArrayList<>();//存储数据库列名
Map<String , Method> map = new HashMap<>();//根据列名存储相应的set方法
Method[] methods = clazz.getDeclaredMethods();//反射获取set方法集合
try {
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();//列名数量
//获取元数组,并拼接方法,以键值对的方式存入map
for(int i =0 ;i<count;i++){
String columnName = rsmd.getColumnLabel(i+1);//获取列名
columnNames.add(columnName);//将列名存入列名集合
//拼接方法名
String methondName = "set" + columnName.substring(0,1).toUpperCase()+columnName.substring(1);
//将方法和列名以键值对的方式存入map
for(Method m:methods){
if(m.getName().equals(methondName)){
map.put(columnName,m);
break;
}
}
}
Constructor<T> con = clazz.getDeclaredConstructor();//反射获取对象的构造方法
if(rs != null){
while(rs.next()){
T t = con.newInstance(); //反射创建一个新对象
for(int i = 0 ; i<count ; i++){
String clonmnName = columnNames.get(i);//获取列名
Object obj = rs.getObject(clonmnName);//通过列名获取对应的属性值
Method m = map.get(clonmnName);//通过列名获取对应的set方法名
m.invoke(t,obj);//用对应的方法给对象的对应属性赋值
}
list.add(t);
flag++;
}
}
} catch (SQLException | NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("一共获取了"+flag+"个对象!");
return list;
}
}
ResultSetHandler接口
package com.situ.JDBC;
import java.sql.ResultSet;
/**
* @author : 一只小海猪
* @date : 17:28 2021/11/10
*/
public interface ResultSetHandler<T> {
T handle(ResultSet rs);
}
测试函数
package com.situ.JDBC;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import com.situ.JDBC.Student;
/**
* @author : 一只小海猪
* @date : 15:18 2021/11/10
*/
public class Test1 {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false";
String user = "root";
String password = "123456";
Connection conn = JdbcUtils.getConnection(url,user,password);
String sql1 = "select id ,`name`,sex,classname from t_student";
//这里只是简单统一使用了String类型,但是如果数据库和对象属性之间的类型不是String或者不相同,就需要对这些列进行特殊处理,将类型转换一致;
//如果查询出的结果表的列名与对象的set方法名字不一致,也需要对这些列进行取别名,使查询结果表的列名与对象的set方法名一致
List<Student> slist = JdbcUtils.query(conn,new BeanListHandler<Student>(Student.class),sql1,new Object[]{} );
for(Student s : slist ) {
System.out.println(s);
}
// ResultSet rs = JdbcUtils.selectFromSQL(conn,sql1,new Object[]{});
// if(rs!=null) {
// try {
// while (rs.next()) {
// Student s = new Student();
// s.setId(rs.getInt("id"));
// s.setName(rs.getString("name"));
// s.setSex(rs.getString("sex"));
// s.setClassname(rs.getString("classname"));
// System.out.println("成功读取 "+s);
// }
// } catch (SQLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
JdbcUtils.closeConnection(conn);
}
}

本文介绍了一个名为JdbcUtils的类,它利用JDBC连接数据库,接收用户输入的数据库连接信息、SQL查询和对象类型,通过反射动态创建和操作Student对象,将查询结果集转化为对象集合并返回。
3352

被折叠的 条评论
为什么被折叠?



