JDBC封装工具类代码(JDBCUtil+BaseDao)

一、新建数据库的配置文件(db.properties)

注:这里使用mysql数据库。

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=1234

二、创建JDBC工具类(JDBCUtil.java)


import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * 使用JDBC进行数据库连接与关闭的工具类
 * 
 * @author XIAOHU
 * @since 2018-04-08
 */
public class JDBCUtil {

    private static String driver;
    private static String url;
    private static String username;
    private static String password;

    static {
        init();
        try {
            // 加载一次驱动
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化数据库连接数据
     */
    public static void init() {
        Properties prop = new Properties();
        InputStream is = 
             JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            prop.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        driver = prop.getProperty("jdbc.driver");
        url = prop.getProperty("jdbc.url");
        username = prop.getProperty("jdbc.username");
        password = prop.getProperty("jdbc.password");
    }

    /**
     * 获取数据库连接
     * 
     * @return
     */
    public static Connection getConnection() {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, username, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 释放所有资源
     * 
     * @param rs
     *            结果集
     * @param st
     *            Statement对象
     * @param conn
     *            数据库连接
     */
    public static void closeAll(ResultSet rs, Statement st, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (st != null) {
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}

三、创建字符串工具类(StringUtil.java)


/**
 * 字符串处理工具类
 * 
 * @author XIAOHU
 * @since 2018-04-11
 */
public class StringUtil {

    /**
     * 将字符串首字母转为大写
     * @param str 要转换的字符串
     * @return 返回转换后的首字母大写的字符串
     */
    public static String toUpper(String str){
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

}

四、创建DAO层实现类的公共父类(BaseDao.java)


import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import cn.xiyou.petshopsystem.utils.JDBCUtil;
import cn.xiyou.petshopsystem.utils.StringUtil;

/**
 * 封装JDBC的增删改查功能
 * 
 * @author XIAOHU
 * @since 2018-04-11
 * 
 */
public class BaseDao<T> {

    /**
     * 封装增、删、改功能
     * 
     * @param sql
     *            需要执行的sql语句
     * @param args
     *            不定参数,是对sql语句中的占位符“?”传入的参数
     * @return 返回操作所影响的行数
     */
    public int executeUpdate(String sql, Object... args) {
        Connection conn = null;
        PreparedStatement pst = null;
        int rows = 0;
        try {
            conn = JDBCUtil.getConnection();
            pst = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                pst.setObject(i + 1, args[i]);
            }
            rows = pst.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.closeAll(null, pst, conn);
        }
        return rows;
    }

    /**
     * 查询一条记录
     * 
     * @param sql
     *            需要执行的sql语句
     * @param cls
     *            由此 Class对象建模的类的类型。如果将被建模的类未知,则使用 Class。
     *            例如,String.class 的类型是Class。     
     * @param args
     *            不定参数,是对sql语句中的占位符“?”传入的参数
     * @return 返回操作所影响的行数
     */
    public T selectOne(String sql, Class cls, Object... args) {
        List list = this.selectMany(sql, cls, args);
        return list.isEmpty() ? null : list.get(0);
    }

    /**
     * 查询所有记录
     * 
     * @param sql
     *            需要执行的sql语句
     * @param cls
     *            由此 Class对象建模的类的类型。如果将被建模的类未知,则使用 Class。
     *            例如,String.class 的类型是Class。
     * @param args
     *            不定参数,是对sql语句中的占位符“?”传入的参数
     * @return 返回操作所影响的行数
     */
    public List selectMany(String sql, Class cls, Object... args) {
        Connection conn = null;
        PreparedStatement pst = null;
        ResultSet rs = null;
        List list = new ArrayList();
        try {
            conn = JDBCUtil.getConnection();
            pst = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                pst.setObject(i + 1, args[i]);
            }
            rs = pst.executeQuery();
            //从结果集中获取数据库表的相关信息
            ResultSetMetaData metaData = rs.getMetaData();
            while (rs.next()) {
                T obj = cls.newInstance();// 创建cls实例
                //metaData.getColumnCount():获得数据库表中列数(字段数)
                for (int i = 1; i <= metaData.getColumnCount(); i++) {
                    String columnLabel = metaData.getColumnLabel(i);//获取字段名

                    // 动态拼接成该属性对应实体中的setter方法的方法名(=set字符串拼接首字母大写
                    // 的属性名)。如:setName(Stringname)的方法名为setName
                    String name = "set" + StringUtil.toUpper(columnLabel);
                    // 获取实体中所有声明(私有+公有)的属性
                    Field field = cls.getDeclaredField(columnLabel);
                    // 获取实体中所有声明(私有+公有)的形参为field.getType()类型,方法名为
                    // name的方法
                    Method method = cls.getDeclaredMethod(name, field.getType());
                    // 通过结果集获取字段名为fieldName(与实体中的对应属性名完全相同)的值
                    Object realParam = rs.getObject(columnLabel);
                    // 执行obj对象中的method方法,传入的实参为realParam
                    method.invoke(obj, realParam);
                }
                list.add(obj);
            }
        } catch (SQLException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.closeAll(null, pst, conn);
        }
        return list;
    }

    /**
     * 查询总记录数
     * 
     * @param sql
     *            需要执行的sql语句
     * @param args
     *            需要对sql语句中的占位符“?”传入的参数数组
     * @return 返回操作所影响的行数
     */
    public int selectCount(String sql, Object... args) {
        Connection conn = null;
        PreparedStatement pst = null;
        ResultSet rs = null;
        int count = 0;
        try {
            conn = JDBCUtil.getConnection();
            pst = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                pst.setObject(i + 1, args[i]);
            }
            rs = pst.executeQuery();
            if (rs.next()) {
                count = rs.getInt(1);
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.closeAll(null, pst, conn);
        }
        return count;
    }

}



说明:这里仅做了部分封装,更多的封装需要自己去实现。BaseDao.java中的封装代码为重点,类似于一些框架底层的实现,想要更深一步学习封装的,希望自己去看一些框架源码和设计模式。

你可能感兴趣的:(Java代码)