JDBC数据库连接池连接数据库及数据库操作DAO层设计通用更新及查询方法(一)

该篇文章介绍了数据库连接池获取数据库连接以及数据库操作的基本使用,然后主要提供了java项目案例中dao层的一种设计,利用反射的原理定义了通用的查询方法可以对应所有的表和实例。文章中的每段代码都提供了详细的注释及逻辑步骤

首先导入数据库连接的所需要的jar包:

       mysql数据库连接驱动:mysql-connector-java-5.1.47-bin.jar

       数据库连接池使用到的jar包:commons-dbcp2-2.4.0.jar

       可能还需要的jar包:commons-logging-1.2.jar       commons-pool2-2.6.0.jar

然后准备配置文件:

      在src下创建dbcp.properties文件

文件内容:

#数据库驱动
driverClassName=com.mysql.jdbc.Driver
#数据库连接地址    端口号    数据库名
url=jdbc:mysql://localhost:3306/text
#数据库用户名
username=root
#密码
password=123456
#连接池最大数据库连接数  0表示无限制
maxActive=30
#最大空闲数  0表示无限制
maxIdle=10
#最大建立连接的等待时间,如果超过改时间接到异常,-1表示无限制
maxWait=1000
#超过removeAbandonTimeout时间后是否进行无用连接的回收默认为false
removeAbandoned=true
#超出时间限制,回收没有使用的连接  默认300秒
removeAbandonedTimeout=180

一、通过数据库连接池获取数据库连接并设计工具类获取数据库连接和关闭连接

工具类JDBCTool

扫描二维码关注公众号,回复: 3859685 查看本文章

class JDBCTool{

         public static Connection getConnection(){}  //获取数据库的连接

         public static void colseAll(Connection connection,Statement statement,ResultSet resultSet){}  //关闭所有连接

}

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

import org.apache.commons.dbcp2.BasicDataSourceFactory;

/**
 * @author Administrator
 *数据库连接工具   获取和关闭数据连接
 */
public class JDBCTools {
	/**
	 * 通过数据库连接池 获取数据库链接
	 * @throws Exception 
	*/
	private static Properties properties = new Properties();    //属性集配置信息对象
	private static DataSource dataSource = null;                //数据源对象
	
