Spring JDBC rowmapper带有类HieAschies
-
11-09-2019 - |
题
我想知道社区如何考虑与Spring JDBC绘制阶级层次结构的“最佳实践”。
我们没有能力使用完整的ORM工具,但是我们正在使用Spring JDBC来减轻JDBC的某些繁琐本质。我们经常利用的一类是BeanPropertyrowMapper,它的使用易用性以及可以从我们的结果集中访问类型不敏感的Bean属性的能力。
我有一个类层次结构,所有层次结构都映射到一个表格(以此小型层次结构为单位的方法)。因此,该表包含一个分类列,该分类列可用于确定实际应该实例化的类。前任。 1 =经理,2 =员工,3 =承包商。所有这些都是“人”,但每个人的子类都有一些班级独有的属性。
我最初的想法是创建一个beanpropertyrowmapper的子类,并尝试注入此逻辑,以说“如果列a = 1 = 1,则可以实例化管理器,然后进行提名绑定”。
这似乎是一种合理的方法吗?人们可能还有其他建议对您有用的建议吗?
提前感谢您的回复,
贾斯汀·N。
解决方案
看起来子类中没有一个地方,您可以在其中添加钩子来切换类,而无需完全复制maprow()的实现,beanpropertyrowmapper。您最好的方法可能是创建一个委派给适当的BeanPropertyrowMapper的RowMapper类。
例如:
final RowMapper managerMapper = new BeanPropertyRowMapper(Manager.class);
final RowMapper employeeMapper = new BeanPropertyRowMapper(Employee.class);
final RowMapper contractorMapper = new BeanPropertyRowMapper(Contractor.class);
RowMapper rm = new RowMapper()
{
@Override
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException
{
int employeeType = rs.getInt("type");
switch (employeeType)
{
case 1:
return managerMapper.mapRow(rs, rowNum);
case 2:
return employeeMapper.mapRow(rs, rowNum);
case 3:
return contractorMapper.mapRow(rs, rowNum);
default:
break;
}
}
};
其他提示
我不确定这是“最佳实践”,但我建议采用以下方法(不使用bean属性 - >应该更快地工作)。
通常,您知道您期望检索哪种对象。因此,执行SQL时,您可以提供相应的行映射器。
声明自定义抽象的通用行绘制器,并为每种类型的人创建自己的行映射器,即:
private static abstract class PersonRowMapper<T extends Person> implements RowMapper<T> {
@Override
public abstract T mapRow(ResultSet rs, int rowNum) throws SQLException;
protected void mapBase(ResultSet rs, T person) throws SQLException {
//base mapping here
}
}
private static class EmployeeRowMapper extends PersonRowMapper<Employee> {
@Override
public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
Employee e = new Employee();
mapBase(rs, e);
//set other specific employee props
}
}
通过其他方法,您可以在基本映射器中为特定道具声明抽象方法,即
private static abstract class PersonRowMapper<T extends Person> implements RowMapper<T> {
@Override
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
T instance = getInstance();
//set base props here
fill(rs, instance);
}
//e.g. return new Employee()
protected abstract T getInstance();
//fill specific instance props
protected abstract void fill(ResultSet rs, T instance) throws SQLException;
}
不隶属于 StackOverflow