反射机制简化Dao层开发

本文参考了: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 tableNames = new ArrayList();
        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

你可能感兴趣的:(数据库,java,Dao层简化开发)