在JAVA中JDBC的访问是比较麻烦的,为此可以使用封装的方法构建一个封装性较好的JDBC工具类,提高编程的可复用性。
具体的想法是:可以生成一个类封装JDBC的connection和statement的构建,使用Property配置文件来保存JDBC访问的路径以及驱动,这样可以有较好的可维护性,再使用反射特性构建一个DataUtil类封装JDBC获取的结果集,并把其显示出来。
1.首先新建一个jdbc.property文件存放jdbc的相关属性
[html] view plaincopy
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/user
jdbc.user=root
jdbc.pass=123456
通过PropertyUtil类可以获得jdbc的属性
[java] view plaincopy
package jdbc;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 属性工具类
*/
public class PropertiesUtil {
//属性列表
private static Properties properties = new Properties();
//配置文件的路径
private static String CONFIG = "/cfg/jdbc.properties";
//读取资源文件, 设置输入流
private static InputStream is = PropertiesUtil.class.getResourceAsStream(CONFIG);
//数据库驱动
public static String JDBC_DRIVER;
//jdbc连接url
public static String JDBC_URL;
//数据库用户名
public static String JDBC_USER;
//数据库密码
public static String JDBC_PASS;
static {
try {
//加载输入流
properties.load(is);
//获得配置的各个属性
JDBC_DRIVER = properties.getProperty("jdbc.driver");
JDBC_URL = properties.getProperty("jdbc.url");
JDBC_USER = properties.getProperty("jdbc.user");
JDBC_PASS = properties.getProperty("jdbc.pass");
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.建立JDBCExecutor类来封装JDBC的数据源获取工作,其中通过单例模式获取数据库的连接
[java] view plaincopy
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCExecutor{
//获得驱动
private static String DRIVER = PropertiesUtil.JDBC_DRIVER;
//获得url
private static String URL = PropertiesUtil.JDBC_URL;
//获得连接数据库的用户名
private static String USER = PropertiesUtil.JDBC_USER;
//获得连接数据库的密码
private static String PASS = PropertiesUtil.JDBC_PASS;
//连接对象
private Connection connection;
//维护一个本类型的对象
private static JDBCExecutor jdbcExecutor;
//Statement对象,可以执行SQL语句并返回结果
private Statement stmt;
//私有构造器
private JDBCExecutor() {
try {
//初始化JDBC驱动并让驱动加载到jvm中
Class.forName(DRIVER);
//创建数据库连接
connection = DriverManager.getConnection(URL, USER, PASS);
//创建Statement对象
stmt = connection.createStatement();
} catch (Exception e) {
throw new JDBCException(e.getMessage());
}
}
//提供一个静态方法返回本类的实例
public static JDBCExecutor getJDBCExecutor() {
//如果本类所维护jdbcExecutor属性为空,则调用私有的构造器获得实例
if (jdbcExecutor == null) {
jdbcExecutor = new JDBCExecutor();
}
return jdbcExecutor;
}
/*
* 执行一句查询的sql
*/
public ResultSet executeQuery(String sql) {
try {
//利用Statement对象执行参数的sql
ResultSet result = stmt.executeQuery(sql);
return result;
} catch (Exception e) {
throw new QueryException(e.getMessage());
}
}
//执行单句INSERT、UPDATE 或 DELETE 语句, 如果执行INSERT时, 返回主键
public int executeUpdate(String sql) {
int result = -1;
try {
//执行SQL语句
stmt.executeUpdate(sql);
//获得主键
ResultSet rs = stmt.getGeneratedKeys();
while(rs.next()) {
//返回最后一个主键
result = rs.getInt(1);
}
rs.close();
return result;
} catch (Exception e) {
throw new QueryException(e.getMessage());
}
}
}
3.为了将JDBC查询操作的数据获取,封装数据获取的类
[java] view plaincopy
package jdbc;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collection;
import vo.User;
import dao.impl.UserDAOImpl;
/**
* 数据转换工具类
*/
public class DataUtil {
static UserDAOImpl us=new UserDAOImpl();
//将rs中的值封装成一个集合
public static Collection getDatas(Collection result, ResultSet rs, Class clazz) {
try {
while (rs.next()) {
//创建类的实例
Object vo = clazz.newInstance();
//获取本对象的属性
Field[] fields = clazz.getDeclaredFields();
//获取父类的属性
// Field[] superFields = clazz.getSuperclass().getDeclaredFields();
// //父类的属性和自己的属性相加
// Field[] allFields = addFields(superFields, fields);
//遍历所有的属性
for (Field field : fields) {
//获得setter方法的方法名
String setterMethodName = getSetterMethodName(field.getName());
//获得setter方法
Method setterMethod = clazz.getMethod(setterMethodName, field.getType());
invokeMethod(rs, field, vo, setterMethod);
}
result.add(vo);
}
rs.close();
} catch (Exception e) {
e.printStackTrace();
throw new DataException(e.getMessage());
}
return result;
}
//执行一个方法, 从ResultSet中获取一个字段的数据, 调用vo的setter方法
private static void invokeMethod(ResultSet rs, Field field, Object vo,
Method setterMethod) {
try {
//当使用ResultSet获取某个字段的时候, 如果没有该字段, 会出现SQLException, 在这里忽略该异常
String value = rs.getString(field.getName());
//从ResultSet中获取与该对象属性名一致的字段, 并执行setter方法
setterMethod.invoke(vo, value);
} catch (Exception e) {
//忽略异常
}
}
//根据属性名获得setter方法的方法名
private static String getSetterMethodName(String fieldName) {
String begin = fieldName.substring(0, 1).toUpperCase();
String end = fieldName.substring(1, fieldName.length());
String methodName = "set" + begin + end;
return methodName;
}
//测试方法
public static void main(String[] args) {
JDBCExecutor executor = JDBCExecutor.getJDBCExecutor();
us.AddUser(new User("111",12,"333"));
// ResultSet rs = executor.executeQuery("select * from user");
// Collection<User> result = DataUtil.getDatas(new ArrayList<User>(), rs,
// User.class);
// for (User user : result) {
// System.out.println(user.getName());
// }
}
}
通过上面Main方法中的调用,可以看出能够很轻易的操纵JDBC连接了。