MyBatis提供了简单的Java注解,使得我们可以不配置XML格式的Mapper文件,方便的编写简单的数据库操作代码:

public interface UserMapper {

@Select("SELECT * FROM users WHERE id = #{userId}")

User getUser(@Param("userId") String userId);

}

但是没有Dynamic SQL的注解是不完整的,故这里向大家介绍下如何通过实现LanguageDriver,优雅的在MyBatis注解中使用Dynamic SQL。

自定义Select In注解

@Lang(SimpleSelectInExtendedLanguageDriver.class)@Select("SELECT * FROM user中鸿王靖安s WHERE id IN (#{userIds})")List selectUsers(@Param("userIds") List 乾元天庭userIds);// 一次编写,受益终生public class SimpleSelectInExtendedLanguageDriver  extends XMLLanguageDriver implements LanguageDriver {  private final Pattern inPattern = Pattern.compile("\\(#\\{(\\w+)\\}\\)"); @Override public SqlSource creatkmvreSqlSource(Configuration configuration,  String script, Class  Matcher matcher = inPattern.matcher(script); if (matcher.find()) { scr里番社ipt = matcher.replaceAll(足恋"(#{__item})"); }  script = ""; return super.createSqlSource(configuration, script, parameterType); }}

我们通过实现自己的LanguageDriver,在MyBat一库宝盒is编译语句前,将我们自定义的标签替换为了动态SQL语句,其等同于:

@Select({""}) List selectUsers(@Param("userIds") List userIds);

通过实现LanguageDriver,剥离出了冗长的动态SQL语句,简化Select In的注解代码。

自定义Update Bean注解

类似的,通过重写LanguageDriver,我们还能扩展出远比其它方案(e.g. XML SQL Mapper配置、在注解语句中写动态SQL)简洁的自定义操作。

一个常用的操作是更新数据库中的一条记录。通常而言,每张表(采用下划线命名法)会有一个对应的Domain对象(采用驼峰式命名法),当我们更新一条记录时,需要为对象中的每个字段配置映射关系,会写出如下的代码:

int updateUser(User user); update users  username=#{username}, password=#{password}, email=#{e搔脚心mail}, home_address=#{homeAddress}  where id=#{userId}

冗长的代码只是把驼峰式命名的变量名映射为下划线式命名的列名,显然我们可以将这种映射规律自动化:

@Update("UPDATE user (#{user}) WHERE id =三眼皮代表什么命 意桥岛之恋 司机高速解手丧命#{userId}")@Lang(SimpleUpdateExtendedLanguageDriver.class)int updateUser(Store store);/** * Created by benxue on 3/1/16. */public class S乳贴姬impleUpdateExtendedLanguageDriver extends XMLLanguageDriver implements LanguageDriver { private final Pattern inPattern = Pattern.compile("\\(#\\{(\\w+)\\}\\)"); @Override public SqlSource createSqlSource(Configuration configuration, String script, Class Matcher matcher = inPattern.matcher(script); if (matcher.find()) { StringBuffer ss = new StringBuffer(); ss.append(""); for (Field field : parameterTyp程冷潇e.getDeclaredFields()) { String temp = "__column=#{__field},"; ss.append(temp.replaceAll("__field", field.getName()) .replaceAll("__column", CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName()))); }  ss.deleteCharAt(ss.lastIndexOf(",")); ss.append(""); script = matcher.replaceAll(ss.toString()); script = ""; } retur余姿昀n super.createSqlSource(configuration, script, parameterType); }}

一个常见的情况是,Domain中的部分属性在数据库表中并不存在对应的列,我们增加一个自定义的注释并对LanguageDriver的实现稍作修改:

public 咕咕速运class User{

...

@Invisible

private UserSearchDO userSearchDO;

...

}

/**

* Created by ben陶崇斌xue on 3/10/16.

* The field marked as Invisib荣乐传奇glle will not be scanned by customized simple extended language drivers

* of myBatis

*/

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

public @interface Invisible {

}

...

for (Field field : parameterType.getDeclaredFields()) {

if (!field.isAnnotationPresent(Invi无肛男婴生命垂危sible.class)) {

String temp = "__column=#{__field},";

ss.append(temp.replaceAll("__field", field.getName())

.replaceAll("__column", CaseFormat.破天网LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName())));

}

}

...

由此,以后就可以用一句话完成动态Update语句了。

总结

通过实现LanguageDriver,青云冰刀易爆点我们可以实现方便的自定义注解。在遵循一些约定的情况下(e.g. Domain使用驼峰命名法,数据库表使用下划线命名法),就可以和麻烦的XML配弹骇什么意思置和动态SQL编写say 88了:)

// 清爽的数据库操作@Select("SELECT * FROM user WHERE user_id IN (#{userIds})")@Lang(SimpleSelectInExtendedLanguageDriver.class)List getUsers(@Param("userIds") List userIds);@Update("UPDATE user (#{user}) WHERE user_id =#{userId}")@Lang(SimpleUpdateExtendedLanguageDriver.class)int updateUser(User user);@Insert("I弗林法温德NSERT INTO user (#{user})")@Lang(SimpleInsertExtend终极圣尊edLanguageDriver.class)void insertUser(User user);

引用

How to use Annotations with iBatis (myBatis) for an IN query