2017-02-10 15 views
0

我的问题是这样的:我可以从Sql获取keyCode(num),但将值(String)映射到对象?

我使用以下设置:

  • 的MyBatis 3.4.2
  • springframework的4.3.3
  • 的MySQL 5.7

我的表MySql是

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 

我想要的是在AccountInfoMapper.xml account_type字段映射像(1:"debit", 2:"credit", 3:"affiliated", ...)

我的Java类

public class AccountInfo { 
    private Integer accountId; 
    private String accountHolderId; 
    private String accountNumber; 
    private String accountType; 
    // getter and setter 
} 

<select id="getAcountInfoById" parameterType="int" resultType="demo.domain.AccountInfo"> 
    select 
    * 
    from 
    account_info 
    where 
    account_id = #{accountId} 
</select> 

这是

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()); 
    } 

} 

测试类返回来自测试课程:

AccountInfo [accountId=9, accountHolderId=1, accountNumber=00010001, accountType=2] 

这是我想什么是结果,而不是:

AccountInfo [accountId=9, accountHolderId=1, accountNumber=00010001, accountType=credit] 

如果有其他不同的方式,我可以有同样的结果将是巨大的。但这一次,我不能修改数据库表或语句。

创建替换映射也是可以接受的。 但是如果在mybatis中有某种方式,可能对我更好。

+0

请提供具体的代码示例。伪代码不清楚,可能以多种方式解释。 如果我尝试一个猜测:你的查询返回一个代码列表(int),你需要一个对象列表,他们的属性是匹配这个代码的标签?如果你确认,我会写基于resultHandler的解决方案。 – blackwizard

+0

我编辑了我的问题。有足够的信息吗?并感谢您的帮助。 –

回答

0

SQL查询中的情况是由@Jorge Campos编写的选项。

另一种选择是创建一个标签表

CREATE TABLE account_type (
    account_type_id int(2) NOT NULL, 
    account_type_name Varchar 
) 

并加入选择:

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 =>标签映射(属性文件,map ...),您可以使用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,如果您使用自己的,则必须自己填写列表。

0

不需要额外的代码或其他。您只需在您的查询中输入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

+1

非常感谢您的建议并修复了我的语法。尽管如此,也许我需要修改很多查询语句,但它帮助我解决了另一个问题。 :) –

相关问题