我可以从 Sql 获取 keyCode(num) 但将 value(String) 映射到对象吗?
Can I get keyCode(num) from Sql but map value(String) to an object?
我的问题是这样的:
我正在使用以下设置:
- mybatis 3.4.2
- springframework 4.3.3
- mysql 5.7
我在 MySql 中的 table 是
CREATE TABLE `account_info` (
`account_id` int(9) NOT NULL AUTO_INCREMENT,
`account_holder_id` char(64) NOT NULL,
`account_number` char(19) NOT NULL,
`account_type` int(2) DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
我想要的是 account_type
像 (1:"debit", 2:"credit", 3:"affiliated", ...)
这样的字段映射
我的javaclass
public class AccountInfo {
private Integer accountId;
private String accountHolderId;
private String accountNumber;
private String accountType;
// getter and setter
}
这个在AccountInfoMapper.xml
<select id="getAcountInfoById" parameterType="int" resultType="demo.domain.AccountInfo">
select
*
from
account_info
where
account_id = #{accountId}
</select>
这是测试class
public class TestMybatisWithXML {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
String resource = "config/myBatisConfig.xml";
Reader inputStream = Resources.getResourceAsReader(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testGetAcountInfoById() {
SqlSession sqlSession = sqlSessionFactory.openSession();
AccountInfoMapper accountInfoMapper = sqlSession.getMapper(AccountInfoMapper.class);
AccountInfo temAccountInfo = accountInfoMapper.getAcountInfoById(9);
sqlSession.close();
System.out.println(temAccountInfo.toString());
}
}
Return 来自测试 class:
AccountInfo [accountId=9, accountHolderId=1, accountNumber=00010001, accountType=2]
这是我想要的结果:
AccountInfo [accountId=9, accountHolderId=1, accountNumber=00010001, accountType=credit]
如果有其他不同的方法可以得到相同的结果,那就太好了。
但是这次,我无法修改数据库 table 或语句。
创建替换地图也将被接受table。
但是如果mybatis有什么办法,可能对我来说更好。
不需要额外的代码或其他任何东西。您只需要在查询中使用 CASE
语句。就像
<select id="getAcountInfoById" parameterType="int" resultType="demo.domain.AccountInfo">
select
account_id,
account_holder_id,
account_number,
case when account_type=1 then 'debit'
when account_type=2 then 'credit'
when account_type=3 then 'affiliated'
.... /*other conditions here*/
end as account_type
from
account_info
where
account_id = #{accountId}
</select>
这应该足够了,因为 class 属性已经是 String
。
SQL 查询中的大小写是@Jorge Campos 所写的一个选项。
另一种选择是创建标签 table
CREATE TABLE account_type (
account_type_id int(2) NOT NULL,
account_type_name Varchar
)
并加入 select:
SELECT account_type_name AS account_type FROM account_info ai
INNER JOIN account_type at ON ai.account_type=at.account_type_id
where account_id = #{accountId}
或者如果你在java(属性文件,映射...)中有账户类型id =>标签映射,你可以使用ResultHandler 来处理映射。
映射器签名变为:void getAcountInfoById(Integer id, ResultHandler rh);
final Map<Integer, String> labelMap = ...
List<AccountInfo> accountInfoList = new ArrayList<>AccountInfo();
ResultHandler<AccountInfo> rh = new ResultHandler() {
public void handleResult(ResultContext<AccountInfo> resultContext) {
AccountInfo accountInfo = getResultObject();
accountInfo.setAccountType(labelMap.get(Integer.valueOf(accountInfo.getAccountType()));
accountInfoList.add(accountInfo)
}
};
accountInfoMapper.getAcountInfoById(id, rh);
这里我使用一个列表作为目标,这适用于有多个预期结果的情况。您可以使用另一个对象,重要的是提供一个目标以将指针保持在结果上。
Mybatis使用的默认(隐式)ResultHandler实际上填充了一个List,如果你使用自己的,则必须自己填充列表。
我的问题是这样的:
我正在使用以下设置:
- mybatis 3.4.2
- springframework 4.3.3
- mysql 5.7
我在 MySql 中的 table 是
CREATE TABLE `account_info` (
`account_id` int(9) NOT NULL AUTO_INCREMENT,
`account_holder_id` char(64) NOT NULL,
`account_number` char(19) NOT NULL,
`account_type` int(2) DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
我想要的是 account_type
像 (1:"debit", 2:"credit", 3:"affiliated", ...)
我的javaclass
public class AccountInfo {
private Integer accountId;
private String accountHolderId;
private String accountNumber;
private String accountType;
// getter and setter
}
这个在AccountInfoMapper.xml
<select id="getAcountInfoById" parameterType="int" resultType="demo.domain.AccountInfo">
select
*
from
account_info
where
account_id = #{accountId}
</select>
这是测试class
public class TestMybatisWithXML {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
String resource = "config/myBatisConfig.xml";
Reader inputStream = Resources.getResourceAsReader(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testGetAcountInfoById() {
SqlSession sqlSession = sqlSessionFactory.openSession();
AccountInfoMapper accountInfoMapper = sqlSession.getMapper(AccountInfoMapper.class);
AccountInfo temAccountInfo = accountInfoMapper.getAcountInfoById(9);
sqlSession.close();
System.out.println(temAccountInfo.toString());
}
}
Return 来自测试 class:
AccountInfo [accountId=9, accountHolderId=1, accountNumber=00010001, accountType=2]
这是我想要的结果:
AccountInfo [accountId=9, accountHolderId=1, accountNumber=00010001, accountType=credit]
如果有其他不同的方法可以得到相同的结果,那就太好了。 但是这次,我无法修改数据库 table 或语句。
创建替换地图也将被接受table。 但是如果mybatis有什么办法,可能对我来说更好。
不需要额外的代码或其他任何东西。您只需要在查询中使用 CASE
语句。就像
<select id="getAcountInfoById" parameterType="int" resultType="demo.domain.AccountInfo">
select
account_id,
account_holder_id,
account_number,
case when account_type=1 then 'debit'
when account_type=2 then 'credit'
when account_type=3 then 'affiliated'
.... /*other conditions here*/
end as account_type
from
account_info
where
account_id = #{accountId}
</select>
这应该足够了,因为 class 属性已经是 String
。
SQL 查询中的大小写是@Jorge Campos 所写的一个选项。
另一种选择是创建标签 table
CREATE TABLE account_type (
account_type_id int(2) NOT NULL,
account_type_name Varchar
)
并加入 select:
SELECT account_type_name AS account_type FROM account_info ai
INNER JOIN account_type at ON ai.account_type=at.account_type_id
where account_id = #{accountId}
或者如果你在java(属性文件,映射...)中有账户类型id =>标签映射,你可以使用ResultHandler 来处理映射。
映射器签名变为:void getAcountInfoById(Integer id, ResultHandler rh);
final Map<Integer, String> labelMap = ...
List<AccountInfo> accountInfoList = new ArrayList<>AccountInfo();
ResultHandler<AccountInfo> rh = new ResultHandler() {
public void handleResult(ResultContext<AccountInfo> resultContext) {
AccountInfo accountInfo = getResultObject();
accountInfo.setAccountType(labelMap.get(Integer.valueOf(accountInfo.getAccountType()));
accountInfoList.add(accountInfo)
}
};
accountInfoMapper.getAcountInfoById(id, rh);
这里我使用一个列表作为目标,这适用于有多个预期结果的情况。您可以使用另一个对象,重要的是提供一个目标以将指针保持在结果上。 Mybatis使用的默认(隐式)ResultHandler实际上填充了一个List,如果你使用自己的,则必须自己填充列表。