java学习 -- 利用类的反射和泛型自己动手写jdbc封装小类库

 自己动手来封装jdbc访问类库

在公司开发项目(ssh框架)的时候,我特别烦躁的一点就是每次用jdbc方式写一个数据访问(hibernate 可以用但是个人觉得对于复杂查询难以做到和好的控制,可能自己还要慢慢研究吧,自己喜欢mybatis),每次都要写一大堆模板代码,比较繁琐!

下面说下我的思路。

第一步,分析抽象


从已有的代码,出发会发现,访问数据库的套路

-->读取配置文件(不是必须的,但是项目中这样做,当然可以tomcat配置数据源之类的啊)

-->获取Connection

-->获取statement或者preparestatement

--->编写你的sql(这里说一下,如果你用的statement这里直接凭借字符,如果用的preparestatement就是设置参数,以后的sql语句最好不要用statement,因为他很不安全!!一个很大的问题的sql注入!no zuo no die!)

-->执行sql命令

-->封装结果

-->返回数据

所以,抽象出来,需要做的是

1.抽象出执行查询和执行更新(update,insert,delete)


2.抽象结果处理


主要完成的就是着两个问题


第二步,接上一步编写执行sql的函数

1.sql执行方法

/**
	 * 执行sql
	 * @param sql		sql文
	 * @param params	参数
	 * @return	
	 */
	public static boolean executeSQL(String sql,String...params){
		boolean flag = false;
		Connection connection = null;
		PreparedStatement statement = null;
		try {			
			connection = getConnection();			
			statement = connection.prepareStatement(sql);
			for(int i = 0,n = params.length;i<n;i++){
				statement.setString(i+1, params[i]);
			}
			statement.execute(sql);
			flag = true;
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(statement!=null){
				try {
					statement.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if(connection!=null){
				try {
					connection.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		return flag;		
	}

2.sql的查询方法

 

 * 查询结果
     * @param sql        sql文
     * @param params    参数
     * @param handler    结果处理集
     * @return            返回结果集
     */
    public static<T> List<?> queryResult(String sql,String[] params,ResultMapper<T> handler,Class<T> c){
        List<Map<String,Object>> results = null;
        Connection connection = null;
        ResultSet resultSet  = null;
        PreparedStatement statement = null;
        try {
            connection = getConnection();
            statement = connection.prepareStatement(sql);
            for (int i = 0, n = (params!=null?params.length:0); i < n; i++) {
                statement.setString(i, params[i]);
            } 
            resultSet = statement.executeQuery();
            if(resultSet!=null){
                results = new ArrayList<>();     
                String[] name = null;
                ResultSetMetaData rsm = null;
                while(resultSet.next()){
                    if(rsm==null){
                        rsm = resultSet.getMetaData();
                        System.out.println(JSON.toJSONString(rsm));
                        int count = rsm.getColumnCount();    
                        System.out.println(count);
                        name = new String[count];
                        for(int i = 0;i<count;i++){
                            name[i] = rsm.getColumnName(i+1);
                        }
                    }
                    Map<String, Object> map = new HashMap<>();
                    // 开始填充值
                    for(String keys:name){
                        map.put(keys, resultSet.getString(keys));
                    }
                    results.add(map);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(statement!=null){  
                try {  
                    statement.close();  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
            }  
            if(resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(connection!=null){  
                try {  
                    connection.close();  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
            } 
        }
        // 开始处理结合
        List<T> lists = new ArrayList<>();
        if(results!=null){
            for(Map<String, Object> e:results){
                T t = (T) handler.convert(e,c);
                lists.add(t);
            }        
            return lists;
        }else{ 
            return null;
        }
    }

第三步,编写数据映射接口和默认实现类

package com.handkoo.dao;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

public class DButils<T> {

    private static final Logger logger = LoggerFactory.getLogger(DButils.class);
    
    private static String url = "";
    private static String user = "";
    private static String password = "";

    static {
        InputStream inputStream = DButils.class.getResourceAsStream("/jdbc.properties");
        Properties properties = new Properties();
        try {
            properties.load(inputStream);
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("password");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static Connection getConnection() {
        Connection connection = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(url, user, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }

    /**
     * 执行sql
     * 
     * @param sql
     *            sql文
     * @param params
     *            参数
     * @return
     */
    public static boolean executeSQL(String sql, String... params) {
        boolean flag = false;
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = getConnection();
            statement = connection.prepareStatement(sql);
            for (int i = 0, n = params.length; i < n; i++) {
                statement.setString(i + 1, params[i]);
            }
            statement.execute(sql);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }

    /**
     * 查询结果
     * 
     * @param sql
     *            sql文
     * @param params
     *            参数
     * @param handler
     *            结果处理集
     * @return 返回结果集
     */
    public static <T> List<?> queryResult(String sql, String[] params, ResultMapper<T> handler, Class<T> c) {
        List<Map<String, Object>> results = null;
        Connection connection = null;
        ResultSet resultSet = null;
        PreparedStatement statement = null;
        try {
            connection = getConnection();
            statement = connection.prepareStatement(sql);
            for (int i = 0, n = (params != null ? params.length : 0); i < n; i++) {
                statement.setString(i+1, params[i]);
            }
            resultSet = statement.executeQuery();
            if (resultSet != null) {
                results = new ArrayList<>();
                String[] name = null;
                ResultSetMetaData rsm = null;
                while (resultSet.next()) {
                    if (rsm == null) {
                        rsm = resultSet.getMetaData();
                        System.out.println(JSON.toJSONString(rsm));
                        int count = rsm.getColumnCount();
                        System.out.println(count);
                        name = new String[count];
                        for (int i = 0; i < count; i++) {
                            name[i] = rsm.getColumnName(i + 1);                                 
                        }
                    }
                    Map<String, Object> map = new HashMap<>();
                    // 开始填充值
                    for (String keys : name) {                     
                        map.put(keys, resultSet.getString(keys));
                    }
                    results.add(map);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        // 开始处理结合
        List<T> lists = new ArrayList<>();
        if (results != null) {
            for (Map<String, Object> e : results) {
                T t = (T) handler.convert(e, c);
                lists.add(t);
            }
            return lists;
        } else {
            return null;
        }
    }

    /**
     * 类型转化接口
     * 
     * @author PengChan
     * 
     * @param <T>
     */
    public interface ResultMapper<T> {
        @SuppressWarnings("hiding")
        <T> T convert(Map<String, Object> resource, Class<T> c);
    }

    /**
     * 默认的类型实现
     * 
     * @author PengChan
     * 
     */
    public class DefaultMapper implements ResultMapper<T> {

        @SuppressWarnings("hiding")
        public <T> T getInstance(Class<T> c) throws InstantiationException, IllegalAccessException {
            return c.newInstance();
        }

        /**
         * 转化的核心方法
         */
        @SuppressWarnings("hiding")
        @Override
        public <T> T convert(Map<String, Object> resource, Class<T> c) {
            T t = null;
            try {
                t = getInstance(c);
                // 获取所有的成员变量
                Field[] declaredFields = t.getClass().getDeclaredFields();
                // 循环遍历设置值
                for (Field f : declaredFields) {
                    setValute(f, t, resource.get(f.getName()));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return t;
        }

        /**
         * 设置类型的值
         * 
         * @param fieldType
         * @param value
         */
        @SuppressWarnings({ "hiding", "rawtypes" })
        private <T> void setValute(Field field, T t, Object value) {
            try {
                Class fieldType = field.getType();
                field.setAccessible(true);
                if (fieldType.equals(int.class)) {// 如果是整形
                    field.setInt(t, (int) value);
                } else if (fieldType.equals(float.class)) {
                    field.setFloat(t, (float) value);
                } else if (fieldType.equals(boolean.class)) {
                    field.setBoolean(t, (boolean) value);
                } else if (fieldType.equals(double.class)) {
                    field.setDouble(t, (double) value);
                } else if (fieldType.equals(byte.class)) {
                    field.setByte(t, (byte) value);
                } else if (fieldType.equals(short.class)) {
                    field.setShort(t, (short) value);
                } else if (fieldType.equals(long.class)) {
                    field.setLong(t, (long) value);
                } else if (fieldType.equals(char.class)) {
                    field.setChar(t, (char) value);
                } else {
                    field.set(t, value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
     

}

调用方式:

DButils.queryResult(sql, null, new DButils().new DefaultMapper(), FitType.class);


注意:该工具类有一个局限性,就是对应的java类的属性名称需要与数据库的名称一致才能匹配。(如果这样,还需要配置xml文件来建立实体类和数据库表之间的映射,这不在考虑的范围之内,建议使用mybatis)



运行的结果如下:


以上就是我全部的分析内容了,有的地方还需要完善。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值