我覺得您的情況最好的解決方法(如果我理解正確的話)是使用MyBatis的類型處理器將狀態列映射到一個OrganizationAddress對象。
我已經根據您提供的信息和它的工作原理編寫了一個示例。下面是修改後的註釋的映射:
// Note: you have an error in the @Select line => maps to VARCHAR not "String"
@Select(value = "{call Get_AccountList(#{accountType, mode=IN, jdbcType=VARCHAR})}")
@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 = "address", column = "State", typeHandler=OrgAddressTypeHandler.class)
})
List<Account> getAccountList(Param param);
你需要考慮的地址字段映射到「狀態」欄,並使用類型處理器與填充其「狀態」屬性創建OrganizationAddress
我創建的OrgAddressTypeHandler看起來是這樣的:
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
public class OrgAddressTypeHandler extends BaseTypeHandler<OrganizationAddress> {
@Override
public OrganizationAddress getNullableResult(ResultSet rs, String colName) throws SQLException {
OrganizationAddress oa = new OrganizationAddress();
oa.setState(rs.getString(colName));
return oa;
}
@Override
public OrganizationAddress getNullableResult(ResultSet rs, int colNum) throws SQLException {
OrganizationAddress oa = new OrganizationAddress();
oa.setState(rs.getString(colNum));
return oa;
}
@Override
public OrganizationAddress getNullableResult(CallableStatement cs, int colNum) throws SQLException {
OrganizationAddress oa = new OrganizationAddress();
oa.setState(cs.getString(colNum));
return oa;
}
@Override
public void setNonNullParameter(PreparedStatement arg0, int arg1, OrganizationAddress arg2, JdbcType arg3) throws SQLException {
// not needed for this example
}
}
如果你需要比這更完整的工作示例,我會很高興地發送更多。或者如果我誤解了你的例子,請告訴我。
使用此解決方案,您可以不加修改地使用您的域對象。您只需要TypeHandler來完成映射,而不需要XML映射器文件。
另外我用MyBatis-3做了這個。1.1在MySQL中。這裏是我創建的簡單模式和存儲過程來測試它:
DROP TABLE IF EXISTS account;
DROP TABLE IF EXISTS organization_address;
CREATE TABLE account (
account_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
organization_name VARCHAR(45) NOT NULL,
account_type VARCHAR(10) NOT NULL,
organization_address_id SMALLINT UNSIGNED NOT NULL,
PRIMARY KEY (account_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE organization_address (
organization_address_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
address VARCHAR(45) NOT NULL,
city VARCHAR(45) NOT NULL,
state VARCHAR(45) NOT NULL,
country VARCHAR(45) NOT NULL,
PRIMARY KEY (organization_address_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO organization_address VALUES(1, '123 Foo St.', 'Foo City', 'Texas', 'USA');
INSERT INTO organization_address VALUES(2, '456 Bar St.', 'Bar City', 'Arizona', 'USA');
INSERT INTO organization_address VALUES(3, '789 Quux Ave.', 'Quux City', 'New Mexico', 'USA');
INSERT INTO account VALUES(1, 'Foo', 'Type1', 1);
INSERT INTO account VALUES(2, 'Bar', 'Type1', 2);
INSERT INTO account VALUES(3, 'Quux', 'Type2', 3);
DROP PROCEDURE IF EXISTS Get_AccountList;
DELIMITER $$
CREATE PROCEDURE Get_AccountList(IN p_account_type VARCHAR(10))
READS SQL DATA
BEGIN
SELECT a.account_id, a.organization_name, o.state
FROM account a
JOIN organization_address o ON a.organization_address_id = o.organization_address_id
WHERE account_type = p_account_type
ORDER BY a.account_id;
END $$
DELIMITER ;
是的,你已經正確理解我的問題,並且此解決方案適用於我。謝謝! :) – Rishabh