MyBatis 在插入时将属性映射到数据库列更新(使用注释)
我刚刚开始学习 MyBatis,我想知道,当我创建插入或更新查询时,是否有一种方法可以使属性名称对重构更加友好?我将更详细地解释:
我的所有域类中都有可用于引用属性名称的常量。在我看来,它减少了拼写错误并使重构变得更加容易。
public static final String FIRST_NAME = "firstName";
private String firstName = "";
当我使用注释创建 MyBatis select 语句时,我可以执行以下操作:
@Select("SELECT ID, FIRST_NAME, LAST_NAME FROM CUSTOMERS WHERE ID = #{id}")
@Results({
@Result(property = CustomerDetail.ID, column = "ID"),
@Result(property = CustomerDetail.FIRST_NAME, column = "FIRST_NAME"),
@Result(property = CustomerDetail.LAST_NAME, column = "LAST_NAME")
})
CustomerDetail selectById(final int id);
如果我重构我的域对象 (CustomerDetail) 并更改属性名称,它最终会变得相当简单。
但是,当我使用注释创建 MyBatis 插入语句时,我必须执行以下操作:
@Insert("INSERT INTO CUSTOMERS (ID, FIRST_NAME, LAST_NAME) VALUES (#{id}, #{firstName}, #{lastName})")
void insertCustomerDetail(final CustomerDetail customerDetail);
在这种情况下,如果我重构域对象 (CustomerDetail) 并更改属性名称,则更容易出错。有没有一种方法可以使用我的常量而无需诉诸一堆字符串连接?这是我应该关心的事情吗?
作为一个新手,我期望 @Insert 和 @Update 注释能够模仿 @Select 注释的结构。例如(请注意,以下内容不是有效的 MyBatis 注释):
@Insert("INSERT INTO CUSTOMERS (ID, FIRST_NAME, LAST_NAME)")
@Params({
@Param(property = CustomerDetail.ID, column = "ID"),
@Param(property = CustomerDetail.FIRST_NAME, column = "FIRST_NAME"),
@Param(property = CustomerDetail.LAST_NAME, column = "LAST_NAME")
})
void insertCustomerDetail(final CustomerDetail customerDetail);
我是否错过了与上述示例具有相同效果的任何选项?或者,我是否可以对 MyBatis 映射进行单元测试,以确保没有人使用我的域对象中不存在的属性名称?测试可能是一个更好的解决方案,因为它也适用于基于 XML 的映射。想法?
I'm just starting to learn MyBatis and I'm wondering, when I'm creating insert or update queries, is there a way that I can make property names a bit more friendly to refactoring? I'll explain in more detail:
I have constants in all of my domain classes that can be used to reference property names. In my opinion, it cuts down on typos and makes refactoring a bit easier.
public static final String FIRST_NAME = "firstName";
private String firstName = "";
When I create a MyBatis select statement using annotations, I can do something like this:
@Select("SELECT ID, FIRST_NAME, LAST_NAME FROM CUSTOMERS WHERE ID = #{id}")
@Results({
@Result(property = CustomerDetail.ID, column = "ID"),
@Result(property = CustomerDetail.FIRST_NAME, column = "FIRST_NAME"),
@Result(property = CustomerDetail.LAST_NAME, column = "LAST_NAME")
})
CustomerDetail selectById(final int id);
If I refactor my domain object (CustomerDetail) and change property names, it ends up being fairly simple.
However, when I create a MyBatis insert statement using annotations, I have to do something like this:
@Insert("INSERT INTO CUSTOMERS (ID, FIRST_NAME, LAST_NAME) VALUES (#{id}, #{firstName}, #{lastName})")
void insertCustomerDetail(final CustomerDetail customerDetail);
In this case, if I refactor my domain object (CustomerDetail) and change property names, it's much more error prone. Is there a way I can use my constants without resorting to a bunch of string concatenation? Is it something I should even concern myself with?
As a total newbie, I was expecting the @Insert and @Update annotations to mimic the structure of the @Select annotation. For example (please note, the below are NOT valid MyBatis annotations):
@Insert("INSERT INTO CUSTOMERS (ID, FIRST_NAME, LAST_NAME)")
@Params({
@Param(property = CustomerDetail.ID, column = "ID"),
@Param(property = CustomerDetail.FIRST_NAME, column = "FIRST_NAME"),
@Param(property = CustomerDetail.LAST_NAME, column = "LAST_NAME")
})
void insertCustomerDetail(final CustomerDetail customerDetail);
Have I missed any options that would have the same effect as my above sample? Alternatively, is it possible for me to unit test MyBatis mappings to ensure no one is using property names that don't exist in my domain objects? Testing may be a better solution since it would also apply to XML based mappings. Thoughts?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不这么认为。我理解您的担忧,并且我知道这样的功能对您有何好处,尤其是在开发早期,当 POJO 经常发生变化时。
我认为您的对象字段不会被重构到足以证明提供此功能所需的投资是合理的。
我建议您阅读 mybatis 用户指南。这并不完全是您在这里寻找的,但它是一种将对象字段名称与 mybatis sql 映射变量解耦的方法。在我看来,我会采用你的方法而不是使用 @Param 传递各个字段。
关于对 sql 映射进行单元测试,我相当确定,如果您使用对象中没有相应 get 方法的 ognl 表达式,您将得到异常。即,如果您使用#{someField},并且传入的对象没有 getSomeField() 方法,则会出现异常。
I don't think so. I understand your concern, and I see how such a feature could be beneficial to you, especially early in development when POJO's tend to change so often.
I don't think your objects fields will be refactored enough to justify the investment needed to provide this functionality.
I suggest you read about the @Param tag in the mybatis user guide. It's not exactly what your looking for here, but it is a way to decouple object field names to mybatis sql map variables. In my mind, I would take your approach over passing in individual feilds with a @Param.
In regards to unit testing your sql maps, i'm fairly certain that if you use an ognl expression that doesn't have a corresponding get method in the object you'll get an exceptions. i.e if you use #{someField}, and the object your passing in doesn't have a getSomeField() method, then you get exception.