黑猴子的家:JDBC -> 自己封装通用的增删改查工具

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");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值