(二十二)自定义简化版JDBC(Dbutils框架的设计思想)

目录


元数据概念

元数据 : 数据库、表、列的定义信息;( 就是一个信息的定义信息 ;)


DataBaseMetaData

DataBaseMetaData 数据库元数据对象 (- Connection.getDatabaseMetaData();)

    ·getURL(): 返回一个String类对象,代表数据的URL 。

    ·getUserName():返回连接当前数据库管理系统的用户名

    ·getDatabaseProductName(): 返回数据库的产品名称

    ·getDatabaseProduceVersion(): 返回数据库的版本号

    ·getDriverName(): 返回驱动程序的名称

    ·getDriverVersion(): 返回驱动程序的版本号

    ·isReadOnly() : 返回 boolean 值,指示数据库是否允许读操作 ;

ParameterMetaData

ParameterMetaData 参数的元数据

     ·PreparedStatement.getParameterMetaData():获得代表 sql参数的元数据的 ParamenterMetaData 对象


     ·getParameterCount() :获得指定sql语句的参数的个数

     ·getParameterType(int param) : 获得指定参数的sql类型 ;(mysql的驱动不支持)

ResultSetMetaData

ResultSetMetaData (从reasultSet上获取;代表ResultSet对象元数据)

    ·getColumnCount() :返回resultset对象的列数。

    ·getColumuName(int column) : 获得指定列的名称 ;

    ·getColumnTypeName(int column) : 获得指定列的类型 ;

编写简化版的JDBC

其实老方讲的就是明天要讲的dbutils的设计思路

在简化 查询 操作的时候,有一种思想在里面(策略模式,treeSet 也是这种模式)!

由于我们是框架设计者,在设计的时候,也不知道查询出来的是什么;

也不知道使用者,准备怎么处理结果集;

对于这种情况,我们就对外暴露一个接口,让使用者自己来写,他自己最清楚怎么操作结果集;

但是,我们也不能任何操作都让使用者自己写;

用你个查询,还要自己写个处理器;还不如使用原始的呢

因此,我们默认实现一些处理器接口的实现类,提供日常操作的实现类 ;


·BeanHandler 实现类 :

        构造器接受一个要返回对象的类型,方法内部使用反射进行赋值 ;

·BeanListHandler 实现类 :

        一样的思路;注意下结果集的游标,之前判断非空被移动到第一行了,再次查询之前需要将它移到表头,否则就从第二行开始查找了

O-R Mapping 概念

O-R Mapping简介

    ·什么是O-R Mapping 映射工具

        O: Object  对象 ;

        R:关系

        就是将对象关系映射到数据库里面 ;

    ·常用的O-R Mapping 映射工具

        ·Hibernate

        ·Ibatis

        ·Commons Dbutils(只是对JDBC 进行简单的封装)

自定义简化版JDBC


        --------------------- 处理器接口 -------------------------

//  对外暴露的 处理器 接口
interface ResultSetHandler {
    // 对 结果集 进行的操作
    Object handler(ResultSet resultSet);
}

        ----------------------- 已实现类 --------------------------------

// 已实现类 将结果集数据封装到 bean 中
class BeanHandler implements ResultSetHandler {

    private Class clazz;

    public BeanHandler(Class clazz) {
        this.clazz = clazz;
    }

    @Override
    public Object handler(ResultSet resultSet) {
        try {
            Object object = clazz.newInstance();
//            查询结果集中有多少行数据
            ResultSetMetaData meta = resultSet.getMetaData();
            int count = meta.getColumnCount();

            for (int i = 0; i < count; i++) {
//                获取每列的字段的名字
                String name = meta.getColumnName(i + 1);
                System.out.println(name);
//                获取字段列的值
                Object value = resultSet.getObject(name);
//        用反射技术,根据名字反射出字段
                Field field = clazz.getDeclaredField(name);
//                破除掉 private 限制
                field.setAccessible(true);
//       字段赋值
                field.set(object, value);
            }

            return object;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

    -------------------------- 已实现类 -----------------------------


//  已实现类 将结果集内容封装进 list 里面
class BeanListHandler implements ResultSetHandler {
    private Class clazz;

    public BeanListHandler(Class clazz) {
        this.clazz = clazz;
    }

    @Override
    public Object handler(ResultSet resultSet) {
        try {
            List list = new ArrayList();
//            需要将结果集游标往前移动一位,因为之前判断是否为空 往后移了一位
//            移到表头
            resultSet.beforeFirst();
            ResultSetMetaData meta = resultSet.getMetaData();
            int count = meta.getColumnCount();
            while (resultSet.next()) {
                Object bean = clazz.newInstance();
                for (int i = 0; i < count; i++) {
//                    获得字段名字
                    String name = meta.getColumnName(i + 1);
//                    反射出字段对象
                    Field field = clazz.getDeclaredField(name);
                    field.setAccessible(true);
//                    通过resultSET查出结果
                    Object value = resultSet.getObject(name);
                    field.set(bean, value);
                }
                list.add(bean);
            }

            return list;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

        --------------------------简化版JDBC框架类----------------------------

// 简化版JDBC框架类
public class SimpleJdbcUtils {

    /**
     * 先简化 增删改
     */
    public static int update(String sql, Object[] objects) {
//        获取连接
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcC3P0Utils.getConnection();
            statement = connection.prepareStatement(sql);

//            循环赋值
            for (int i = 0; i < objects.length; i++) {
                statement.setObject(i + 1, objects[i]);
            }

            return statement.executeUpdate();

        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        } finally {
            JdbcC3P0Utils.closedConnection(resultSet, statement, connection);
        }

    }


    /**
     * 简化 查询 操作
     */
    public static Object query(String sql, Object[] objects, ResultSetHandler handler) {

        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            connection = JdbcC3P0Utils.getConnection();
            statement = connection.prepareStatement(sql);

            for (int i = 0; i < objects.length; i++) {
                statement.setObject(i + 1, objects[i]);
            }

            resultSet = statement.executeQuery();

            if (!resultSet.next()) {
                return null;
            }

            return handler.handler(resultSet);

        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            JdbcC3P0Utils.closedConnection(resultSet, statement, connection);
        }
    }
}


        ---------------------- 测试简化版JDBC ----------------------

  //  增删改查 只需要3行代码。。
   @Test
    public void test1() {
        String sql = "insert into employee(name,money) values(?,?)";
        Object[] objects = {"qqqq", 12000};
        SimpleJdbcUtils.update(sql, objects);
    }

    @Test
    public void test2() {
        String sql = "update employee set money = ? where id = ?";
        Object[] objects = {"14000", 1};
        SimpleJdbcUtils.update(sql, objects);
    }

    @Test
    public void test3() {
        String sql = "delete from employee  where id = ?";
        Object[] objects = {2};
        SimpleJdbcUtils.update(sql, objects);
    }

    @Test
    public void test4() {
        String sql = "select * from employee  where id = ?";
        Object[] objects = {4};
        Employee employee = (Employee) SimpleJdbcUtils.query(sql, objects,new BeanHandler(Employee.class));
        System.out.println(employee.getId());
        System.out.println(employee.getMoney());
        System.out.println(employee.getName());
    }

    @Test
    public void test5() {
        String sql = "select * from employee ";
        Object[] objects = {};
        List<Employee> list = (List) SimpleJdbcUtils.query(sql, objects,new BeanListHandler(Employee.class));

        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i).getName()+" ");
            System.out.print(list.get(i).getId()+" ");
            System.out.print(list.get(i).getMoney()+" ");
            System.out.println();
        }



原文地址:https://www.cnblogs.com/young-youth/p/11665699.html