最近不知道那根筋打错了,突然心血来潮,重新想起了自己的博客,于是,在下班闲暇之余鼓捣了一下自己的博客,在原来的基础上加了一些在工作中学到的东西,并且莫名其妙的想起了用mybatis作为自己博客的持久层框架,于是,整个人仿佛又回到了那段折腾的时光。在折腾的过程中,在写一个通用Dao的时候遇到了问题,于是在网上不断的找答案,最后我接触到了mybatis的Provider(关于mybatis Provider的使用这里就不多说了http://www.mybatis.org/mybatis-3/zh/java-api.html),开始的时候,由于向Provider传递的参数只有一个,像这样:
Dao:
public interface BaseDao<T> {
@SelectProvider(type=BasePrivider.class,method="selectOne")
@ResultType(User.class)
public T getPojo(@Param("id")Object id);
}
Provider:
public class BasePrivider {
public String selectOne(Object id) {
String tableName = AnnotationUtil.getTableName(c);
SQL sql = new SQL();
sql.SELECT("*").FROM(tableName).WHERE("id = #{id}");
System.out.println(sql.toString());
return sql.toString();
}
}
是没有任何问题的,之后参数多了,问题就出现了,网上说的当参数大于两个的时候,Provider的参数必须是一个Map对象,像这样:
public interface BaseDao<T> {
@SelectProvider(type=BasePrivider.class,method="selectOne")
@ResultType(User.class)
public T getPojo(Map<String, Object> params);
}
其中key是@Param指定的名称,值就是对应的参数值,如果未指定,则按照一定规则设置key,但是,遗憾的是用map我根本获取不到参数。最后在网上苦苦搜索,在官方文档中找到了答案http://www.mybatis.org/mybatis-3/zh/java-api.html。
意思就是说你需要在Provider中使用某个参数的话就需要用@Param标注,对于在SQL语句中使用的参数,可以不用写出,除非你在Provider中显式使用那个参数。像这样:
Dao:
public interface BaseDao<T> {
@SelectProvider(type=BasePrivider.class,method="selectOne")
@ResultType(User.class)
public T getPojo(@Param("id")Object id, @Param("class") Class c);
}
传递两个参数 id和c
Provider:
public class BasePrivider {
public String selectOne(@Param("class") Class c) {
String tableName = AnnotationUtil.getTableName(c);
SQL sql = new SQL();
sql.SELECT("*").FROM(tableName).WHERE("id = #{id}");
System.out.println(sql.toString());
return sql.toString();
}
}
在Provider中,我需要根据Class c上的注解信息获取实体对应的表名,在selectOne中必须使用到参数c,这个方法上我就只用@Param标注了Class c,至于另外的参数id,可以看到,直接在SQL使用mybatis的参数占位就可以了,最后运行,问题完美解决。
注:对于更多的参数,也一样。我使用的mybatis版本是3.4.6。
我的表达能力不是很好,可能说的不是很清楚,希望大家见谅,不喜勿喷。