我可以从Sql获取keyCode(num)但是将值(String)映射到对象吗?

时间:2017-02-10 10:57:37

标签: spring mybatis

我的问题是这样的:

我使用以下设置:

  • 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 

我想要的是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
}

这在AccountInfoMapper.xml

<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有某种方式,对我来说可能更好。

2 个答案:

答案 0 :(得分: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 :(得分: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}

如果您的帐户类型为id =&gt;标签映射在java(属性文件,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,如果你使用自己的,你必须自己填写列表。