在Java与数据库(mysql)相关的内容中,基本都是与JDBC相关,mybatis作用主要是对JDBC的功能进行了拓展。
mybatis对于sql语句的获取
以select注解为例对于以下使用
@Select(select * from tb where id = #{id} and name = #{name})
public User getUser(String id, String name)
首先对于这个方法,会通过反射从select注解获取sql语句
Select select = method.getAnnotation(Select.class)
String value = select.value();
这个时候value的值为select * from tb where id = #{id} and name = #{name}
这个时候完成了sql的获取
方法中参数的处理
Java会通过反射的机制拿到方法中的参数
Parameter[] parameters = method.getParameters();
拿到的parameters即为所有的参数
之后mybatis会通过循环的方式,将parameter[i].getName,arg[i]为键值对存入提前制定好的map中(map<String,Object>)不过此时的parameter[i].getName为arg[i].
当只有一个参数的时候,不需要映射,可以直接写。
当参数有多个时(如示列),需要通过@Param来指定名称
@Select(select * from tb where id = #{id} and name = #{name})
public User getUser(@Param("id")String id,@Param("name") String name)
这是java就可以通过注解的value拿到属性名称
sql的预编译
sql在mybatis中会被预编译,将#{...}变为?,熟悉的同学应该有所了解。当存在多个参数的时候怎么确定参数的位置?mybatis在处理sql的时候,会通过内部的处理器进行匹配,并且将对于位置的变量名存入提前申请好的链表中。
GenericTokenParser genericTokenParser = new genericTokenParser ("#{","}","tokenhandel");
tokenhandel会将#{}按照tokenhandel的规则返回"?"
查询结果处理
查询结果会首先通过反射得到方法是否有范型,若不存在则直接变为返回值类型,否则提取范型,再通过反射创建对象,通过JDBC来解析出查询结果的所有列,通过遍历赋值,此处对于变量的属性,赋值,获取,均是通过反射处理,通过获取所有的以set方法开头的方法(赋值)赋值,并且通过方法的参数确定需要的类型(如果通过get方法可能会出现类型强制转换)。
总结
mybatis主要通过反射实现各种操作的处理,特别是对于赋值等操作,对于删除等操作,对于反射的使用相对较少,效率会相对高一些