package PreparedStatementCURD;
import User.UserInfo;
import org.junit.Test;
import util.GetConnection;
import java.awt.*;
import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.*;
/**
* @author Vodka
* @date 2021/07//16:18
*/
/* ORM编程思想(Object relational mapping)
* 一个数据表对象一个java类,表中的一条记录代表一个对象,一个字段代表java类的属性
* java类型 SQL类型
* 1.boolean bit
* 2.byte tinyint
* 3.short smallint
* 4.int integer
* 5.long bigint
* 6.String char, varchar, longvarchar
* 7.byte array binary, varbinary
* 8.java.sql.Date Date
* 9.java.sql.Time Time
* 10.java.sql.Timestamp Timestamp
*/
public class QueryTest {
@Test
public void QTest() {
//当Java中自定义的类的属性名与数据库中的列名不一致时,可以在查询语句这里起(与自定义类属性名相同的)别名解决
String Qsql = "select * from student where Sex = ? and Sage < ?";
UserInfo [] Students = SelectQuery(Qsql, "1",100);
for(UserInfo Stu:Students){
if(Stu ==null) break;
System.out.println(Stu);
}
}
public static UserInfo[] SelectQuery(String QuerySQL, Object...args){
Connection conn = null;
PreparedStatement ps = null;
ResultSet resultSet = null;
UserInfo [] Students = new UserInfo[100]; //对象数组
try {
//建立数据库连接
conn = GetConnection.getConnection();
ps = conn.prepareStatement(QuerySQL);
for( int i= 0 ; i < args.length ; ++i){
ps.setObject(i+1,args[i]);
}
resultSet = ps.executeQuery(); //返回查询的结果集
//获取结果集中,描述数据类型的元数据:ResultSetMetaData
ResultSetMetaData rsmd = resultSet.getMetaData();
//获取数据库中数据类型列数的多少
int ColumnCount = rsmd.getColumnCount();
System.out.println("该表有"+ ColumnCount + "列。");
int index = 0 ;
//处理结果集
while(resultSet.next()){
//判断结果集下一节点是否有数据,若有返回true,指针下移,没有就返回false
//输出方法: 1.字符串拼接输出 2.Object [] data = new Object[] { Sno , Sname , Sex , Sage , InTime }
// 3. 将数据封装为一个对象,一个对象代表数据库表的一条记录,对象的属性就是一条记录中的一个字段
//创建一个自定义的UserInfo对象,通过两重循环来接收数据库查询返回的数据,要在while循环体里创建,
// 避免在循环体外面浪费内存空间(查询不到对象时)
UserInfo Student = new UserInfo();
for(int j = 0 ; j < ColumnCount; ++j){
//通过resultSet,遍历一条记录(一个对象)中的所有字段(属性)
Object ColumnValue = resultSet.getObject(j+1);
//通过元数据的getColumnName(),获取当前遍历的字段名,即当前列名
//通过元数据的getColumnLabel(), 获取当前字段(列)的别名
String ColumnLabel = rsmd.getColumnLabel(j+1);
//给对象指定属性(列名) ColumnName,再给该属性赋值:ColumnValue,
//根据列名,用反射机制获取该列名在UserInfo类中的数据类型
Field field = UserInfo.class.getDeclaredField(ColumnLabel);
//如果field是public类型,则不用setAccessible(true),
// 给(带有当前列名的)数据类型的属性赋值,并设置为相应对象的属性
field.setAccessible(true);
field.set(Student,ColumnValue);
}
//给对象数组添加对象
Students[index] = Student;
index++;
}
}catch(SQLException e){
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
} catch(ClassNotFoundException e){
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} finally{
try{
GetConnection.CloseResource(conn,ps,resultSet);
}catch(SQLException e){
e.printStackTrace();
}
}
//返回接收结果集的对象
return Students;
}
}
package PreparedStatementCURD;
import org.junit.Test;
import util.GetConnection;
import User.UserInfo;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* @description 针对不同表的通用的查询操作(泛型,反射)
* @author Vodka
* @date 2021/07//17:25
*/
public class DifferentTableOperation {
@Test
public void TableSQL(){
String sql = "select * from student where sex = ?";
List<UserInfo> Students = TableSearch(UserInfo.class,sql,"0");
for(UserInfo obj :Students){
System.out.println(obj);
}
}
//使用泛型的通用表查询
// 这个<T> T 可以传入任何类型的数据
// * 关于参数T
// * 第一个 表示是泛型
// * 第二个 表示返回的是T类型的数据
// * 第三个 限制参数类型为T
public <T> List<T> TableSearch(Class<T> TableClass, String sql, Object... arg) {
//这里利用反射的Class,用来动态获取具体的表的相应的类,再根据反射获得的类来创建相应的对象
Connection conn = null;
PreparedStatement ps = null;
ResultSet resultSet = null;
ArrayList<T> TList = null;
try {
conn = GetConnection.getConnection();
ps = conn.prepareStatement(sql);
//填充查询语句中的占位符
for (int index = 0; index < arg.length; ++index) {
ps.setObject(index + 1, arg[index]);
}
//执行查询操作,使用Result的实例对象来接收查询结果集
resultSet = ps.executeQuery();
//从结果集中获取数据库相应表的元数据(即数据类型),以及(元数据的个数)表的列数
ResultSetMetaData rsmd = resultSet.getMetaData();
int ColumnNums = rsmd.getColumnCount();
TList = new ArrayList<>();
//遍历结果集
while (resultSet.next()) {
//利用反射,动态获取相应表的类,再创建对象
T t = TableClass.getDeclaredConstructor().newInstance();
//遍历每一列,获取数据
for (int index = 0; index < ColumnNums; ++index) {
//通过ResultSet获取每一列的值
Object ColumnValue = resultSet.getObject(index + 1);
//通过rsmd,获取相应的列名,getColumnLabel()该方法既能获取列名,也可以获取列的别名
String ColumnLabel = rsmd.getColumnLabel(index + 1);
//利用反射机制,动态获取对象的相应类,再通过列名获取其在相应类中的属性域
Field field = t.getClass().getDeclaredField(ColumnLabel);
field.setAccessible(true); // 当要修改不是public的属性时,要设置为truee
field.set(t, ColumnValue);
}
//添加到表的集合对象中
TList.add(t);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
GetConnection.CloseResource(conn, ps, resultSet);
} catch (Exception e) {
e.printStackTrace();
}
}
//返回包含所有查询对象的集合
return TList;
}
}
//操作类,包含两个方法,一个是通用查询,一个是增删改通用
package Instrument;
import User.CetStu;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author Vodka
* @date 2021/07//15:53
*/
public class Operation {
//高内聚,低耦合,封装一个curd通用的函数,因为参数是不确定的,所以利用可变参数
public static int Update(String sql,Object...args) {
Connection conn = null;
PreparedStatement ps = null;
int ExecuteRS = 0;
try {
//建立连接
conn = GetConnection.getConnection();
//预编译
ps = conn.prepareStatement(sql);
for (int index = 0; index < args.length; index++) {
ps.setObject(index + 1, args[index]); //这里要注意两个变量下标起始值的不同
}
//执行sql语句
/*
* 对于ps.execute():
* 1.如果执行的是查询操作,查询成功就返回true
* 2.如果执行的是增删改,失败就返回false
* 对于ps.executeUpdate():
* 1.执行增删改成功,就返回DML操作的行数,失败就什么都不返回
*
* */
ExecuteRS = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (conn != null && ps != null) GetConnection.Close(conn, ps);
} catch (SQLException e) {
e.printStackTrace();
}
}
return ExecuteRS;
}
public static <T> List<T> TableSearch(Class<CetStu> TableClass, String sql,Object...arg) {
//这里利用反射的Class,用来动态获取具体的表的相应的类,再根据反射获得的类来创建相应的对象
Connection conn = null;
PreparedStatement ps = null;
ResultSet resultSet = null;
ArrayList<T> TList = null;
try {
conn = GetConnection.getConnection();
ps = conn.prepareStatement(sql);
//填充查询语句中的占位符
for (int index = 0; index < arg.length; ++index) {
ps.setObject(index + 1, arg[index]);
}
//执行查询操作,使用Result的实例对象来接收查询结果集
resultSet = ps.executeQuery();
//从结果集中获取数据库相应表的元数据(即数据类型),以及(元数据的个数)表的列数
ResultSetMetaData rsmd = resultSet.getMetaData();
int ColumnNums = rsmd.getColumnCount();
TList = new ArrayList<>();
//遍历结果集
while (resultSet.next()) {
//利用反射,动态获取相应表的类,再创建对象
T t = (T) TableClass.getDeclaredConstructor().newInstance();
//遍历每一列,获取数据
for (int index = 0; index < ColumnNums; ++index) {
//通过ResultSet获取每一列的值
Object ColumnValue = resultSet.getObject(index + 1);
//通过rsmd,获取相应的列名,getColumnLabel()该方法既能获取列名,也可以获取列的别名
String ColumnLabel = rsmd.getColumnLabel(index + 1);
//利用反射机制,动态获取对象的相应类,再通过列名获取其在相应类中的属性域
Field field = t.getClass().getDeclaredField(ColumnLabel);
field.setAccessible(true); // 当要修改不是public的属性时,要设置为truee
field.set(t, ColumnValue);
}
//添加到表的集合对象中
TList.add(t);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
GetConnection.CloseResource(conn, ps, resultSet);
} catch (Exception e) {
e.printStackTrace();
}
}
//返回包含所有查询对象的集合
return TList;
}
}