从配置文件读取数据连接信息,利用泛型和java反射机制,写一个公共的增删改查数据库操作类

知识点:

(1)泛型:可以加强类型安全,减少类型转换

(2)java反射机制:可以取得任意一个已经class的内部信息,例如属性和方法

背景:

最近在学习java,然后就看了spring jdbc。对于菜鸟来说,看得实在头大,然而还有强迫症作祟最是要不得。又要导入common的相关jar包,又要导入mysql的jar包,还要导入spring的相关jar包。对于还不是很清楚每个jar包到底有哪些作用就拿来用,各种难受。所以觉得还是自己写个数据库处理类方便,只要导入一个mysql的jar包就可以了。


过程:

在写的过程中,增删改三个操作直接写一个公共调用方法就可以了,然后写到查询就头疼了。我想要实现的是,这个方法谁来调用都可以,会返回一个你想要的对象集合。所以菜鸟想要自学最好能有一个大神朋友,随时给予指导。各种矫情不好意思下,把想法告诉了老公,老公夸了我有这个想法是好的,然后可以尝试用泛型和反射来实现看看。


结果:

虽然写出来了,可能也经不起推敲,对于自己写过什么也记不住的尿性,还是写篇博文做个知识备忘,


1.新建一个java项目,项目名称dbProjo,要导入mysql的jar包



2.数据库连接属性文件:dbConnection.properties

# 驱动名称
driverClassName=com.mysql.jdbc.Driver
# 数据库连接地址
url=jdbc:mysql://127.0.1:3306/myWeb
# 数据库连接账号和密码
username=root
password=root


3..两个测试用的实体类

a)User.java

package dbUtil;

/**
 * 用户类
 * 
 * @author huaernan
 * 
 */
public class User {
	// 登录账号
	private String username;
	// 登录密码
	private String password;
	// 真实名称
	private String realname;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getRealname() {
		return realname;
	}

	public void setRealname(String realname) {
		this.realname = realname;
	}

	/**
	 * 输出信息方法
	 */
	public void outPutString() {
		System.out.println("这个用户的账号是:" + this.username + ",登录密码是:"
				+ this.password);
	}
}



b)Product.java

package dbUtil;

/**
 * 商品类
 * 
 * @author huaernan
 * 
 */
public class Product {
	// 商品名称
	private String proName;
	// 商品价格
	private String proPrice;
	// 商品展示地址
	private String proShowUrl;

	public String getProName() {
		return proName;
	}

	public void setProName(String proName) {
		this.proName = proName;
	}

	public String getProPrice() {
		return proPrice;
	}

	public void setProPrice(String proPrice) {
		this.proPrice = proPrice;
	}

	public String getProShowUrl() {
		return proShowUrl;
	}

	public void setProShowUrl(String proShowUrl) {
		this.proShowUrl = proShowUrl;
	}

}


4.利用泛型实例对象,用反射得到该对象,获得对象的方法,调用set方法给属性赋值

GenericClassBean.java

package dbUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 泛型类,获取实例化对象
 * 
 * @author huaernan
 * 
 * @param <T>
 */
public class GenericClassBean<T> {

	private static Class beanClass;

	public GenericClassBean(Class beanClass) {
		this.beanClass = beanClass;
	}

	/**
	 * 获取对象示例
	 * 
	 * @param t
	 * @return
	 */
	public T getClassBean(T t) {
		try {
			t = (T) beanClass.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
		return t;

	}

	/**
	 * 给对象属性赋值
	 * 
	 * @param propertyName
	 *            对象的set方法名称
	 * @param paropertyValue
	 *            对象set方法set的值
	 */
	public static void setClassBeanPropertyValue(Object object,
			String propertyName, String paropertyValue) {
		Method method = null;
		/*
		 * propertyName对应的是对象的属性名称,和数据库列名称也要相同,例如User类的属性有username,
		 * 对应的数据库字段也是username,对应的方法名称就是setUsername
		 */
		propertyName = propertyName.substring(0, 1).toUpperCase()
				+ propertyName.substring(1);
		String setMethod = "set" + propertyName;
		try {
			// 找到对象的set方法
			method = beanClass.getMethod(setMethod, String.class);
		} catch (NoSuchMethodException | SecurityException e) {
			e.printStackTrace();
		}
		try {
			// 调用方法set方法给属性赋值
			method.invoke(object, paropertyValue);
		} catch (IllegalAccessException | IllegalArgumentException
				| InvocationTargetException e) {
			e.printStackTrace();
		}
	}

}

5.共用类,数据库增删改查方法

DBUtil.java

package dbUtil;

import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import com.mysql.jdbc.PreparedStatement;

/**
 * 公共数据库操作类
 * 
 * @author huaernan
 * 
 */
public class DBUtil {
	private static Properties properties;
	private static FileReader fileReader;

