在用JDBC的过程中,我们可能会根据实际需求来编写N个查询方法(特别是新手),这样虽然简单,但是会产生大量的重复代码。且不容易维护。那么有没有办法,只编写一个方法呢?
通过分析,不难发现,对于查询,我们发现除了SQL语句的变动意外,就是实体类的变动。其它基本保持不变。
于是 我们就可以利用Java反射就可以做到这一点,但需要注意一个问题:就是实体类的属性名一定要和数据库查询结果的字段名名保持一致。(如果有别名,就和别名一致)
以下是我萌新的个人思路,大神看看就好。
比如我们数据库中有以下一张表:
那么我们就应该对应一个实体类:
public class User
{
private int id;
private String username;
private char sex;
private String tell;
//GET和SET方法......略
}
查询代码如下:
public class Test
{
public static void main(String[] args) throws Exception
{
//对于其它的查询,我们只需要带入一个SQL参数,和一个实体类的Class就可以了。不过用的时候记得强制转换回来
List<Object> obj = query("select * from userinfo;",User.class);
//打印查询结果
for(User u : obj.toArray(new User[0]))
{
System.out.println(u.toString());
}
}
public static List<Object> query(String querySql,Class objClass) throws Exception
{
//查询结果集
List<Object> queryResult = new ArrayList<Object>();
//数据库连接,这段代码应该写出去,这里为了演示,写里面了
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mydatabase";
String username = "root";
String password = "12345678";
Connection conn = DriverManager.getConnection(url, username, password);
//执行查询
PreparedStatement preparedStatement = conn.prepareStatement(querySql);
ResultSet result = preparedStatement.executeQuery();
//获取实体对象的方法和私有属性
Map<String,Method> objMap = new HashMap<String,Method>();
Field [] fields = objClass.getDeclaredFields();
Method [] methods = objClass.getDeclaredMethods();
Field.setAccessible(fields, true);
for(Method m:methods)
{
for(Field f:fields)
{
if(m.getName().toLowerCase().startsWith("set")
&& m.getName().toLowerCase().contains(f.getName().toLowerCase()))
{
objMap.put(f.getName(), m);
}
}
}
//获取结果
while(result.next())
{
//利用反射执行SET方法
Object obj = objClass.newInstance();
for(String fieldValue : objMap.keySet())
{
Method setMethod = objMap.get(fieldValue);
String paramenterType = setMethod.getParameterTypes()[0].getSimpleName();
if(paramenterType.toLowerCase().equals("string"))
{
setMethod.invoke(obj, result.getString(fieldValue));
}
else if(paramenterType.toLowerCase().equals("int"))
{
setMethod.invoke(obj, result.getInt(fieldValue));
}
else if(paramenterType.toLowerCase().equals("char"))
{
setMethod.invoke(obj, result.getString(fieldValue).toCharArray()[0]);
}
//。。。。。。。。这里可以把剩余的基本数据类型补充完整
}
queryResult.add(obj);
}
preparedStatement.close();
conn.close();
return queryResult;
}
}