	//静态代码块加载驱动
	static{
		//获取配置文件的流对象
		InputStream inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("dbcp.properties");
		try {
			//加载配置问价获取配置信息
			properties.load(inStream);
			//获取数据原对象
			dataSource = BasicDataSourceFactory.createDataSource(properties);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//获取数据库连接对象
	public static Connection getConnection() throws Exception{
		return dataSource.getConnection();
	}
	
	/**
	 * 关闭数据所有连接
	 * @param connection
	 * @param statement
	 * @param set
	 */
	public static void colseAll(Connection connection,Statement statement,ResultSet resultSet){
		if(resultSet != null){
			try {
				resultSet.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if(statement != null){
			try {
				statement.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if(connection != null){
			try {
				connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

二、定义一个工具类方法利用反射为实例对象的属相赋值

//obj实例对象   fieldName属性名   value属性值

public static void setFielValue(Object obj,String fieldName,Object value){}

public class ReflectionUtils {
	
	public static void setFielValue(Object obj,String fieldName,Object value ) throws Exception{
		//获取类的class对象
		Class clazz = obj.getClass();
		//获取属性对象
		Field f = clazz.getDeclaredField(fieldName);
		//设置属性为可设置
		f.setAccessible(true);
		//设置属性值
		f.set(obj, value);
	}
}

三、定义一个接口DaoFun定义所有的功能  

public interface DaoFun {
	/**
	 *//数据库更新操作,sql可以是update,insert,delete的预编译语句,可变参数为预编译语句中占位符的值
	 * @param sql
	 * @param args
	 */
	void updata(String sql,Object ... args);
	
	/**
	 *//查询单条记录  返回对应的实例对象 ,clazz为对应实例类的class对象,SQL为select的预编译语句,可变参数是对应的占位符的值
	 * @param clazz
	 * @param sql
	 * @param args
	 */
	<T> T getObject(Class<T> clazz,String sql,Object ... args );
	
	/**
	 * //查询多条记录,返回对应实例对象的集合,clazz为对应实例类的class对象,SQL为select的预编译语句,可变参数是对应的占位符的值
	 * @param clazz
	 * @param sql
	 * @param args
	 */
	<T> List<T> getObjectList(Class<T> clazz, String sql,Object ... args);
	
	/**
	 * 查询某条记录的某一个字段值
	 * @param clazz
	 * @param sql
	 * @param args
	 */
	<E> E getForValue(String sql,Object ... args);
}

四、定义一个基类BaseDao实现DaoFun接口,该类的方法可以定义成protected,定义dao层的实现类来继承该类即可直接使用该类的方法。

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.mysql.jdbc.ResultSetMetaData;
import com.qy.util.JDBCTools;
import com.qy.util.ReflectionUtils;

public class BaseDAO implements DaoFun {
	
	private Connection connection = null;     //数据库连接对象
	private PreparedStatement statement = null;  //预编译语句对象
	private ResultSet resultSet = null;          //查询数据集对象
	
	@Override
	public void updata(String sql, Object... args) {
		try {
			//获取数据库连接
			connection = JDBCTools.getConnection();
			//获取预编译语句对象
			statement = connection.prepareStatement(sql);
			//设置预编译语句的参数值
			for(int i = 0; i < args.length; i ++){
				statement.setObject(i + 1, args[i]);
			}
			int a = statement.executeUpdate();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally{
			JDBCTools.colseAll(connection, statement, resultSet);
		}
		
	}

	@Override
	public <T> T getObject(Class<T> clazz, String sql, Object... args) {
		T entity = null;
		try {
			//1.获取connection
			connection = JDBCTools.getConnection();
			//2.获取preparedStatement
			statement = connection.prepareStatement(sql);
			//3.填充占位符
			for (int i = 0; i < args.length; i++) {
				statement.setObject(i + 1, args[i]);
			}
			//4.进行查询
			resultSet = statement.executeQuery();
			//5.准备map<String,Object> 字段名的别名  字段值
			if(resultSet.next()){
				Map<String,Object> map = new HashMap<String, Object>();
				//6.得到ResultSetMetaData对象
				ResultSetMetaData rsmd = (ResultSetMetaData) resultSet.getMetaData();
			//7.处理resultSet  
				//8.有ResultSetMetaData对象得到结果集中有多少列
				int columnCount = rsmd.getColumnCount();
				//9.由resultSetMetaData 得到每一列的别名  ResultSet得到值
				for (int i = 0; i < columnCount; i++) {
					String columnLabel = rsmd.getColumnLabel(i + 1);
					Object columnValue = resultSet.getObject(columnLabel);
					//10.填充map对象
					map.put(columnLabel, columnValue);
				}
				//11利用反射获取class对象
				entity = clazz.newInstance();
				//12.遍历map对象利用反射填充对象的属性值 属性名为map的key 属性值为map中的value	
				for(Map.Entry<String, Object> entry : map.entrySet()){
					String propertyName = entry.getKey();
					Object value = entry.getValue();
                     //利用反射对属相赋值
					ReflectionUtils.setFielValue(entity, propertyName, value);
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally{
			JDBCTools.colseAll(connection, statement, resultSet);
		}
		return entity;
	}

	@Override
	public <T> List<T> getObjectList(Class<T> clazz, String sql, Object... args) {
		ArrayList<T> list = new ArrayList<T>();
		T entity = null;
		try {
			//1.获取connection
			connection = JDBCTools.getConnection();
			//2.获取preparedStatement
			statement = connection.prepareStatement(sql);
			//3.填充占位符
			for (int i = 0; i < args.length; i++) {
				statement.setObject(i + 1, args[i]);
			}
			//4.进行查询
			resultSet = statement.executeQuery();
			//5.准备map<String,Object> 字段名的别名  字段值
			Map<String,Object> map = new HashMap<String, Object>();
			//6.得到ResultSetMetaData对象
			ResultSetMetaData rsmd = (ResultSetMetaData) resultSet.getMetaData();
			//8.有ResultSetMetaData对象得到结果集中有多少列
			int columnCount = rsmd.getColumnCount();
			while(resultSet.next()){
			//7.处理resultSet  
				//9.由resultSetMetaData 得到每一列的别名  ResultSet得到值
				for (int i = 0; i < columnCount; i++) {
					String columnLabel = rsmd.getColumnLabel(i + 1);
					Object columnValue = resultSet.getObject(columnLabel);
					//10.填充map对象
					map.put(columnLabel, columnValue);
				}
				//11利用反射获取class对象
				entity = clazz.newInstance();
				//12.遍历map对象利用反射填充对象的属性值 属性名为map的key 属性值为map中的value	
				for(Map.Entry<String, Object> entry : map.entrySet()){
					String propertyName = entry.getKey();
					Object value = entry.getValue();
                    //利用反射为对象属性赋值
					ReflectionUtils.setFielValue(entity, propertyName, value);
				}
				list.add(entity);
			}
		}catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally{
			JDBCTools.colseAll(connection, statement, resultSet);
		}
		return list;
	}

	@Override
	public <E> E getForValue(String sql, Object... args) {
		
		try {
		//1.获取connection
		connection = JDBCTools.getConnection();
		//2.获取preparedStatement
		statement = connection.prepareStatement(sql);
		//3.填充占位符
		for (int i = 0; i < args.length; i++) {
			statement.setObject(i + 1, args[i]);
		}
		//4.进行查询
			resultSet = statement.executeQuery();
		//处理resultSet
			if(resultSet.next()){
				return  (E) resultSet.getObject(1);
			}
		} catch (Exception e1) {
			
			e1.printStackTrace();
		}finally{
			JDBCTools.colseAll(connection, statement, resultSet);
		}
		return null;
	}
	
}

本篇文章主要介绍了dao层的一种设计,定义通用的数据库操作方法,提高程序设计时提高代码的复用性,下篇文章主要介绍该篇定义方法的使用。

猜你喜欢

转载自blog.csdn.net/weixin_42758003/article/details/83301482
今日推荐