	/**
	 * 获取数据库连接
	 * 
	 * @return
	 */
	public static Connection getConn() {
		Connection conn = null;
		try {
			fileReader = new FileReader("src/dbUtil/dbConnection.properties");
			properties = new Properties();
			properties.load(fileReader);
			// 加载mysql的驱动
			Class.forName(properties.getProperty("driverClassName"));
			// 建立数据库连接
			conn = DriverManager.getConnection(properties.getProperty("url"),
					properties.getProperty("username"),
					properties.getProperty("password"));

		} catch (Exception e) {
			e.printStackTrace();
		}

		return conn;

	}

	/**
	 * 关闭数据库连接
	 * 
	 * @param connection
	 * @param preparedStatement
	 */
	public static void close(Connection connection,
			PreparedStatement preparedStatement) {
		try {
			preparedStatement.close();
			connection.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 插入、删除、修改
	 * 
	 * @param sql
	 *            插入语句
	 * @param params
	 *            sql中?占位符对应的值
	 * @return
	 */
	public static boolean insertUpdateDelete(String sql, Object[] params) {
		Connection connection = getConn();
		PreparedStatement preparedStatement = null;
		// resultCode执行sql返回的结果值
		int resultCode = -1;
		try {
			preparedStatement = (PreparedStatement) connection
					.prepareStatement(sql);
			for (int i = 1; i < params.length + 1; i++) {
				// 赋值的时候,索引是从1开始的
				preparedStatement.setObject(i, params[i - 1]);
			}
			resultCode = preparedStatement.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 关闭连接
			close(connection, preparedStatement);
		}
		return resultCode == 1 ? true : false;
	}

	/**
	 * 查询所有或者根据条件查询
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	public static List<Object> select(String sql, Class classname,
			Object[] params) {
		// 获取数据库连接
		Connection connection = getConn();
		// 查询结果集
		List<Object> objectList = new ArrayList<Object>();
		try {
			// 执行说起来
			PreparedStatement preparedStatement = (PreparedStatement) connection
					.prepareStatement(sql);
			// 如果有查询条件
			if (params != null) {
				for (int i = 1; i < params.length + 1; i++) {
					preparedStatement.setObject(i, params[i - 1]);
				}
			}
			ResultSet resultSet = preparedStatement.executeQuery();
			// 要查的列表数量
			int columnCount = resultSet.getMetaData().getColumnCount();
			while (resultSet.next()) {
				// 构建一个对象实例
				GenericClassBean classBean = new GenericClassBean(classname);
				Object beanObject = (Object) classBean.getClassBean(classBean);

				for (int i = 1; i <= columnCount; i++) {
					// 获取查询的字段名称
					String columnName = resultSet.getMetaData()
							.getColumnName(i);
					// 获取查询的字段的值
					String value = resultSet.getString(i);
					// 给对象属性赋值
					classBean.setClassBeanPropertyValue(beanObject, columnName,
							value);
				}
				objectList.add(beanObject);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return objectList;

	}

}

6.测试类,写个main方法来测试效果

MainTest.java

package dbUtil;

import java.util.List;

public class MainTest {
	// 测试效果
	public static void main(String[] args) {
		String params[] = { "test", "test", "这是一个测试数据" };
		// 插入
		String insertSql = "INSERT INTO USER(username,password,realname)VALUES(?,?,?)";
		// DBUtil.insertUpdateDelete(insertSql, params);

		// 查询语句1
		String selectSql_1 = "select username,password,realname from user";
		// DBUtil.select(selectSql_1, null);

		// 查询语句2
		String selectSql_2 = "select username,password,realname from user where username=?";
		params = new String[] { "admin" };

		// 查询语句3
		String selectSql_3 = "select proName,proPrice,proShowUrl from product";
		List<Object> productList = DBUtil.select(selectSql_3, Product.class,
				null);
		//
		for (int i = 0; i < productList.size(); i++) {
			Product pro = (Product) productList.get(i);
			System.out.println(pro.getProName());
		}
	}
}




  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值