Java连接数据库,增删改查操作时的封装思想

面向对象程序设计语言的四大特点之一就是:封装。正如Java,其在固定的类中封装了很多方法,这些方法我们不用管它的底层是怎么实现的,只要知道它如何用就可以进行编程。所以,我们在平时项目的过程中也应该考虑到这一点,从而减少代码量,达到应有的目的。

我的以下代码是对数据库的一系列操作进行了封装,封装成了一个名字叫做DButil的类,在这个类中存在很多方法可以去对数据库进行一系列的操作。其中最主要的是这个类里面的query方法,即查询方法,在访问数据库时增删改这三个操作其实可以统称为一个,因为他们不需要返回结果集,只需要把相对应的sql语句发送到数据库去执行。但是查询方法是要把查询的结果作为一个结果集返回给用户的。然而如果每次都使用ResultSet对象是不会对结果进行长时间存储的,所以说每次都要去查询一次,并且对ResultSet对象这一结果集进行一系列操作也不方便,所以在以下代码中没一次查数据库都有一个类与之对应,然后利用Java的反射机制通过查询出来的结果创建一个与这个类相对应的一个实例,其数据便存在了类的对象中,然后再把这个实例存储在list中,作为用户对该方法调用后的返回,对list集合操作起来比对ResultSet对象操作起来容易得多。其中,一张表对应一个类,并且表中列名要与类中相对应的属性名保持一致。这一特点在代码中也是可以看出的,因为利用反射机制创建对象的实例时,用到的fieldname便是从数据库中查询出的列名。

具体代码如下:

package com.util;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

public class DButil {
	//实例化连接池
	public static Vector<Connection> connectionPool = new Vector<Connection>();
	//初始化连接池
	static{
		try {
			Class.forName("com.mysql.jdbc.Driver");//加载驱动
			for(int i = 0;i<10;i++){
			Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3307/shengshiliandong", "root", "admin");//得到连接对象
			connectionPool.add(connection);
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	//取连接
	public static Connection getConnection(){
		Connection connection = connectionPool.get(0);
		connectionPool.remove(0);
		return connection;
	}
	//释放连接
	public static void releaseConnection(Connection connection){
		connectionPool.add(connection);
	}
	//增删改
	public static void zsg(String sql,Object...objects){//Objects...为不定数组
		Connection connection = null;
		try {
			connection = getConnection();//取连接
			PreparedStatement preparedStatement = connection.prepareStatement(sql);
			if(objects != null){//给sql语句中的问号赋值
				for(int i = 0;i<objects.length;i++){
					preparedStatement.setObject(i+1,objects[i] );
				}
			}
			int n = preparedStatement.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			releaseConnection(connection);//释放连接
		}
	}
	//查询
	public static List query(Class c,String sql,Object...objects){
		List list = new ArrayList();
		Connection connection = getConnection();
		try {
			PreparedStatement preparedStatement = connection.prepareStatement(sql);
			if(objects != null){//给sql语句中的?号赋值
				for(int i = 0;i<objects.length;i++){
					preparedStatement.setObject(i+1, objects[i]);
				}
			}
			ResultSet resultSet = preparedStatement.executeQuery();//发送SQL语句,并返回结果集
			ResultSetMetaData resultSetMetaData = resultSet.getMetaData();//得到resultSet对象相对应的resultSetMetaData对象
			int count = resultSetMetaData.getColumnCount();//得到ResultSet对象的总列数
			while(resultSet.next()){//外层while循环用于控制“行”
				Object object = c.newInstance();//创建c所代表的类的新实例
				for(int i = 0;i<count;i++){//for循环用于控制“列”
					String fieldName = resultSetMetaData.getColumnLabel(i+1);//获取打印输出和显示的指定的第i+1列的标题
					Field field = c.getDeclaredField(fieldName);//返回一个 Field 对象,该对象反映此 Class 对象所表示的类的指定已声明字段
					field.setAccessible(true);//值为 true用于指示反射的对象在使用时应该取消 Java 语言访问检查,即使得field可以访问此class对象所对应的类的私有化属性
					field.set(object, resultSet.getObject(i+1));//将指定对象变量object上此 Field 对象表示的字段设置为指定的新值resultSet.getObject(i+1)
				}
				list.add(object);
			}
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			releaseConnection(connection);//释放连接
		}
		return list;//返回储存着对象实例的list集合
	}
	
	
}

猜你喜欢

转载自blog.csdn.net/My_name_is_ZwZ/article/details/81084009