数据库小框架DbUtils的封装

要封装一个数据库框架,我们需要明白几个问题:

1. 对数据库的CURD操作是与获取连接等的放在一起,还是分开写。
2. 如何来保证事物
3. 如何实现通用性

其实答案很简单,首先,对于是否放在一起,其实看个人心情,怎样觉得代码优雅,就怎样写;其次保证事物实际上就是要保证我的每次操作都是同一个连接,那么可以使用ThreadLocal(实际很多框架,如Mybatis底层也是使用ThreadLocal来保证事物的);最后,实现通用性,可以采用继承或者接口。因此,我们可以写一个JdbcUtils,再写个BaseDao,并且使用c3p0连接池连管理连接,最后写一个UserDao来实现。

话不多说,直接上代码:

JdbcUtils

主要封装了获取连接、开启事物等


import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.photograph_u.consts.JdbcConsts;
import java.sql.*;

public class JdbcUtils {
    private static ThreadLocal<Connection> connectionThreadLocal = new ThreadLocal<>();


    //c3p0连接池获取连接
    private static ComboPooledDataSource dataSource = new ComboPooledDataSource("mysql");

    public static Connection getConnection() throws SQLException {
        Connection conn = connectionThreadLocal.get();
        if (conn == null) {
            conn = dataSource.getConnection();
        }
        return conn;
    }

    //JDBC获取链接
    /*
    public static Connection getConnection() throws SQLException {
        Connection conn = connectionThreadLocal.get();
        if (conn == null) {
            try {
                Class.forName(JdbcConsts.DRIVER);
                conn = DriverManager.getConnection(JdbcConsts.URL, JdbcConsts.USERNAME, JdbcConsts.PASSWORD);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        }
        return conn;
    }
    */

    //获取预处理
    public static PreparedStatement getPreparedStatement(Connection conn, String sql) throws SQLException {
        if (conn != null) {
            return conn.prepareStatement(sql);
        }
        return null;
    }

    //填充参数
    public static void setParams(Object[] params, PreparedStatement pstm) throws SQLException {
        if (pstm != null && params != null) {
            for (int i = 1; i <= params.length; i++) {
                pstm.setObject(i, params[i - 1]);
            }
        }
    }

    //开启事物
    public static void beginTransaction() {
        Connection conn = null;
        try {
            conn = getConnection();
            conn.setAutoCommit(false);
            connectionThreadLocal.set(conn);
        } catch (SQLException e) {
            connectionThreadLocal.remove();
            close(conn, null, null);
            throw new RuntimeException(e);
        }

    }

