Mybatis

        Mybatis是一个半自动的orm(sql语法模板);

        Mybatis工作原理:先封装SQL,接着调用JDBC操作数据库,最后把数据库返回的表结果封装成Java类;

        Mapper执行:通过动态代理去执行SQL。

————————————————————

JDBC

        通过 DriverManager(需要Java Spi 机制加载驱动) 或者DataSource 获得一个Conection连接之后 再通过Statement SQL语句的执行器去执行语句 再获得一个ResultSet

        Connection:

        一个Connection对象表示通过JDBC驱动与数据源建立的连接;

        Connection对象表示客户端会话,因此它需要一些相关的状态信息,例如用户id、一组SQL语句和会话中使用的结果集以及事务隔离级别等信息;

        Connection的获取可以从两个方面获取:

     1、 JDBC API中提供的DriverManager类获取:
        Connection connection = DriverManager.getConnection(
          "jdbc:mysql://127.0.0.1:3306/data?user=root&password=123456");

    2、  DataSource接口的实现类获取
        DataSource dataSource = new UnpooledDataSource(
                "com.mysql.cj.jdbc.Driver",
                "jdbc:mysql://127.0.0.1:3306/data?user=root&password=123456&AllowPublicKeyRetrieval=true",
                "root","qwer1234");

  ————————————————————

      Statement

Statement 不支持输入参数,字符串拼接方式创建,有sql注入的风险;

PreparedStatement:增加了设置SQL参数的方法,可以把参数有?代替,preparedStatement承接出来;

 CallableStatement:增加了调用存储过程以及检索存储过程调用结果的方法;(不常见)

不同Statement执行的方式

		Connection connection = DriverManager.getConnection("");
        String sql = "SELECT * FROM admin WHERE username = ? AND password = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setString(1,"username");
        preparedStatement.setString(2,"password");
        ResultSet resultSet = preparedStatement.executeQuery();


        String sql2 = "SELECT * FROM admin WHERE username = 'username' AND password = 'password'";
        Statement statement2 = connection.createStatement();
        ResultSet resultSet2 = statement.executeQuery(sql);

        可扩展组件

1、Executor:是MyBatis的SQL执行器,MyBatis中对数据库所有的增删改查操作都是由Executor组件完成的。

2、StatementHandler组件:封装了对JDBC Statement的操作,例如设置Statement对象的fetchSize属性、设置查询超时时间、调用JDBC Statement与数据库交互等。

  • SimpleStatementHandler :封装了JDBC的 Statement 对象
  • PreparedStatementHandler:封装了JDBC的 PreparedStatement 对象 (可添加sql参数)
  • CallableStatementHandler:封装了JDBC的 CallableStatement 对象

3、ParameterHandler组件:当MyBatis框架使用的Statement类型为CallableStatement和PreparedStatement时,ParameterHandler用于为Statement对象参数占位符设置值。

4、ResultSetHandler:封装了对JDBC中的ResultSet对象操作,当执行SQL类型为SELECT语句时,ResultSetHandler用于将查询结果转换成Java对象。

        自定义转化处理器:

TypeHandler:处理JDBC类型与Java类型之间的转换

        描述配置信息:

Configuration:用于描述MyBatis的主配置信息,其他组件需要获取配置信息时,直接通过Configuration对象获取。除此之外,MyBatis在应用启动时,将Mapper配置信息、类型别名、TypeHandler等注册到Configuration组件中,其他组件需要这些信息时,也可以从Configuration对象中获取。

MappedStatement:用于描述Mapper中的SQL配置信息,是对Mapper XML配置文件中<select|update|delete|insert>等标签或者@Select/@Update等注解配置信息的封装。

————————————————————

Mybatis描述文件的属性

typenamedesc
通用id

在命名空间中唯一的标识符,可以被用来引用这条配置信息

parameterType

用于指定这条语句的参数类的完全限定名或别名

statementType

参数可选值为STATEMENT、PREPARED或CALLABLE,这会让MyBatis分别使用Statement、PreparedStatement或CallableStatement与数据库交互,默认值为PREPARED。

flushCache

用于控制是否刷新缓存。如果将其设置为 true,则任何时候只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值为false。

timeout

驱动程序等待数据库返回请求结果的秒数,超时将会抛出异常。

databaseId

(databaseIdProvider:根据不同数据库执行不同的sql语句)

如果配置了 databaseIdProvider,MyBatis会加载所有不带databaseId或匹配当前 databaseId 的语句

selelctresultType

从这条语句中返回的期望类型的类的完全限定名或别名。注意,如果返回结果是集合类型,则resultType属性应该指定集合中可以包含的类型,而不是集合本身。

resultMap

用于引用通过<resultMap>标签配置的实体属性与数据库字段之间建立的结果集的映射(注意:resultMap和resultType属性不能同时使用)

