1、MyCRUDUtils 工具
package com.yinggu.utils;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
* 此类用于演示封装通用的增删改查工具方法
*
* @author:黑猴子的家
* @博客 :https://www.jianshu.com/u/37fd8e2dff4c
*
* 功能: 1、封装通用的增删改
* (1)适合任何的增删改sql语句
* (2)适合任何表
* 2、通用的查询
* (1)适合任何的查询sql语句
* (2)适合任何表
public class MyCRUDUtils {
/**
* 功能:通用的查询多条记录
*
* @param sql
* 待查询的sql
* @param clazz
* class对象
* @param objects
* 占位符
* @return 单条对象
* @throws Exception
*/
public static <T> List<T> queryMulti(
String sql, Class<T> clazz,
Object... objects) throws Exception {
// 1.获取连接
Connection connection = JDBCUtils.getConnection();
// 2.执行sql
// 2-1 获取预编译命令对象
PreparedStatement statement = connection.prepareStatement(sql);
// 2-2 设置占位符
for (int i = 0; i < objects.length; i++) {
statement.setObject(i + 1, objects[i]);
}
// 2-3 执行
ResultSet set = statement.executeQuery();
// 获取元数据结果集对象
ResultSetMetaData metaData = set.getMetaData();
List<T> list = new ArrayList<>();
while (set.next()) {
// 1.通过反射创建对应类型的对象
T t = clazz.newInstance();
/*
* 需求:
* 封装该条记录的对象,并为该位对象的属性赋值,然后返回
* 反射的步骤:
* 1.通过反射创建对应类型的对象
* T t = clazz.newInstance();
*
* 2.为属性赋值 遍历里面每一个属性:?列数、列名
*
* 假如,知道每一个列名(属性名) for(int i=1;i<=列数;i++){ //获取列名?
* Field field = clazz.getDeclaredFiled(属性名);
* field.setAccessible(true); field.set(t,set.get(列索引或列名)); }
* 3.返回该对象 return t;
*/
// 获取结果集的列数
int columnCount = metaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {// 遍历每个列(每个属性)
// 2.为属性赋值
// 获取列名?
String columnName = metaData.getColumnLabel(i);
// clazz.getDeclaredField(columnName);
//实体类和数据库,大小写最好一样,java是区分大小写的
//如果不一样, sql语句要起别名
Field field = clazz.getDeclaredField(columnName);
field.setAccessible(true);
field.set(t, set.getObject(columnName));
}
list.add(t);
}
JDBCUtils.closeConnection(set, statement, connection);
return list;
}
/**
* 功能:通用的查询单条记录
* orm -> object relation mapping
* 对象关系映射
*
* 表的设计 -> java 中类的设计
* 表中的每一条记录,相当于java中的一个对象
* 表中的每一个字段,相当于java中的每一个属性
*
* 需求
* 封装查询的单条记录的对象,并为该对象的属性赋值,然后返回
*
* @param sql
* 待查询的sql
* @param clazz
* class对象
* @param objects
* 占位符
*
* <T> T 泛型
* @return 单条对象
* @throws Exception
*/
public static <T> T querySingle(
String sql, Class<T> clazz,
Object... objects) throws Exception {
// 1.获取连接
Connection connection = JDBCUtils.getConnection();
// 2.执行sql
// 2-1 获取预编译命令对象
PreparedStatement statement = connection.prepareStatement(sql);
// 2-2 设置占位符
for (int i = 0; i < objects.length; i++) {
statement.setObject(i + 1, objects[i]);
}
// 2-3 执行
ResultSet set = statement.executeQuery();
// 获取元数据结果集对象
ResultSetMetaData metaData = set.getMetaData();
// 1.通过反射,创建对应类型的对象
T t = clazz.newInstance();
if (set.next()) {
/*
* 反射的步骤
* 需求: 封装该条记录的对象,并为该位对象的属性赋值,然后返回
* 反射的步骤:
* 1.通过反射创建对应类型的对象
* T t = clazz.newInstance();
*
* 2.为属性赋值 遍历里面每一个属性:?列数、列名
* 假如,知道每一个列名(属性名) for(int i=1;i<=列数;i++){ //获取列名?
*
* Field field = clazz.getDeclaredFiled(属性名);
* field.setAccessible(true);
* field.set(t,set.get(列索引或列名)); }
*
* 3.返回该对象 return t;
*
*/
// 获取结果集的列数
int columnCount = metaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {// 遍历每个列(每个属性)
// 2.为属性赋值
// 获取列名或者属性名
String columnName = metaData.getColumnLabel(i);
Field field = clazz.getDeclaredField(columnName);
//得到or激活
field.setAccessible(true);
//赋值
field.set(t, set.getObject(columnName));
}
}
JDBCUtils.closeConnection(set, statement, connection);
return t;
}
/**
* 功能:通用的增删改 注意:连接不用关闭
*
* @param connection
* 使用的连接对象
* @param sql
* 待执行的sql语句
* @param objects
* 占位符的参数列表
* @return 受影响的行数
* @throws Exception
*/
public static int update(
Connection connection,
String sql, Object... objects) throws Exception {
// 2.执行
// 2-1.获取预编译命令对象
PreparedStatement statement = connection.prepareStatement(sql);
// 2-2.设置占位符
for (int i = 0; i < objects.length; i++) {
statement.setObject(i + 1, objects[i]);
}
// 2-3.执行
int update = statement.executeUpdate();
// 3.关闭
JDBCUtils.closeConnection(null, statement, null);
return update;
}
/**
* 功能:通用的增删改
*
* @param sql
* 待执行的sql语句
* @param objects
* 占位符的参数列表
* @return 受影响的行数
* @throws Exception
*/
public static int update(String sql, Object... objects) throws Exception {
// 1.获取连接
Connection connection = JDBCUtils.getConnection();
// 2.执行
// 2-1.获取预编译命令对象
PreparedStatement statement = connection.prepareStatement(sql);
// 2-2.设置占位符
for (int i = 0; i < objects.length; i++) {
statement.setObject(i + 1, objects[i]);
}
// 2-3.执行
int update = statement.executeUpdate();
// 3.关闭
JDBCUtils.closeConnection(null, statement, connection);
return update;
}
}
2、ResultSetMetaData类
(1)可用于获取关于 ResultSet 对象中列的类型和属性信息的对象
(2)ResultSetMetaData meta = rs.getMetaData();
getColumnName(int column)
:获取指定列的名称
getColumnLabel(int column)
:获取指定列的别名
getColumnCount()
:返回当前 ResultSet
对象中的列数
getColumnTypeName(int column)
:检索指定列的数据库特定的类型名称 getColumnDisplaySize(int column)
:指示指定列的最大标准宽度,以字符为单位
isNullable(int column)
:指示指定列中的值是否可以为 null
isAutoIncrement(int column)
:指示是否自动为指定列进行编号,这样这些列仍然是只读的
3、ExamStudent 实体类
package com.yinggu.bean;
public class ExamStudent {
private int FlowID;
private int Type;
private String IDCard;
private String ExamCard;
private String StudentName;
private String Location;
private int Grade;
@Override
public String toString() {
return "ExamStudent [FlowID=" + FlowID +
", Type=" + Type +
", IDCard=" + IDCard +
", ExamCard=" + ExamCard+
", StudentName=" + StudentName +
", Location=" + Location +
", Grade=" + Grade + "]";
}
public ExamStudent() {
super();
}
public ExamStudent(
int flowID,
int type,
String iDCard,
String examCard,
String studentName,
String location,
int grade) {
super();
FlowID = flowID;
Type = type;
IDCard = iDCard;
ExamCard = examCard;
StudentName = studentName;
Location = location;
Grade = grade;
}
public int getFlowID() {
return FlowID;
}
public void setFlowID(int flowID) {
FlowID = flowID;
}
public int getType() {
return Type;
}
public void setType(int Type) {
this.Type = Type;
}
public String getIDCard() {
return IDCard;
}
public void setIDCard(String iDCard) {
IDCard = iDCard;
}
public String getExamCard() {
return ExamCard;
}
public void setExamCard(String examCard) {
ExamCard = examCard;
}
public String getStudentName() {
return StudentName;
}
public void setStudentName(String studentName) {
StudentName = studentName;
}
public String getLocation() {
return Location;
}
public void setLocation(String location) {
Location = location;
}
public int getGrade() {
return Grade;
}
public void setGrade(int grade) {
Grade = grade;
}
}
4、使用 MyCRUDUtils 工具做查询练习
(1) 单个查询
package com.yinggu.demo3;
import java.util.List;
import org.junit.Test;
import com.yinggu.bean.ExamStudent;
import com.yinggu.utils.MyCRUDUtils;
* @author:黑猴子的家
* @博客 :https://www.jianshu.com/u/37fd8e2dff4c
public class TestCRUD {
/**
* 查询单个
* @throws Exception
*/
@Test
public void testSelectSingle() throws Exception {
ExamStudent examstudent = MyCRUDUtils.querySingle(
"select * from examstudent where flowid = ? ",
ExamStudent.class, 1);
System.out.println(examstudent);
}
}
(2) 多个查询
package com.yinggu.demo3;
import java.util.List;
import org.junit.Test;
import com.yinggu.bean.ExamStudent;
import com.yinggu.utils.MyCRUDUtils;
public class TestCRUD {
/**
* 查询多个
* @throws Exception
*/
@Test
public void testSelectMulti() throws Exception {
List<ExamStudent> list = MyCRUDUtils.queryMulti(
"select * from examstudent where flowid >= ? ", ExamStudent.class,1);
for (ExamStudent examStudent : list) {
System.out.println(examStudent);
}
}
}
5、改写PreparedStatement 查询操作
使用MyCRUDUtils工具改写PreparedStatement 查询练习
package com.yinggu.demo3;
import java.util.Scanner;
import org.junit.Test;
import com.yinggu.bean.ExamStudent;
import com.yinggu.utils.MyCRUDUtils;
* 使用PreparedStatement实现增删改查 使用MyCRUDUtils
* @author:黑猴子的家
* @博客 :https://www.jianshu.com/u/37fd8e2dff4c
public class TestPreparedStatementByUtils {
Scanner input = new Scanner(System.in);
/*
* 此方法未使用 不用看, 看最后边两个方法
*/
@Test
public void testSelect() throws Exception {
System.out.println("请选择要输入的类型");
System.out.print("a、身份证号");
System.out.print("b、准考证号");
char key = input.next().charAt(0);
switch (key) {
case 'a':
selectByIdCard();
break;
case 'b':
selectByExamCard();
break;
default:
break;
}
}
/**
* 按准考证查询
* @throws Exception
*/
private void selectByExamCard() throws Exception {
System.out.println("请输入准考证号:");
String examCard = input.next();
String sql = "select * from examstudent where examCard=?";
ExamStudent student = MyCRUDUtils.querySingle(
sql, ExamStudent.class, examCard);
System.out.println(student);
}
/**
* 按身份证号查询 使用 了 MyCRUDUtils
* @throws Exception
*/
private void selectByIdCard() throws Exception {
System.out.println("请输入身份证号:");
String idCard = input.next();
// ------------------------以下为连接数据库的步骤-------------------
String sql = "select * from examstudent where idcard=?";
ExamStudent student = MyCRUDUtils.querySingle(
sql, ExamStudent.class, idCard);
System.out.println(student);
}
/**
* 使用了MyCRUDUtils
* @throws Exception
*/
@Test
public void testInsert() throws Exception {
System.out.println("请输入考生的详细信息");
System.out.print("Type:");
int type = input.nextInt();
System.out.print("IDCard:");
String idCard = input.next();
System.out.print("ExamCard:");
String examCard = input.next();
System.out.print("StudentName:");
String studentName = input.next();
System.out.print("location:");
String location = input.next();
System.out.print("Grade:");
int grade = input.nextInt();
// ------------------------以下为连接数据库的步骤-------------------
String sql = "insert into examstudent values(null,?,?,?,?,?,?)";
int update = MyCRUDUtils.update(
sql, type, idCard, examCard, studentName, location, grade);
System.out.println(update > 0 ? "succss" : "failure");
}
}