从SP到复杂对象的java映射结果
我正在努力在我的工作项目中实施MyBatis。它是一个遗留系统,仅通过存储过程使用普通JDBC访问数据库。我知道要调用存储过程,MyBatis需要一个包含存储过程输入参数的对象和另一个保存结果集的对象。不确定这是否完全正确
为了防止在系统中创建过多的数据实体,我希望重用现有的实体。这就是问题所在。让我解释一下我所面临的典型情况/情景,以及我如何试图解决它
假设系统中有以下数据实体:
class Account {
private int accountID;
private String accountName;
private OrganizationAddress address;
// Getters-Setters Go Here
}
class OrganizationAddress extends Address {
// ... some attributes here
// Getters-Setters Go Here
}
class Address {
private String address;
private String city;
private String state;
private String country;
// Getters-Setters Go Here
}
我正在使用注释,所以我的Mapper
类有如下内容:
@Select(value = "{call Get_AccountList(#{accountType, mode=IN, jdbcType=String})}")
@Options(statementType = StatementType.CALLABLE)
@Results(value = {
@org.apache.ibatis.annotations.Result
(property = "accountID", column = "Account_ID"),
@org.apache.ibatis.annotations.Result
(property = "accountName", column = "Organization_Name"),
@org.apache.ibatis.annotations.Result
(property = "state", column = "State", javaType=OrganizationAddress.class)
})
List<Account> getAccountList(Param param);
问题:当我调用存储过程时,Account
对象的state
总是null
此外,我无权访问上述数据实体的来源。所以我也无法尝试在这个链接上提供的解决方案-Mybatis select with nested objects
我的问题是:
- 我是否可以使用系统中已经存在的数据实体,还是必须创建新的实体,然后将数据映射到现有的实体?
- 如果是,我该怎么做?任何参考资料,如果有的话李>
- 如果没有,有没有办法减少我为调用存储过程而创建的数据实体的数量(对于in和out参数)李>
# 1 楼答案
我认为最好的解决方案(如果我理解正确的话)是使用MyBatis TypeHandler,它将状态列映射到OrganizationAddress对象
根据你提供的信息,我总结了一个例子,它是有效的。以下是修订后的注释地图:
您需要将Account的address字段映射到“state”列,并使用TypeHandler创建一个OrganizationAddress,并填写其“state”属性
我创建的OrgAddressTypeHandler如下所示:
如果您需要一个比这个更完整的工作示例,我很乐意发送更多。如果我误解了你的例子,请告诉我
有了这个解决方案,你可以不用修改就可以使用你的域对象。只需要TypeHandler来进行映射,而不需要XML映射器文件
我也用MySQL中的MyBatis-3.1.1实现了这一点。下面是我为测试它而创建的简单模式和存储过程: