Question
I am using MyBatis 3.0.3 and have problem: some columns in database have names with underscores and these columns should be mapped to the entity properties (that are of course in camelCase)
class User {
private String first_name;
...
}
public interface UserDao {
@Select("SELECT * FROM users")
List<User> findAllUsers();
}
Unfortunately I can't see any way to solve that declaretively (like it is done in JPA - @Column(name = "first_name")). I could make aliases in select-clause for such columns (sush as first_name as firstName and etc.), but that also looks lame.
Any ideas? Thanks.
Solution
Thanks to DwB. That helped:
@Select("SELECT * FROM users")
@Results({
@Result(property = "firstName", column = "first_name"),
@Result(property = "lastName", column = "last_name")
})
List<User> findUsers();
ps But in case of multiple queries I need to boilerplate @Results/@Result code for each method where entity User is returned. In my case there will be a very few places so it isn't a problem, but in general I would still like to find more general solution.
OTHER TIPS
Eduardo Macarron has suggested this feature on the following issue:
https://code.google.com/p/mybatis/issues/detail?id=43
According to the documentation of MyBatis 3, now is possible through a setting described in:
http://mybatis.github.io/mybatis-3/configuration.html#settings
Basically you must configure:
<setting name="mapUnderscoreToCamelCase" value="true"/>
Which means:
Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn.
Define a ResultMap
in the UserMapper.xml
file, and add these lines:
<resultMap id="BaseResultMap" type="package.for.User">
<result column="user_name" jdbcType="VARCHAR" property="userName" />
<!-- other columns -->
</resultMap>
In your Java code, add@ResultMap
annotation:
public interface UserDao {
@Select("SELECT * FROM users")
@ResultMap("BaseResultMap")
List<User> findAllUsers();
}
You can use MyBatis Generator to generate these base codes automatically.
If there is not so much columns you can do it this way and avoid ResultMap.
@Select("SELECT first_name as firstName, last_name as lastName FROM users")
List<User> findUsers();
to make it more readable you can use array of strings, which MyBatis concanate with extra space
@Select({
"SELECT",
" first_name as firstName,",
" last_name as lastName",
"FROM users"})
List<User> findUsers();
In spring annotation-based configuration underscore to camel case mapping can be enabled through a customizable SqlSessionFactory, like that:
@Bean
@Primary
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactory factory = sessionFactoryBuilder().build();
factory.getConfiguration().setMapUnderscoreToCamelCase(true);
// other configurations
return factory;
}
use MyBatis's Auto-mapping in your config file (sth like application.properties or application.yml), here like:
mybatis.configuration.map-underscore-to-camel-case=true
Reference: http://www.mybatis.org/mybatis-3/sqlmap-xml.html#Auto-mapping
Chinese Reference: http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#Auto-mapping