JDBC(三) JdbcFramework数据框架

搭建数据框架:

导入连接池jar包:

<c3p0-config>
  <default-config>
    <!--配置连接池初识的连接数-->
    <property name="initialPoolSize">10</property>
    <!--配置最大连接数-->
    <property name="maxPoolSize">25</property>
    <!--配置最小连接数-->
    <property name="minPoolSize">5</property>
    <!--配置驱动-->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <!--配置URL-->
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/geekhome</property>
    <!--配置连接数据库的用户名-->
    <property name="user">root</property>
    <!--配置密码-->
    <property name="password">tjhilu</property>
  </default-config>
</c3p0-config>

用户类:

public class User {

    private int userId;
    private String userName;
    private String password;

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

用户数据操作类:

public class UserDao {
    /**
     * 添加用户
     * @param user
     */
    public void add(User user){
        JdbcUtil.executeUpdate("insert into users(username,password) values(?,?)", new Object[]{user.getUserName(),user.getPassword()});
    }

    public User findUserByName(String userName){
        List<User> list = JdbcUtil.executeQuery("select userId,userName,password from users " +
                "where userName=?",new Object[]{userName},User.class);
        if(!list.isEmpty()){
            return list.get(0);
        }
        return null;
    }
}

员工类:

public class Emp {
    private String firstName;
    private double salary;
    private Date hireDate;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public Date getHireDate() {
        return hireDate;
    }

    public void setHireDate(Date hireDate) {
        this.hireDate = hireDate;
    }
}

数据访问辅助类,封装数据连接与关闭:

/**
 * 数据访问辅助类,封装数据连接与关闭
 */
public class JdbcHandler {
    //数据池:用dataSource进行接收,是为了以后更换数据池类型
    private static DataSource dataSource;

    static{
        //初始化数据池
        dataSource = new ComboPooledDataSource();
    }

