知识点:
(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;
}
}
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());
}
}
}