resultSetType

参数可选值为FORWARD_ONLY、SCROLL_SENSITIVE或SCROLL_INSENSITIVE,用于设置ResultSet对象的特征

useCache

是否使用二级缓存。如果将其设置为 true,则会导致本条语句的结果被缓存在MyBatis的二级缓存中,对应<select>标签,该属性的默认值为true

fetchSize

用于设置JDBC中 Statement对象的fetchSize属性,该属性用于指定SQL执行后返回的最大行数

insert

update

useGeneratedKeys

Statement对象的getGeneratedKeys()方法来取出由数据库内部生成的键值,例如MySQL自增主键。

KeyProperty

用于将数据库自增主键或者<insert>标签中<selectKey>标签返回的值填充到实体的属性中,如果有多个属性,则使用逗号分隔。

————————————————————

#{}与${}参数占位符区别:

        ● 使用#{}参数占位符时,占位符内容会被替换成“?”,然后通过PreparedStatement对象的setXXX()方法为参数占位符设置值;而${}参数占位符内容会被直接替换为参数值。

        ● 使用#{}可以有效的防止SQL注入,提高系统安全性。当#{}参数占位符无法满足需求时,(排序、分页等)才考虑使用${}参数占位符。

        (原因在于:预编译机制。预编译完成之后,SQL的结构已经固定,即便用户输入非法参数,也不会对SQL的结构产生影响,从而避免了潜在的安全风险。预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。)

————————————————————

Mapper

MyBatis中Mapper的配置分为两部分: Mapper接口和Mapper SQL配置。

        MyBatis通过动态代理的方式创建Mapper接口的代理对象,MapperProxy类中定义了Mapper方法执行时的拦截逻辑,通过MapperProxyFactory创建代理实例,MyBatis启动时,会将MapperProxyFactory注册到Configuration对象中。另外,MyBatis通过MappedStatement类描述Mapper SQL配置信息,框架启动时,会解析Mapper SQL配置,将所有的MappedStatement对象注册到Configuration对象中。

        通过Mapper代理对象调用Mapper接口中定义的方法时,会执行MapperProxy类中的拦截逻辑,将Mapper方法的调用转换为调用SqlSession提供的API方法。在SqlSession的API方法中通过Mapper的Id找到对应的MappedStatement对象,获取对应的SQL信息,通过StatementHandler操作JDBC的Statement对象完成与数据库的交互,然后通过ResultSetHandler处理结果集,将结果返回给调用者。

————————————————————

几种扩展的执行顺序:

Executor   >  ParameterHandler  >  StatementHandler Init  >  TypeHandler getResult Before >  ResultSetHandler   >  StatementHandler Before  >  StatementHandler After  >  Executor

Executor ------> Start    sql:[select  * from  `order` where  sub_size = ? and amount = ?]
ParameterHandler  ------>   select  * from  `order` where  sub_size = ** NOT SPECIFIED ** and amount = ** NOT SPECIFIED **
StatementHandler Init ------>   query
TypeHandler getResult Before ------>   {}
ResultSetHandler  ------>   [{"amount":333,"data":"{}","gmtCreate":1639716832000,"id":2,"jsonData":{},"subSize":333}]
StatementHandler Before ------>   [{"amount":333,"data":"{}","gmtCreate":1639716832000,"id":2,"jsonData":{},"subSize":333}]
StatementHandler After  ------>   [{"amount":333,"data":"{\"StatementHandler\":\"Live\"}","gmtCreate":1639716832000,"id":2,"jsonData":{"StatementHandler":"Live"},"subSize":333}]
Executor ------>  END  [{"amount":333,"data":"{\"StatementHandler\":\"Live\"}","gmtCreate":1639716832000,"id":2,"jsonData":{"StatementHandler":"Live"},"subSize":333}]

————————————————————

MyBatis缓存:

        一级缓存:

        ● 一级缓存默认是开启的,而且不能关闭。

        ● 一级缓存级别:参数 localCacheScope

 SESSION:当指定localCacheScope参数值为SESSION时,缓存对整个SqlSession有效,只有执行DML语句(更新语句)时,缓存才会被清除

 STATEMENT:当localCacheScope值为STATEMENT时,缓存仅对当前执行的语句有效,当语句执行完毕后,缓存就会被清空。

        二级缓存:

        ● 默认二级缓存关闭

        ● 作用域为 Namespaces(xml文件)

        ● 当Namespaces内执行查询操作时,查询结果会缓存到二级缓存中,执行更新操作后,二级缓存会被清空。

        第三方缓存:

        ● 支持使用第三方作为缓存

————————————————————

Mapper的生命周期

Mapper配置文件的读取和装载

Mapper代理的执行

——————————————————————————————————————

笔记内容来源:B站“小河神”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值