    /**
     * 打开数据库连接
     * @return
     */
    public static Connection openConnection(){
        Connection con = null;
        if(dataSource != null){
            try {
                con = dataSource.getConnection();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return con;
    }

    /**
     * 关闭数据库对象
     * @param con
     * @param pstmt
     * @param rs
     */
    public static void close(Connection con, PreparedStatement pstmt, ResultSet rs){
        try {
            if(rs != null){
                rs.close();
            }
            if(pstmt != null){
                pstmt.close();
            }
            if(con != null){
                con.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
方便获取结果集的一些数据:

获取结果集的列名称、根据列的名称查找属性、将属性的首字母转换大写
public class JdbcCommonUtil {
    /**
     * 获取结果集的列名称
     * @param metaData
     * @return 将列的名称封装成一个String集合,返回出去
     */
    public static String[] getColumnNames(ResultSetMetaData metaData){
        String[] array = null;
        try {
            //根据列的数量创建数组
            array = new String[metaData.getColumnCount()];
            for(int i = 0; i < array.length; i++){
                //获取数据列的原名称 FIRST_NAME
                //array[i] = metaData.getColumnName(i+1);
                //获取数据列的标签名,标签名会随着别名进行更改,会将最终的名称改为as的别名firstname
                array[i] = metaData.getColumnLabel(i+1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return array;
    }

    /**
     * 根据列的名称查找属性
     * @param columnName
     * @param fields
     * @return
     */
    public static Field findField(String columnName,Field[] fields){
        for (Field field : fields) {
            //判断属性名称是否相同:对属性名进行遍历,与传入的列名进行比较,如果一致,返回这个属性
            if(field.getName().equalsIgnoreCase(columnName)){
                return field;
            }
        }
        return null;
    }

    /**
     * 将属性的首字母转换大写
     * @param fieldName
     * @return
     */
    public static String parseUpperField(String fieldName){
        return (char)(fieldName.charAt(0)-32)+fieldName.substring(1);
    }
}

数据库访问工具类,封装了数据常用的增删改查的操作方法:

/**
 * 数据库访问工具类,封装了数据常用的增删改查的操作方法
 */
public class JdbcUtil {
    /**
     * 用于处理数据增删改
     * @param sql 执行的SQL语句
     * @param params 注入至SQL语句占位符的值(参数不是必须的)
     * @return
     */
    public static int executeUpdate(String sql,Object[] params){
        int resultCount = -1;
        Connection con = JdbcHandler.openConnection();
        PreparedStatement pstmt = null;
        if(con != null){
            try {
                pstmt = con.prepareStatement(sql);
                //判断是否需要注入参数
                if(params != null){
                    //注入参数
                    for(int i = 0; i < params.length; i++){
                        //判断每个参数的类型
              //可以直接用Object就不用判断每个参数的class类型了
Object param = params[i]; //  if(param.getClass() == Integer.class || param.getClass() == int.class){ //    pstmt.setInt(i+1, (int)param); //  } //  else if(param.getClass() == Float.class || param.getClass() == float.class){ //     pstmt.setFloat(i+1, (float)param); //  } //  else if(param.getClass() == String.class){ //    pstmt.setString(i+1, param.toString()); //  } pstmt.setObject(i+1, param); } } //执行SQL语句:要在if外面进行执行,因为参数可能为null resultCount = pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { //关闭数据库:不管try里面的结果如何,都要关闭数据库连接 JdbcHandler.close(con, pstmt, null); } } return resultCount; } /** * 查询行 * @param sql * @param params * @param objClass 数据表映射类的Class * @return */ public static <T> List<T> executeQuery(String sql,Object[] params,Class<T> objClass){ List<T> list = new ArrayList(); //获取连接 Connection con = JdbcHandler.openConnection(); PreparedStatement pstmt = null; ResultSet rs = null; if(con != null){ try { //创建预处理器 pstmt = con.prepareStatement(sql); //判断参数是否存在 if(params != null){ //注入参数 for(int i = 0; i < params.length; i++){ pstmt.setObject(i+1, params[i]); } } //执行查询,获得结果集 rs = pstmt.executeQuery(); //获取结果集的元数据 ResultSetMetaData metaData = rs.getMetaData(); //反射获取对象的所有属性:要调用declareFields才能将私有的属性也获取出来 Field[] fields = objClass.getDeclaredFields(); //解析结果集的数据结构,获得结果集的列名 String[] columnNames = JdbcCommonUtil.getColumnNames(metaData); //迭代结果集 while(rs.next()){ //将实体类实例化:通过无参构造方法创建对象 T t = objClass.newInstance(); //获取每列的值
            //遍历通说结果集获取的列名,将列名与属性名进行比较,如果查找到有相对应的属性则将列值赋给属性
for (String columnName : columnNames) { //System.out.println("列名:"+columnName); //根据列名查找属性:传入当前遍历的列名和属性名集合 Field field = JdbcCommonUtil.findField(columnName,fields); if(field != null){ //获取属性的类型 Class fieldClass = field.getType(); //声明列值 Object value = null; //根据属性类型调用结果集中对应的get方法 if(fieldClass == String.class){ value = rs.getString(columnName); } else if(fieldClass == double.class || fieldClass == Double.class){ value = rs.getDouble(columnName); } else if(fieldClass == float.class || fieldClass == Float.class){ value = rs.getFloat(columnName); } else if(fieldClass == int.class || fieldClass == Integer.class){ value = rs.getInt(columnName); } else if(fieldClass == Date.class){ value = rs.getTimestamp(columnName); } //System.out.println(value); //查找相应的setter方法(通过setter方法的名称进行查找setter方法,直接将列值写入),将列值写入 // System.out.println("属性名:"+field.getName()); // System.out.println("set"+JdbcCommonUtil.parseUpperField(field.getName())); Method method = objClass.getMethod("set"+JdbcCommonUtil.parseUpperField(field.getName()),fieldClass); //执行setter方法:invoke第一个参数是调用方法的对象是哪个对象,第二个参数是要传入的值 method.invoke(t,value); } else{ //未找到属性抛出异常:抛出自定义异常 throw new MappingFieldNotFoundException(); } } //System.out.println("---------------------------"); //将实体对象添加至集合 list.add(t); } } catch (SQLException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e){ e.printStackTrace(); } catch(InvocationTargetException e){ e.printStackTrace(); } } //关闭数据库 return list; } }
自定义异常:
/**
 * 映射属性未找到异常
 */
public class MappingFieldNotFoundException extends RuntimeException {
  //如果没有找到相对应的属性和列名,则抛出异常
    public MappingFieldNotFoundException() {
        super("映射的属性未找到!");
    }
}

测试类:

package com.igeek.test;

import com.igeek.dao.UserDao;
public class Test {

    public static void main(String[] args) {
     //测试修改信息的方法
        JdbcUtil.executeUpdate("update users set password=?", new Object[]{"111"});
        JdbcUtil.executeUpdate("delete from users where userid=108", null);
        JdbcUtil.executeUpdate("update users set " +
                "birthday=? where userid=?", new Object[]{new Date(),2});
     //测试查询信息的方法 List
<User> list = JdbcUtil.executeQuery("select userid,username,password from users", null, User.class);
     //循环打印查找的结果
for (User user : list) { System.out.println(user.getUserId()+" "+user.getUserName()+" "+user.getPassword()); }      //测试查询信息的方法:列名和属性名称不一致时,用as修改列名方便和属性名进行匹配 List<Emp> list = JdbcUtil.executeQuery("select first_name as firstname,salary,hire_date as hireDate " + "from emp where department_id=?", new Object[]{50}, Emp.class); for (Emp emp : list) { System.out.println(emp.getFirstName()+" "+emp.getSalary()+" "+emp.getHireDate()); }
     //通过用户操作类进行查询单行数据 UserDao userDao
= new UserDao();
     //新建一个用户 User user
= new User(); user.setUserName("testName"); user.setPassword("000"); userDao.add(user);      //测试查询单行数据 User user = userDao.findUserByName("testName"); if(user != null){ System.out.println(user.getUserId()+" "+user.getPassword()); } } }
原文地址:https://www.cnblogs.com/gfl-1112/p/12775270.html