- 访问数据库的五个步骤
- 注册驱动和数据库信息
- 获取
Connection,得到Statement对象 - 通过
Statement对象预执行SQL语句,得到处理结果 - 对处理结果进行相关的处理
- 关闭数据库连接对象
- 缺点
- 代码量很大,比较麻烦
- 需要对异常进行捕获并进行相应的处理
- 优点
- 将映射规则分离到
xml或注解中,减少了代码的耦合度 - 无需管理数据库连接,住需配置对应的
XML即可 - 一个会话,只需要操作
Session即可 - 关闭资源,只需要关闭
Session即可
- 将映射规则分离到
- 缺点
- 全表映射不便利,更新时需要发送所有字段
- 无法根据不同的条件组装不同的
SQL - 对于多表连接和复杂
SQL查询支持较差,需要自己手动编写SQL,同时需要自己将处理结果组合为 POJO 对象 HQL性能较差,无法优化SQL- 不能有效支持存储过程
- 优点
- 可以动态配置
SQL - 可以对
SQL进行优化,并通过配置来决定SQL的映射规则 - 支持存储过程
- 具有自动映射功能,在注意命名规则的基础上,无须再写映射规则
- MyBatis 提供接口编程的映射器,只需要一个接口和映射文件便可以运行
- 代码耦合度低
- 可以动态配置
-
mybatis-config.xml-
Mybatis 的配置文件,使用时稍作修改即可
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 一些配置属性,在此处配置即可在别的区域使用 `$` 进行引用,方便统一进行管理 --> <properties> <property name="url" value="jdbc:mysql://127.0.0.1:3306/effect_db?useSSL=true&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="17358870357yi"/> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> </properties> <settings> <!-- 有关日志的配置, 可选的值为 SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING 或者任何实现了 `org.apache.ibatis.logging.Log ` 接口,且构造方法以字符串为参数的类完全限定名 --> <setting name="logImpl" value="STDOUT_LOGGING"/> <!-- 设置列和字段属性的自动配置,NONE 表示取消自动配置,PARTIAL 设置部分映射,FULL 表示全自动映射(包括嵌套映射) --> <setting name="autoMappingBehavior" value="NONE"/> <!-- 是否开启将下划线命名转换为驼峰式命名,如果开启,则需要启动上文的自动映射行为 --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <environments default="dev"> <environment id="dev"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <databaseIdProvider type="DB_VENDOR" /> <mappers> <mapper resource="mapper/UserMapper.xml" /> </mappers> </configuration>
-
-
mapper映射文件-
入参方式
@Param注解指定传入参数名称- 不带任何注解,则以传入的参数名为传入的参数
- 使用
Map, 设置对应的查询参数,将Map作为参数传入,可以得到Map的 key 的参数值 - 以实体的方式传入参数,可以得到实体的字段属性值
-
相关标签
- - 映射文件的主标签,设置 `namespace` 属性指定关联的要实现接口
- - 配置类属性和查询列的映射规则
- - 插入方法执行后需要手动提交事物,才能完成记录的插入(或者在调用 `openSession` 方法时设置为 true,即可实现插入时的自动提交) - 设置 `useGenearatedKeys` 实现自增主键的回写
-
入参与结果集
$与#传递参数的区别$使用值传递的方式构建SQL语句, 可能会造成SQL注入,存在安全性的问题#使用预编译的方式构建SQL语句
- 存储结果集的方式
Map方式存储结果集POJO方式存储结果
-
- 一对一级联
- 直接关联到
DAO即可
- 直接关联到
- 一对多级联
- 直接关联对应的
DAO即可
- 直接关联对应的
- 一级缓存
- MyBatis 默认开启的缓存
- 多次对同一个 Session 的同一对象的查询,将会从缓存中查询
- 每次新的 Session 的创建,都会使得一级缓存失效
- 二级缓存
- 需要手动开启
- 在
Mapper.xml文件内,添加<cache />标签即可开启二级缓存 - 每次记录的读都要手动提交事务,才能使得二级缓存可以命中
- 要求实例化对象实现
Serializable接口,即实例化对象是可序列化的
- 自定义缓存
- 要求实现
org.apache.ibatis.cache.Cache接口 - 在
Mapper.xml中加入 标签 - 将 标签的
type属性设置为自定义标签
- 要求实现
ExecutorStatementHandlerPreparementHandlerResultSetHandler
-
首先在创建
Session会将对应的Mybatis配置文件读入Configuration对象中,注册相关的Mapper.xml映射文件 -
getMapper的执行流程DefaultSqlSession调用Configuration的getMapperMapRegister提供一个HashMap, 保存对每个Mapper.xml的注册- 通过对应的
Mapper.xml生成对应的代理对象,该代理对象使用的是 JDK 的动态代理的方式
-
mapper接口方法的执行
-
调用代理对象的
invoke方法,被代理的方法所在的类method = getUserById(2L); declaringClass = mapper.UserMapper.class;
-
如果得到的的
declaringClass是java.lang.Object,则调用Object的方法;如果method是defaultMethod, 那么调用defaultMethod -
如果以上两个条件都不满足,则会获取
MapperMethod实例-
如果缓存中存在对应的
MapperMethod实例,则直接从缓存中获取 -
创建
SqlCommand对象-
SqlCommand只维护两个属性// MappedStatement 的唯一标识 id private final String name; // sql的命令类型 UNKNOWN, INSERT, UPDATE, DELETE, SELECT, FLUSH; private final SqlCommandType type;
-
拼装
statementId如
mapper.UserMapper.getUserById- 获取
MappedStatement对象- 以
statementId为key,查询Configuration配置对象内的Map<String, MappedStatement> mappedStatements,如果对应的MappedStatement,则直接返回该MappedStatement实例对象 - 如果
Configuration对象不包含对象,则遍历Mapper接口类的方法,查询这些接口方法是否有对应的MappedStatement, 如果有,则直接返回该实例对象,否则返回null
- 以
- 得到
SqlCommand对象- 如果得到的
MappedStatement不为null,则可以从MappedStaement中得到对应的方法签名和该SQL的操作类型。 - 如果得到的
MappedStatement为null,则会检查对应的方法是否设置了@Flush注解,如果设置了@Flush注解,那么就会将方法全限定名设置为null,SQL执行类型为FLUSH。 - 如果未设置
@Flush注解,则会抛出BindingException异常
- 如果得到的
- 获取
-
-
创建
MethodSignature对象
-
-
将
MapperMethod放入缓存






