jdbchandler

public class JdbcHandler {
    private JdbcHandler() {

    }

    /**
     * 专门用来完成需要返回自增主键的insert操作
     *
     * @param sql
     * @param keyCoulmnName 主键列
     * @param params
     * @return
     */
    public static int insert(String sql, String keyCoulmnName, Object... params) {
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            con = DBUtils.getConnection();
            ps = con.prepareStatement(sql, new String[]{keyCoulmnName});
            //设置占位符参数
            setParameter(ps, sql, params);
            ps.executeUpdate();
            rs = ps.getGeneratedKeys();
            if (rs.next()) {
                return rs.getInt(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtils.closeResource(con, ps, rs);
        }
        return -1;
    }


    /**
     * 定义DML操作
     *
     * @param sql
     * @param params
     * @return 返回受影响的行数
     */
    public static int update(String sql, Object... params) {
        Connection con = null;
        PreparedStatement ps = null;
        try {
            con = DBUtils.getConnection();
            ps = con.prepareStatement(sql);
            //设置占位符参数
            setParameter(ps, sql, params);
            return ps.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtils.closeResource(con, ps,null );
        }
        return -1;
    }


    /**
     * 可以查询单个对象:先以列表方式查询,如果长度不为0,就获取第一个元素
     *
     * @param sql
     * @param clazz
     * @param params
     * @param <T>
     * @return
     */
    public static <T> T queryForObject(String sql, Class<T> clazz, Object... params) {

        List<T> list = queryForList(sql, clazz, params);
        if (list.size() != 0) {
            return list.get(0);
        }
        return null;
    }


    /**
     * @param clazz  指定返回集合泛型对应的类信息,方便在结果集遍历中通过反射进行实例化
     * @param sql    要执行的sql语句
     * @param <T>    可以是Emp,Dept,……
     * @param params 要传递的占位符参数的值
     * @return 返回查询后的列表
     */
    public static <T> List<T> queryForList(String sql, Class<T> clazz, Object... params) {
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<T> list = new ArrayList<>();
        try {
            con = DBUtils.getConnection();
            ps = con.prepareStatement(sql);
            setParameter(ps, sql, params);
            rs = ps.executeQuery();
            //ResultSetMetaData:结果集元数据对象,在这个对象中封装了结果集的具体信息
            //例如结果集中字段的名字,以及字段的数量等内容
            ResultSetMetaData rsmd = rs.getMetaData();
            while (rs.next()) {
                T t = null;
                //如果没有无参构造方法
                if (String.class == clazz) {
                    t = (T) rs.getString(1);
                } else if (int.class == clazz || Integer.class == clazz) {
                    t = (T) new Integer(rs.getInt(1));
                } else if (double.class == clazz || Double.class == clazz) {
                    t = (T) new Double(rs.getDouble(1));
                } else if (java.util.Date.class == clazz || Date.class == clazz) {
                    t = (T) rs.getDate(1);
                }
                //TODO: 其它数据类型
                else {
                    //如果是有无参构造方法的类型则通过下面的方式进行实例化
                    //通过无参构造进行实例化
                    t = clazz.newInstance();
                    //为当前对象的属性进行赋值
                    //思路:将结果集中对应字段的值赋值给对象的属性值
                    //例如:empno字段对应empno属性
                    //ename字段对应ename属性
                    //……

                    //根据结果集中所有的列名分别获取所有对应的属性名,然后对每一个属性都来进行赋值
                    for (int i = 1; i <= rsmd.getColumnCount(); i++) {
                        //获取列名
                        String columnName = rsmd.getColumnLabel(i);
                        //根据列名获取类中的属性对象
                        Field field = getFieldByName(clazz, columnName);
                        //如果能找到属性,则对属性进行赋值操作
                        if (field != null) {
                            field.setAccessible(true);
                            //获取属性的类型
                            Class<?> fieldType = field.getType();
                            if (String.class == fieldType) {
                                field.set(t, rs.getString(i));
                            }
                            if (int.class == fieldType || Integer.class == fieldType) {
                                field.set(t, rs.getInt(i));
                            }
                            if (double.class == fieldType || Double.class == fieldType) {
                                field.set(t, rs.getDouble(i));
                            }
                            if (java.util.Date.class == fieldType || Date.class == fieldType) {

                                //TODO 重新处理date型的逻辑
//                                field.set(t, rs.getDate(i));

                                try {
                                    field.set(t, new Date(rs.getTimestamp(i).getTime()));
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    field.set(t, rs.getDate(i));
                                }
                            }
                            //TODO;其它数据类型
                            if (Timestamp.class == fieldType) {
                                field.set(t, rs.getTimestamp(i));
                            }

                            field.setAccessible(false);
                        }
                    }
                }
                list.add(t);
            }
        } catch (SQLException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        } finally {

            DBUtils.closeResource(con, ps,rs );
        }
        return list;
    }


    /**
     * 根据列名获取属性对象
     *
     * @param clazz      当前要获取属性对象的类
     * @param columnName 列名
     * @return
     */
    private static Field getFieldByName(Class<?> clazz, String columnName) {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //考虑列名和属性名存在大小写不同的情况
            if (field.getName().equalsIgnoreCase(columnName)) {
                return field;
            }
        }
        return null;
    }

    /**
     * 从sql语句中获取占位符参数的个数
     *
     * @param sql
     * @return
     */
    private static int getPlaceHolderCount(String sql) {
        int count = 0;
        Matcher matcher = Pattern.compile("\\?").matcher(sql);
        while (matcher.find()) {
            count++;
        }
        return count;
    }

    /**
     * 设置占位符参数
     */
    private static void setParameter(PreparedStatement ps, String sql, Object... params) throws SQLException {
        int placeHolderCount = getPlaceHolderCount(sql);
        if (params != null) {
            if (params.length != placeHolderCount) {
                throw new SQLException("有" + params.length + "个参数,但是占位符个数为:" + placeHolderCount);
            }
        }
        //设置占位符参数的值
        for (int i = 0; i < params.length; i++) {
            ps.setObject(i + 1, params[i]);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值