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

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

作者: 黑猴子的家 | 来源:发表于2019-03-01 11:13 被阅读1次

    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");
        }
    }
    

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/zzgruqtx.html