反射机制简化Dao层开发

来源:互联网 发布:ubuntu 1604 编辑:程序博客网 时间:2024/05/27 16:42

本文参考了:Java反射机制在DAO层的应用实例

所完成的功能是:由于Dao层有很多代码都是重复的,故想要使用几个类封装一下这个过程。

结果实现:完成Dao层的基础功能,更多的功能可以继续封装,也可以由开发者自己实现。代码在下边,需要的请自取。

基本思路是:
首先创建一个连接池存储数据库链接,再使用一个类 DataSourceDeal 封装了处理数据库的过程,完成包括取数据库连接,传sql语句,执行sql语句,处理结果集,关闭PreStatement和ResultSet,回收数据库连接等一系列动作。在处理除了select操作外其他操作都可以直接传入sql语句,然后执行就可以获得操作结果。需要处理select操作时,也仅仅只需重写getObjectFromResult()方法。最后使用一个类 DaoUtil 使用反射机制封装了将Entity转变成执行sql的过程,也就是说仅仅调用DaoUtil中的方法,提供一个Entity实例参数就可以完成数据库的处理了。 是不是很简单?
简单是有代价的,其实也不算代价,只是将一些编写数据库的常用的行为规范化起来而已。
1:Entity的成员变量中必须有一个标识号,名字必须以id结尾,而且不能只是id。
2:Entity中只能有一个以Id结尾的成员变量。
3:Entity中的成员变量由至少两个单词组成,单词用驼峰命名法。
4:数据库中字段命名和Entity一样。

主要部分代码(仅展示部分代码一部分完整版可去下方下载):

/**  *这部分代码主要功能是向数据库中插入一个bean对象  *  */// 完成对象的插入    public static Object insertObject(Object obj) {        StringBuilder sb = new StringBuilder("insert into ");        // 获取表名        Class<?> c = obj.getClass();        // 添加到sql语句中        sb.append(getTableNameFromClass(c));        // 获取所有的Field和Method        Method[] methods = c.getDeclaredMethods();        // 存放表名和值的容器        List<String> tableNames = new ArrayList<String>();        final List tableValues = new ArrayList();        // 填充容器        for (Method m : methods) {            String mName = m.getName();            if (mName.startsWith("get") && !mName.startsWith("getClass")) {                Object value = null;                try {                value = m.invoke(obj, null);                } catch (InvocationTargetException e) {                    e.printStackTrace();                } catch (IllegalAccessException e) {                    e.printStackTrace();                } catch (IllegalArgumentException e) {                    e.printStackTrace();                }                if(value == null)continue;                tableValues.add(value);                tableNames.add(getFieldFromMethod(mName));            }        }        // 填充sql语句的字段部分        for (int i = 0; i < tableNames.size(); i++) {            if (i == 0) {                sb.append("(");                sb.append(tableNames.get(i));            } else if (i == tableNames.size() - 1) {                sb.append(",");                sb.append(tableNames.get(i));                sb.append(")");            } else {                sb.append(",");                sb.append(tableNames.get(i));            }        }        sb.append(" values(");        // 填充sql语句的值部分        for (int i = 0; i < tableNames.size(); i++) {            sb.append('?');            if (i != tableNames.size() - 1)                sb.append(',');        }        sb.append(")");        // 已经完成sql语句的形成,下边创建处理对象        DataSourceDeal deal = new DataSourceDeal(sb.toString()) {            @Override            public Object getObjectFromResultSet(PreparedStatement ps,                    ResultSet rs) {                try {                    for (int i = 0; i < tableValues.size(); i++) {                        dealValue(ps, i + 1, tableValues.get(i));                    }                    return ps.executeUpdate();                } catch (SQLException e) {                    e.printStackTrace();                }                return -1;            }        };        // 执行sql语句        Object o = null;        try {            o = deal.doDeal();        } catch (SQLException e) {            e.printStackTrace();        }        System.out.println("返回信息:" + o);        return o;    }        /**     * 根据 value值的类型将 value 放到PreparedStatement指定位置中     *      * @param ps     * @param index     *            在sql语句中?的位置     * @param value     *            表中字段值     */    private static void dealValue(PreparedStatement ps, int index, Object value)            throws SQLException {        if (value instanceof String) {            ps.setString(index, (String) value);        } else if (value instanceof Date) {            try {                ps.setDate(index, new java.sql.Date(((Date) value).getTime()));            } catch (SQLException e) {                e.printStackTrace();                ps.setTimestamp(index,                        new java.sql.Timestamp(((Date) value).getTime()));            }        } else if (value instanceof Integer) {            ps.setInt(index, (Integer) value);        } else if (value instanceof Long) {            ps.setLong(index, (Long) value);        } else if (value instanceof Double) {            ps.setDouble(index, (Double) value);        }    }/**     * 从提供方法的名字获取到与之匹配的数据库字段名 ---即从set,get方法名称获取到数据库中字段名字     *      * @param MethodName     * @return     */    private static String getFieldFromMethod(String MethodName) {        String selectId = MethodName.substring(3);        return selectId;    }    /**     * 从Bean类名名获取到表名     *      * @param c     * @return     */    private static String getTableNameFromClass(Class c) {        String cName = c.getName();        return cName.substring(cName.lastIndexOf(".") + 1);    }

再看看调用的代码:

    @Test    public void test_insertObjects(){        Person person = new Person();        person.setPersonId(102L);//      person.setPersonBirthday(new Date());        person.setPersonName("zff罚单");        person.setPersonPassword("1945sdf");        DaoUtil.insertObject(person);    }

是不是很简单。 所有的Bean都可以按照这个方式插入数据库

文件和例子已上传,其中有例子:

http://download.csdn.net/download/zf_1024/9982492

阅读全文
0 0
原创粉丝点击