mybatis内部提供了很多使用的工具,如果不仔细研究mybatis,平时的一些工作往往会重复造轮子,比如下面的几种情况
- 字符串拼接SQL
- 反射获取对象属性并设置值
- 反射判断对象是否包含某个方法,是否包含构造方法,获取Class中的某个属性的类型
下面就来看一下mybatis提供的实用工具类怎么快速的解决这些问题吧~再也不用重复造轮子了。
拼接SQL
之前项目里这么拼接SQL
@Test
public void noMybatisSQL(){
StringBuilder sb = new StringBuilder();
String table = "user";
String sql = sb.append("select * ").append("distinct id ")
.append("from ").append(table).append(...........省略)
}
这种写法写的快恶心吐了,可读性还差,得思考好久才能知道SQL写的啥,而且项目里远远要复杂我上面的这个例子,比如项目里把查询的表,过滤的条件等都存在了数据库中,都需要变量接收然后再做拼接。后来发现mybatis自带的工具类可以拼接SQL而且可读性非常好。并且无须关心关键字之间的空格问题,看即上手.
而且动态拼接SQL的可读性也非常好。
@Test
public void testSQL() {
String name = "张三";
String sql = new SQL() {{
SELECT("*");
FROM("user u");
INNER_JOIN("role r on u.id = r.id ");
if (name != null) {
WHERE("uname='" + name + "'");
}
}}.toString();
System.out.println(sql);
}
API我放这里了
MetaObject反射工具
mybatis提供了一个反射工具类MetaObject,它帮我们屏蔽掉了反射的复杂细节,通过SystemMetaObject.forObject方法返回的对象,就可以通过属性名称来获取属性值与设置属性值,非常简单,如果属性是另外一个对象可以通过a.b.c.d的形式无限递归的获取属性,用法如下。
@Test
public void test() {
User user = new User();
MetaObject metaObject = SystemMetaObject.forObject(user);
metaObject.setValue("name", "zhangsan");
Integer age = (Integer) metaObject.getValue("age");
System.out.println(user);
System.out.println(age);
}
MetaClass工具类
上面说到的MetaObject是用来获取对象的属性,其中的操作是针对对象而言的。
而MetaClass是针对class类型进行操作的,它可以获得class类型的getter方法、setter方法、构造函数,属性的类型等等。用法如下
// 先定义一个POJO
public class User1 {
private String name;
private Integer age = 18;
private String p;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
@Test
public void test2() throws InvocationTargetException, IllegalAccessException {
MetaClass metaClass = MetaClass.forClass(User1.class);
System.out.println(metaClass.hasGetter("name")); // false
System.out.println(metaClass.hasDefaultConstructor()); // true
System.out.println(metaClass.getSetterType("age")); // class java.lang.Integer
// 获取getter方法
Invoker ageGetInv = metaClass.getGetInvoker("age");
Object invoke = ageGetInv.invoke(new User1(), null); // 调用反射方法
System.out.println(invoke); // 输出该方法原本的返回类型
// 获取setter方法并调用
User1 user1 = new User1();
Invoker nameSetInv = metaClass.getSetInvoker("name");
nameSetInv.invoke(user1,new Object[]{"李四"});
System.out.println(user1);
}
输出结果
true
true
class java.lang.Integer
18
User{name='李四', age=18}
可以看到通过MetaClass可以很方便的获取到对象内部的getter/setter/默认构造方法,属性类型。比使用Class对象获取方法要简单很多。所以再涉及到反射的操作可以使用该对象方便开发。
总结
- 拼接SQL使用mybatis自带的
SQL工具类可以使得代码的可读性非常好而不影响效率,并且无须关心关键字之间的空格。 - 反射操作使用
MetaObjectMetaClass这两个工具类可以很方便的判断一个Class是否有某个方法,获取Class的方法并反射执行,获取对象的属性,反射直接设置对象的属性值。