1.Mybatis中 #{} 和 ${}符号的区别
#{} 是预编译的,在动态解析SQL语句之前,会使用占位符替换#{}的内容,安全
${}不是预编译的,在动态解析SQL语句的时候,才会替换掉${},不安全,容易导致SQL注入
2.Mybatis是如何通过Mapper接口实现和数据库交流的
先回答这个问题之前,需要知道Mybatis的前身ibatis,开发者是通过SqlSession这个接口提供的一系列方法访问数据库的;Mybatis是在ibatis的基础上再次封装,开发者只需要通过Mapper接口来实现和数据库的交流,因此只要知道如何把Mapper接口和SqlSession接口是如何映射的,就可以知道Mybatis是如何通过Mapper接口实现和数据库交流的
问题1:如何对应SqlSession中的方法,比如是用selectOne或者SelectList等
答案:根据Mapper接口调用的方法的命令(Select,Insert等)和返回值类型来确定具体执行SqlSession的哪个方法。
问题2:如何对应到配置文件中的sql语句
答案:1) 设置Mapper接口的全类名 作为配置文件的命名空间
2) 方法名作为配置文件中具体指令的id属性
3) mapper.getClass().getName() + "." + method.getName()最为key就可以定位Sql语句
问题3:参数如何传递
答案:把Mapper接口调用方法传递的参数,解析成SqlSession对应方法所需的参数类型即可
通过*Mapper接口的类型获取接口代理类
1)org.apache.ibatis.session.SqlSession#getMapper
2)org.apache.ibatis.session.Configuration#getMapper
3)org.apache.ibatis.binding.MapperRegistry#getMapper
3.1)knownMappers.get() 根据接口类型获取接口代理类
4)org.apache.ibatis.binding.MapperProxyFactory#newInstance(org.apache.ibatis.session.SqlSession)
4.1)org.apache.ibatis.binding.MapperProxy
5)java.lang.reflect.Proxy#newProxyInstance --JDK动态代理技术
获取到*Mapper接口的动态代理类,调用接口的方法
1)org.apache.ibatis.binding.MapperProxy#invoke
1.1)org.apache.ibatis.binding.MapperProxy#cachedMapperMethod 把*Mapper接口调用的方法缓存起来
1.2)得到MapperMethod类
2)org.apache.ibatis.binding.MapperMethod#execute
2.1)根据接口方法对应的命令类型,select,insert等,来调用SqlSession接口的对应方法
2.2)如果命令是SELECT类型的,还要根据方法的返回类型调用SqlSession接口的不同方法
2.2.1) 如果返回的是void类型
org.apache.ibatis.session.SqlSession#select(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
2.2.2) 如果返回的是集合类型的
org.apache.ibatis.session.SqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
2.2.3) 如果返回的是Map
org.apache.ibatis.session.SqlSession#selectMap(java.lang.String, java.lang.Object, java.lang.String, org.apache.ibatis.session.RowBounds)
2.2.4) 如果返回的是org.apache.ibatis.cursor.Cursor类型的
org.apache.ibatis.session.SqlSession#selectCursor(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
2.2.5) 如果不是上面任何一种类型
org.apache.ibatis.session.SqlSession#selectOne(java.lang.String, java.lang.Object)