需求实现思路效果展示字段数据相关
注解@Row属性信息的实体类入口 小结
需求将ResultSet中的数据直接封装成实体类。
实现思路- 由实体类获取字段数据由字段数据取对应字段的值反射创建对象,注入属性值保留字段数据,以便下次访问
画渣,见谅~
项目地址:https://gitee.com/zxing2021/orm.git
效果展示测试代码,关键只有中间几行:
@Test
public void fun1() {
PreparedStatement ps = null;
try {
ps = JDBCUtil.getStatement("select id,name,age from student");
ResultSet rs = ps.executeQuery();
List list = ResultSetHandler.getList(rs, Student.class);
for (Student student : list) {
System.out.println(student);
}
JDBCUtil.commitAndClose(ps);
} catch (SQLException throwables) {
throwables.printStackTrace();
JDBCUtil.rollbackAndClose(ps);
}
}
运行效果:
用以指定列名:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Row {
String value();
}
属性信息的实体类
用以存放属性的信息:
@Data
public class RowInfo {
private final String colName;
private final String attrName;
private final String attrType;
}
解析一个属性:
private RowInfo(Field field) {
Row row = field.getDeclaredAnnotation(Row.class);
if (row != null) {
this.colName = row.value();
this.attrName = field.getName();
this.attrType = field.getType().getSimpleName();
} else {
this.colName = null;
this.attrName = null;
this.attrType = null;
}
}
简单判空:
public Boolean isNull() {
return this.colName == null;
}
解析一个实体类:
public static ListcreateList(Class target) { List result = new ArrayList<>(); for (Field field : target.getDeclaredFields()) { RowInfo info = new RowInfo(field); if (!info.isNull()) { result.add(info); } } return result; }
从ResultSet中获取该属性的值:
//由ResultSet获取值
public Object getValue(ResultSet resultSet) throws SQLException {
switch (attrType) {
case "Integer":
return resultSet.getInt(colName);
case "String":
return resultSet.getString(colName);
default:
return null;
}
}
入口
容器,用以存放解析结果,以免每次都要重新解析:
public class ResultSetHandler {
private static final ConcurrentHashMap> map = new ConcurrentHashMap();
//...
}
获取一个类的解析结果:
private static ListgetList(Class target) { List result = map.get(target); if (result == null) { List parse = RowInfo.createList(target); map.put(target, parse); return parse; } else { return result; } }
入口方法:
public staticList getList(ResultSet resultSet, Class target) { List result = new ArrayList<>(); try { while (resultSet.next()) { E e = create(resultSet, target); result.add(e); } } catch (SQLException e) { e.printStackTrace(); } return result; }
创建实体的方法:
private staticE create(ResultSet resultSet, Class target) { E result = null; try { //实例化 result = target.newInstance(); for (RowInfo info : getList(target)) { Object attr = info.getValue(resultSet); Method method = target.getMethod("set" + upper(info.getAttrName()), attr.getClass()); //属性赋值 method.invoke(result, attr); } } catch (Exception e) { e.printStackTrace(); } return result; }
杂七杂八:
private static String upper(String name) {
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
小结
ORM思想:实体类与数据表一一对应。
此处只是单表映射成实体类。



