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

来源:互联网 发布:阿里云域名备案服务号 编辑:程序博客网 时间:2024/05/22 00:17

知识点:

(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=rootpassword=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);// 查询语句1String selectSql_1 = "select username,password,realname from user";// DBUtil.select(selectSql_1, null);// 查询语句2String selectSql_2 = "select username,password,realname from user where username=?";params = new String[] { "admin" };// 查询语句3String 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());}}}




1 0