JDBC的工具类--BaseDao增强型

  • 在使用JDBC操作数据库的过程中通常都会使用到BaseDao工具类,在类中定义连接数据库的方法、查询数据库的方法、修改数据库的方法,方便我们操作数据库
  • 一般情况下简单的basedao工具类只需要4个方法
    • public Connection getConnection() 获取连接的方法
    • public ResultSet executeQuery(String sql,Object… params) 查询数据库的通用方法
    • public int executeUpdate(String sql,Object… params);
    • public void close() 用于关闭连接的方法
  • 以下是完整代码
package com.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class BaseDao {
    private String driverName = "oracle.jdbc.driver.OracleDriver";
    private String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
    private String userName = "scott";
    private String pwd = "123";
    public Connection conn;
    public PreparedStatement statement;
    public ResultSet rs;

    /**
     * 连接数据库
     * @return
     * @throws Exception
     */
    public Connection getConnection() {
        try {
            Class.forName(driverName);
            conn = DriverManager.getConnection(url, userName, pwd);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 关闭数据库连接
     * 
     * @throws Exception
     */
    public void close() throws Exception {
        if (rs != null) {
            rs.close();
        }
        if (statement != null) {
            statement.close();
        }
        if (conn != null) {
            conn.close();
        }
    }

    /**
     * 查询数据库的通用方法
     * @param sql  查询的SQL语句
     * @param objects  sql的参数
     * @return  结果集
     */
    public ResultSet executeQuery(String sql, Object... objects) {
        getConnection();
        try {
            statement = conn.prepareStatement(sql);
            if (objects != null && objects.length > 0) {
                for (int i = 0; i < objects.length; i++) {
                    statement.setObject((i + 1), objects[i]);
                }
            }
            return statement.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 增删改的通用方法
     */
    public int update(String sql, Object... objects)  {
        getConnection();
        int num = 0;
        try {
            statement = conn.prepareStatement(sql);
            if (objects != null) {
                for (int i = 0; i < objects.length; i++) {
                    statement.setObject((i + 1), objects[i]);
                }
            }
            num = statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return num;
    }
}

但是这个简单版的basedao只适合测试时使用,实际的项目中使用会出现很多问题
1、首先就是事务的控制问题,由于jdbc是自动提交事务的,所以当需要控制事务时必须设置手动提交
2、并发问题,当同时又大量数据库操作时产生大量的连接,且每个数据库操作都会使用一个连接,效率低下
所以我们针对这种情况可以优化basedao工具类
1、使用properties配置文件将数据库连接信息统一管理,方便后期维护
2、使用dbcp数据源(或者其他数据源)增强连接效率
3、使用ThreadLocal来保存连接,方便与事务的管理
增强后的basedao

package com.dao;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSourceFactory;

import com.test.MainTest;

/**
 * 增强型basedao
 * @author Administrator
 *
 */
@SuppressWarnings("static-access")
public class BaseDao {
    //ThreadLocal用来存储数据的,使用范围:仅在当前线程内使用,单线程共享
    private static ThreadLocal threadLocal = new ThreadLocal(); 
    private static DataSource ds;
    //使用连接池技术获取数据库连接,现有的连接池技术比较多,java常用的有DBCP和C3P0
    /**
     * 静态代码块,用于初始化的时候创建数据源,只会创建一次,整个服务器共享一个数据源
     */
    static{
        InputStream is = BaseDao .class.getClassLoader().getResourceAsStream("config/jdbc.properties");
        Properties prop = new Properties();
        try {
            prop.load(is);
            ds = new BasicDataSourceFactory().createDataSource(prop);
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
    /**
     * 用户获取数据库连接的,是通过threadlocal来实现单线程共享一个数据裤连接
     * 默认是自动提交事物的
     * @return
     */
    public static Connection getConnection() {
        return getConnection(true);
    }

    /**
     * 如果需要手动提交事物,在调用时传递false来设置手动提交
     * @param flag
     * @return
     */
    public static Connection getConnection(boolean flag) {
        //如果threadlocal对象里没有存入conn对象,那么获取的结果为null
        Connection conn = threadLocal.get();
        if(conn==null){ //说明是第一次获取连接,那么通过jdbc获取并存入threadlocal
            try {
                conn = ds.getConnection();
                conn.setAutoCommit(flag);
                threadLocal.set(conn);
            } catch (Exception e) {
                e.printStackTrace();
            } 
        }
        return conn;
    }


    /**
     * 数据库事物提交的方法
     */
    public static void commit(){
        Connection conn = threadLocal.get();
        if(conn!=null){
            try {
                conn.commit();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 数据库事物回滚的方法
     */
    public static void rollback(){
        Connection conn = threadLocal.get();
        if(conn!=null){
            try {
                conn.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 数据库事物回滚的方法
     */
    public static void close(){
        Connection conn = threadLocal.get();
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 执行增删改的通用方法
     * @param sql
     * @param param
     * @return
     */
    public int executeUpdate(String sql,Object[] param){
        Connection conn = getConnection();
        int num = 0;
        try {
            PreparedStatement pstmt = conn.prepareStatement(sql);
            if(param!=null){
                for(int i=0;i1), param[i]);
                }
            }
            num = pstmt.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return num;
    }

    /**
     * 执行查询的通用SQL
     * @param sql
     * @param param  是可变参数,可以传递0个或任意多个参数,最终组成一个数组
     * @return
     */
    public ResultSet executeQuery(String sql,Object... param){
        Connection conn = getConnection();
        try {
            PreparedStatement pstmt = conn.prepareStatement(sql);
            if(param!=null){
                for(int i=0;i1), param[i]);
                }
            }
            return pstmt.executeQuery();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

jdbc配置文件

url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
driverClassName=oracle.jdbc.driver.OracleDriver
username=scott
password=123
initialSize=10
maxActive=100

你可能感兴趣的:(开发教程)