注解开发和底层实现原理

1.使用注解开发

使用注解开发:主要是在接口的方法上加入@标签,在标签内直接写sql语句

@Select("select * from mybatis.user")
List<User> getUsers();

然后在核心配置文件中绑定接口

<!--接口配置-->
<mappers>
    <mapper class="com.zhaox.Mapper.UserMapper"/>
</mappers>

但这样做有一个最大的弊端,就是他无法处理一些比较困难的语句,比如之前的结果集映射,在这里就无法实现了,所以mybvatis官方推荐在mybatis中依旧使用xml映射的方式。

  • 本质:反射机制实现
  • 底层:动态代理模式

关于@param

  • 基本类型的参数或者String类型,需要加上
  • 引用类型不需要加
  • 如果只有一个基本类型的话,可以忽略,但是建议大家都加上!
  • 我们在SQL中引用的就是我们这里的@Param()中设定的属性名!

#{} ${} 区别

项目中传入表名称时用#{tableName}及时间比较时用{time}出现错误,于是搜了下两者的区别:

MyBatis中使用parameterType向SQL语句传参,parameterType后的类型可以是基本类型int,String,HashMap和java自定义类型。

在SQL中引用这些参数的时候,可以使用两种方式#{parameterName}或者{parameterName}。

#{}
#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。例如:order by #{parameterName} //或取Map中的value#{Key}也是一样操作。

假设传入参数是“Smith”

会解析成:order by "Smith"

${}
$将传入的数据直接显示生成在sql中。

例如:order by #{parameterName} //或取Map中的value#{Key}也是一样操作。

假设传入参数是“Smith”

会解析成:order by Smith

区别:
#方式能够很大程度防止sql注入 方式无法防止SQL注入。
$方式一般用于传入数据库对象,例如传入表名。
从安全性上考虑,能使用#尽量使用#来传参,因为这样可以有效防止SQL注入的问题。

注意:如果使用注解开发则优先使用注解中的变量名

2.mybatis详细的执行流程

  1. 将配置文件变成流
  2. 通过实例化的SqlSessionFactoryBuilder的build方法,将配置文件流作为参数,得到一个SqlSessionFactory对象
    1. 将核心配置文件读入XMLConfigBuilder并实例化
    2. 实例化的对象调用Parse方法,返回一个configuration对象
    3. 再回到SqlSessionFactoryBuilder里调用一个参数为configure的build方法,得到SqlSession
  3. 通过OpenSession方法,返回一个SqlSession
    1. OpenSession方法是一个接口就,具体实现是openSessionFromDataSource方法
    2. 利用之前工厂内的configure对象,实例化一堆参数,最终创建执行器exector
    3. 将执行器,configuration等作为参数传入DefaultSqlSession构造函数中,得到一个崭新的SqlSession
    4. 接下来就是SqlSession使用Exector去实现每一条对应的sql了
  4. Sqlseesion内部所携带的执行器,去执行配置文件里的sql语句

    mybatis底层实现原理高清
    注意:可以在工厂openSession传入一个布尔值,如果为true则代表开启

醉后不知天在水,满船清梦压星河