zoukankan      html  css  js  c++  java
  • 使用DbUtils对JDBC封装实现面向实体查询

    直接上代码

    package org.smart4j.chapter2.helper;
    
    import org.apache.commons.dbcp2.BasicDataSource;
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import org.apache.commons.dbutils.handlers.MapListHandler;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.smart4j.chapter2.util.CollectionUtil;
    import org.smart4j.chapter2.util.PropsUtil;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    
    /**
     * DbUtils 提供对 JDBC 的轻量级封装
     *  通过 DbUtils 提供的 QueryRunner 对象可以面向实体(Entity)进行查询。
     *  它的原理是:执行 SQL 语句并返回一个 ResultSet,随后通过反射去创建并初始化实体对象。
     *  Created by zhengbinMac on 2017/3/25.
     */
    public class DatabaseHelper {
        private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseHelper.class);
    
        // 线程连接
        private static final ThreadLocal<Connection> CONNECTION_THREAD_LOCAL;
        // DbUtils
        private static final QueryRunner QUERY_RUNNER;
        // 线程池
        private static final BasicDataSource DATA_SOURCE;
    
        static {
            CONNECTION_THREAD_LOCAL = new ThreadLocal<>();
            QUERY_RUNNER = new QueryRunner();
    
            Properties conf = PropsUtil.loadProps("config.properties");
            // 设置连接池,使用 DBCP 来获取数据库连接
            DATA_SOURCE = new BasicDataSource();
            DATA_SOURCE.setDriverClassName(conf.getProperty("jdbc.driver"));
            DATA_SOURCE.setUrl(conf.getProperty("jdbc.url"));
            DATA_SOURCE.setUsername(conf.getProperty("jdbc.username"));
            DATA_SOURCE.setPassword(conf.getProperty("jdbc.password"));
        }
    
        /**
         * 获取数据库连接
         */
        public static Connection getConnection() {
            // 首先从 ThreadLocal 中获取
            Connection connection = CONNECTION_THREAD_LOCAL.get();
            // 若不存在,则创建一个新的 Connection,并最终将其放入 ThreadLocal 中
            if (connection == null) {
                try {
                    connection = DATA_SOURCE.getConnection();
                } catch (SQLException e) {
                    LOGGER.error("get connection failure", e);
                } finally {
                    CONNECTION_THREAD_LOCAL.set(connection);
                }
            }
            return connection;
        }
    
        /**
         * 批量查询实体
         */
        public static <T> List<T> queryEntityList(Class<T> entityClass, String sql, Object... params) {
            List<T> entityList = null;
            try {
                Connection conn = getConnection();
                entityList = QUERY_RUNNER.query(conn, sql, new BeanListHandler<T>(entityClass), params);
            } catch (SQLException e) {
                LOGGER.error("query entity list failure", e);
            }
            return entityList;
        }
    
        /**
         * 查询单个实体
         */
        public static <T> T queryEntity(Class<T> entityClass, String sql, Object... params) {
            T entity = null;
            try {
                Connection conn = getConnection();
                entity = QUERY_RUNNER.query(conn, sql, new BeanHandler<T>(entityClass), params);
            } catch (SQLException e) {
                LOGGER.error("query entity failure", e);
                e.printStackTrace();
            }
            return entity;
        }
    
        public static List<Map<String, Object>> executeQuery(String sql, Object... params) {
            List<Map<String, Object>> result = null;
            try {
                Connection conn = getConnection();
                result = QUERY_RUNNER.query(conn, sql, new MapListHandler(), params);
            } catch (SQLException e) {
                LOGGER.error("query entity failure", e);
                e.printStackTrace();
            }
            return result;
        }
    
        /**
         * 执行更新语句(update、insert 和 delete)
         */
        public static int executeUpdate(String sql, Object... params) {
            int updateRows = 0;
            try {
                Connection conn = getConnection();
                updateRows = QUERY_RUNNER.update(conn, sql, params);
            } catch (SQLException e) {
                LOGGER.error("execute update failure", e);
                e.printStackTrace();
            }
            return updateRows;
        }
    
        /**
         * 插入实体
         */
        public static <T> boolean insertEntity(Class<T> entityClass, Map<String, Object> fieldMap) {
            if (CollectionUtil.isEmpty(fieldMap)) {
                LOGGER.error("can not insert entity: fieldMap is empty");
                return false;
            }
            String sql = "INSERT INTO " + getTableName(entityClass);
            StringBuilder colums = new StringBuilder("(");
            StringBuilder values = new StringBuilder("(");
    
            // 插入实体的字段名,和字段值的占位符
            for (String colum : fieldMap.keySet()) {
                colums.append(colum).append(", ");
                values.append("?, ");
            }
            colums.replace(colums.lastIndexOf(", "), colums.length(), ")");
            values.replace(values.lastIndexOf(", "), values.length(), ")");
            sql += colums + " VALUES " + values;
    
            // 插入实体的值
            Object[] params = fieldMap.values().toArray();
            return executeUpdate(sql, params) == 1;
        }
    
        /**
         * 更新实体
         */
        public static <T> boolean updateEntity(Class<T> entityClass, long id, Map<String, Object> fieldMap) {
            if (CollectionUtil.isEmpty(fieldMap)) {
                LOGGER.error("can not update entity: fieldMap is empty");
                return false;
            }
            // 更具 fieldMap 拼接出更新 SQL 语句
            String sql = "UPDATE " + getTableName(entityClass) + " SET ";
            StringBuilder columns = new StringBuilder();
            // 更新实体的字段
            for (String colums : fieldMap.keySet()) {
                columns.append(columns).append("=?, ");
            }
    
            // 去掉 SQL 最后一个 ', '
            sql += columns.substring(0, columns.lastIndexOf(", ")) + " WHERE id=?";
    
            // 更新实体的值
            List<Object> paramList = new ArrayList<Object>();
            paramList.addAll(fieldMap.values());
            paramList.add(id); // 增加主键 id
            Object[] params = paramList.toArray();
    
            return executeUpdate(sql, params) == 1;
        }
    
        /**
         * 删除实体
         */
        public static <T> boolean deleteEntity(Class<T> entityClass, long id) {
            String sql = "DELTE FROM " + getTableName(entityClass) + "WHERE id=?";
            return executeUpdate(sql, id) == 1;
        }
    
        /**
         * 获取操作表的表名,即实体的类名
         */
        private static String getTableName(Class<?> entityClass) {
            return entityClass.getSimpleName();
        }
    }

    两个工具类

    集合工具类:

    package org.smart4j.chapter2.util;
    
    import org.apache.commons.collections.MapUtils;
    
    import java.util.Collection;
    import java.util.Map;
    
    /**
     * 集合工具类
     * 
     * Created by zhengbinMac on 2017/3/25.
     */
    public class CollectionUtil {
        /**
         * 判断 Collection 是否为空
         */
        public static boolean isEmpty(Collection<?> collection) {
            return CollectionUtil.isEmpty(collection);
        }
    
        /**
         * 判断 Collection 是否为非空
         */
        public static boolean isNotEmpty(Collection<?> collection) {
            return !isEmpty(collection);
        }
    
        /**
         * 判断 Map 是否为空
         */
        public static boolean isEmpty(Map<?, ?> map) {
            return MapUtils.isEmpty(map);
        }
    
        /**
         * 判断 Map 是否为非空
         */
        public static boolean isNotEmpty(Map<?, ?> map) {
            return !isEmpty(map);
        }
    }
    View Code

    属性文件(properties)工具类:

    package org.smart4j.chapter2.util;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    /**
     * 属性文件工具类
     * 
     * Created by zhengbinMac on 2017/3/25.
     */
    public class PropsUtil {
        private static final Logger LOGGER = LoggerFactory.getLogger(PropsUtil.class);
    
        /**
         * 加载属性文件
         */
        public static Properties loadProps(String fileName) {
            Properties properties = null;
            InputStream is = null;
            try {
                is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
                if (is == null) {
                    throw new FileNotFoundException(fileName + "file is not found");
                }
                properties = new Properties();
                properties.load(is);
            } catch (IOException e) {
                LOGGER.error("load properties file failure", e);
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        LOGGER.error("close inputStream failure", e);
                    }
                }
            }
            return properties;
        }
    
        /**
         * 获取字符型属性(默认值为空字符串)
         */
        public static String getString(Properties properties, String key) {
            return getString(properties, key, "");
        }
    
        /**
         * 获取字符型属性(可指定默认值)
         */
        public static String getString(Properties properties, String key, String defaultValue) {
            String value = defaultValue;
            if (properties.contains(key)) {
                value = properties.getProperty(key);
            }
            return value;
        }
    
        /**
         * 获取数值型属性(默认值为0)
         */
        public static int getInt(Properties properties, String key) {
            return getInt(properties, key, 0);
        }
    
        /**
         * 获取数值型属性(可指定默认值)
         */
        public static int getInt(Properties properties, String key, int defaultValue) {
            int value = defaultValue;
            if (properties.contains(key)) {
                value = CastUtil.castInt(properties.getProperty(key));
            }
            return value;
        }
    
        /**
         * 获取布尔型属性(默认值为 false)
         */
        public static boolean getBoolean(Properties properties, String key) {
            return getBoolean(properties, key, false);
        }
    
        /**
         * 获取布尔型属性(可指定默认值)
         */
        public static boolean getBoolean(Properties properties, String key, boolean defaultValue) {
            boolean value = defaultValue;
            if (properties.contains(key)) {
                value = CastUtil.castBoolean(properties.getProperty(key));
            }
            return value;
        }
    }
    View Code

    参考资料

    [1] 架构探险, 第 2 章 - 为 Web 应用添加业务功能

  • 相关阅读:
    C#(99):TreadPool
    C#(99):多线程锁:Mutex互斥体,Semaphore信号量,Monitor监视器,lock,原子操作InterLocked
    C#(99):Thead线程 System.Thread
    ASP.NET(99):WebService之WebMethod参数介绍
    C#(99):WCF之WebService
    Windows服务 System.ServiceProcess.ServiceBase类
    应用程序域 System.AppDomain,动态加载程序集
    C#(99):app.config/web.config配置文件增删改
    C#(99):文件读写(三)利用FileStream类操作字节数组byte[]、BinaryFormatter、内存流MemoryStream
    C#(99):文件读写(二)利用SteamReader和StreamWrite类处理字符串、FileSystemWatcher、BinaryReader/BinaryWriter
  • 原文地址:https://www.cnblogs.com/zhengbin/p/6632183.html
Copyright © 2011-2022 走看看