    //提交事物
    public static void commitTransaction() {
        Connection conn = connectionThreadLocal.get();
        if (conn != null) {
            try {
                conn.commit();
            } catch (SQLException ex) {
                try {
                    conn.rollback();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
                throw new RuntimeException(ex);
            } finally {
                connectionThreadLocal.remove();
                close(conn, null, null);
            }
        }
    }

    //释放资源
    public static void close(Connection conn, PreparedStatement pstm, ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (pstm != null) {
                pstm.close();
            }
            if (connectionThreadLocal.get() == null) {
                if (conn != null) {
                    conn.close();
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
BaseDao

主要封装了对数据库的增删查改


import com.photograph_u.util.CommUtils;
import com.photograph_u.util.JdbcUtils;
import org.apache.commons.beanutils.BeanUtils;
import java.sql.*;
import java.util.*;

public class BaseDao {
    //查询封装到Bean
    static <T> T queryToBean(String sql, Object[] params, Class<T> clazz) {
        T object = null;
        Connection conn = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            pstm = JdbcUtils.getPreparedStatement(conn, sql);
            JdbcUtils.setParams(params, pstm);
            rs = pstm.executeQuery();
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            while (rs.next()) {
                object = clazz.newInstance();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnName(i);
                    Object columnValue = rs.getObject(i);
                    if (columnValue != null && !("".equals(columnValue))) {
                        BeanUtils.setProperty(object, CommUtils.changeUnderlineToHumpName(columnName), columnValue);
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtils.close(conn, pstm, rs);
        }
        return object;
    }

    //查询封装到BeanList
    public static <T> List<T> queryToBeanList(String sql, Object[] params, Class<T> clazz) {
        List<T> objectList = new ArrayList<>();
        Connection conn = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            pstm = JdbcUtils.getPreparedStatement(conn, sql);
            JdbcUtils.setParams(params, pstm);
            rs = pstm.executeQuery();
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            while (rs.next()) {
                T object = clazz.newInstance();
                for (int i = 1; i <= columnCount; i++) {
                    Object columnValue = rs.getObject(i);
                    String columnName = metaData.getColumnName(i);
                    if (columnValue != null && !("".equals(columnValue))) {
                        BeanUtils.setProperty(object, CommUtils.changeUnderlineToHumpName(columnName), columnValue);
                    }
                }
                objectList.add(object);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtils.close(conn, pstm, rs);
        }
        return objectList;
    }

    //查询封装到Map
    public Map<String, Object> queryToMap(String sql, Object[] params) {
        Map<String, Object> resultMap = null;
        Connection conn = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            pstm = JdbcUtils.getPreparedStatement(conn, sql);
            JdbcUtils.setParams(params, pstm);
            rs = pstm.executeQuery();
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            while (rs.next()) {
                resultMap = new LinkedHashMap<>();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnName(i);
                    Object columnValue = rs.getObject(i);
                    if (columnValue != null && !("".equals(columnValue))) {
                        resultMap.put(CommUtils.changeUnderlineToHumpName(columnName), columnValue);
                    }
                }
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtils.close(conn, pstm, rs);
        }
        return resultMap;
    }

    //查询封装到mapList
    public List<Map<String, Object>> queryToMapList(String sql, Object[] params) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        Connection conn = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            pstm = JdbcUtils.getPreparedStatement(conn, sql);
            JdbcUtils.setParams(params, pstm);
            rs = pstm.executeQuery();
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            while (rs.next()) {
                Map<String, Object> resultMap = new LinkedHashMap<>();//这里为了保证查询顺序的正确性,不能直接使用HashMap
                for (int i = 1; i <= columnCount; i++) {
                    Object columnValue = rs.getObject(i);
                    String columnName = metaData.getColumnName(i);
                    if (columnValue != null && !("".equals(columnValue))) {
                        resultMap.put(CommUtils.changeUnderlineToHumpName(columnName), columnValue);
                    }
                }
                mapList.add(resultMap);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtils.close(conn, pstm, rs);
        }
        return mapList;
    }

    //增删改
    public static int update(String sql, Object[] params) {
        Connection conn = null;
        PreparedStatement pstm = null;
        int count;
        try {
            conn = JdbcUtils.getConnection();
            pstm = JdbcUtils.getPreparedStatement(conn, sql);
            JdbcUtils.setParams(params, pstm);
            count = pstm.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtils.close(conn, pstm, null);
        }
        return count;
    }
}
UserDao

具体的实现


import com.photograph_u.domain.User;

import java.util.Map;

public class UserDao extends BaseDao {
    //检查用户是否存在
    public boolean checkUser(String phone) {
        String sql = "select count(*) as count from user where phone=? and is_deleted=0";
        long count = (long) queryToMap(sql, new Object[]{phone}).get("count");//注意这里为long
        return count == 1;
    }

    //添加用户
    public boolean addUser(String phone, String password) {
        String sql = "insert into user(phone,password) values(?,?)";
        int count = update(sql, new Object[]{phone, password});
        return count == 1;
    }

    //查询用户
    public User queryUser(String phone, String password) {
        String sql = "select id,nickname,head_image,sex,birthday,phone,school from user where phone=? and password=? and is_deleted=0";
        User user = queryToBean(sql, new Object[]{phone, password}, User.class);
        return user;
    }

    //修改密码字段
    public boolean updatePassword(int userId, String password, String newPassword) {
        String sql = "update user set password=? where password=? and id=? and is_deleted=0";
        int count = update(sql, new Object[]{newPassword, password, userId});
        return count == 1;
    }

    //重置密码
    public boolean resetPassword(String phone, String newPassword) {
        String sql = "update user set password=? where phone=? and is_deleted=0";
        int count = update(sql, new Object[]{newPassword, phone});
        return count == 1;
    }

    //查询用户
    public User queryUserById(int userId) {
        String sql = "select id,nickname,head_image,sex,birthday,phone,school from user where id=? and is_deleted=0";
        User user = queryToBean(sql, new Object[]{userId}, User.class);
        return user;
    }

    //修改个人信息
    public boolean updateInfo(User user) {
        String sql = "update user set nickname=?,sex=?,birthday=?,school=? where id=? and is_deleted=0";
        Object[] params = {user.getNickname(), user.getSex(), user.getBirthday(), user.getSchool(), user.getId()};
        int count = update(sql, params);
        return count == 1;
    }

    //修改头像
    public boolean updateHeadImage(int userId, String headImage) {
        String sql = "update user set head_image=? where id=? and is_deleted=0";
        int count = update(sql, new Object[]{headImage, userId});
        return count == 1;
    }

    //查询用户头像和昵称
    public Map<String, Object> queryUserHeadImageAndNickNameById(int userId) {
        String sql = "select nickname,head_image from user where id=? and is_deleted=0";
        Map<String, Object> resultMap = queryToMap(sql, new Object[]{userId});
        return resultMap;
    }

}
c3p0-config.xml
<?xml version="1.0" encoding="utf-8"?>
<c3p0-config>
    <default-config>
        <property name="initialPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">100</property>
        <property name="minPoolSize">10</property>
        <property name="maxStatements">200</property>
    </default-config>
    <named-config name="mysql">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_photograph_u</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        <property name="initialPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">100</property>
        <property name="minPoolSize">10</property>
        <property name="maxStatements">200</property>
    </named-config>

</c3p0-config>

猜你喜欢

转载自blog.csdn.net/qq_35890572/article/details/80989016
今日推荐