一直想探究Mybatis的内部实现,之前自己抽空看了下源码,当时把核心的代码流程都能走一遍,感觉似懂非懂的懂了,过了一段时间呢又没啥收获了,还是缺乏理解深度。最近有时间买了本《Mybatis技术内幕》,站在大牛的肩膀,更好的理解Mybatis。
在开始认识Mybatis之前,得先了解一些基本概念
基本概念
JDBC
- Java和数据库交互的统一API
- 两部分:Java API 、数据库驱动API
- JDBC操作步骤:
- 打开连接—数据库驱动 :URL 用户名 密码等连接信息
- DriverManager
- Statement
- ResultSet
- 转JavaBean
- 关闭连接
- 数据源
- 结果缓存
- 数据库连接池
ORM
- Object Relational Mapping 对象关系映射
- java 文件 <—> 映射配置文件 <—> 数据库
- 常见ORM框架
Hibernate
- hbm.xml配置
- java 对象 OneToMany、OneToOne、ManyToMany关系,应用层对象维护主外键关系
- HQL语句,面向对象的思维,屏蔽掉底层数据库的差异。
- 没有代码侵入性,业务代码不需要继承或实现Hibernate任何类和接口
- 提供一级和二级缓存,降低数据库压力
- 根据对象模型自动建表
- 缺点:
- 数据库有自身的组织方式,hibernate生成的sql不一定是最优性能,并且很难修改生成的SQL
- 数据量大,结构复杂的表,生成的SQL复杂,索引不能正确使用,导致大量慢查询,不适合大数据量,高并发,低延迟的场景
- 对批处理的支持并不友好,会影响部分性能
JPA
- EJB3.0中的持久化部分的规范,并没有提供实现。
Spring JDBC
- 本质是个使用模板方法封装了原生JDBC,并不算ORM框架
- 封装Template
- 提供Callback ,供处理ResultSet
MyBatis
- 屏蔽原生JDBC,配置文件实现ResultSet与Java对象映射
- 轻量级,可控性高,半自动化编写SQL语句,更加灵活,提高系统性能。
Hibernate、Mybatis和Spring JDBC三者比较
- Hibernate生成SQL语句,Spring JDBC和Mybaits使用原生SQL
- Mybatis 和 Hibernate 使用二级缓存
- Hibernate屏蔽数据方言,Spring JDBC和Mybaits未支持
- Hibernate和Mybatis 通过XML配置,Spring JDBC通过Template 和Callback 方式实现
- 量级重到轻:Hibernate --> Mybatis --> Spring JDBC
Mybatis整体架构
整体架构分为三层:基础支持层、核心处理层和接口层
基础支持层
- 反射模块:对Java原生的反射进行良好封装,提供简洁易用的API,供上层使用。并进行了优化,提高反射性能
- 类型转换模块:别名机制;Java类型与JDBC类型转换
- 日志模块:提供详细的日志输出信息,还能够集成多种日志框架。日志模块主要功能集成第三方日志框架
- 资源加载模块:对类加载器的封装,加载类文件,资源文件
- 解析器模块:XPath的封装,解析配置文件提供支持;处理动态SQL语句的占位符提供支持
- 数据源模块:自身提供数据源模块,也提供了第三方数据源集成的接口
- 事务管理:自身提供事务接口和简单实现,也与Spring框架集成,由Spring框架管理事务
- 缓存模块:Mybatis 一级二级缓存都依赖缓存模块实现,利用的是JVM堆内存。
- Binding模块:将用户自定义的Mapper接口和映射配置文件关联起来,系统可通过Mapper接口中的方法执行对应的SQL语句,完成数据库操作。
核心处理层
实现了MyBatis的核心处理流程,包括初始化及完成一次数据库操作涉及的全部流程。
- 配置解析:解析mybatis-config.xml文件、映射配置文件及Mapper接口注解信息,保存Configuration对象中,利用Configuration对象创建SqlSessionFactory对象等。
- SQL解析与scripting模块:提供动态SQL语句功能,对应各种节点。例如、等。scripting模块接受用户传参,占位符解析绑定入参。
- SQL执行:Executor(提供事务管理,维护一、二级缓存)、StatementHandler、ParameterHandler和ResultSetHandler等。
- 插件:提供插件接口,供添加用户自定义插件,可以改变Mybatis默认行为。例如:可以拦截SQL语句并对其重写。
接口层
暴露给应用程序调用的API,核心是SqlSession接口。
使用Mybatis的示例代码
mybatis-config.xml
<?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 指定properties配置文件,指定数据库连接配置文件 -->
<properties resource="database.properties"/>
<!-- settings配置:这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。一般使用只需保持默认值。 -->
<settings>
<!-- 全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存。默认true -->
<setting name="cacheEnabled" value="true"/>
<!--延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。默认false-->
<setting name="lazyLoadingEnabled" value="false"/>
<!--当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载(参考lazyLoadTriggerMethods).默认值 false (true in ≤3.4.1)-->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 是否允许单一语句返回多结果集(需要兼容驱动)。 默认true-->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 使用列标签代替列名。不同的驱动在这方面会有不同的表现, 具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。 默认值true-->
<setting name="useColumnLabel" value="true"/>
<!-- 允许 JDBC 支持自动生成主键,需要驱动兼容。 如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。默认false-->
<setting name="useGeneratedKeys" value="false"/>
<!--指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。默认为PARTIAL-->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!--指定发现自动映射目标未知列(或者未知属性类型)的行为。-->
<!--
NONE: 不做任何反应
WARNING: 输出提醒日志 ('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN)
FAILING: 映射失败 (抛出 SqlSessionException)
-->
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<!-- 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。默认SIMPLE -->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!--设置超时时间,它决定驱动等待数据库响应的秒数。设置任意正值,没有默认值-->
<setting name="defaultStatementTimeout" value="25"/>
<!--为驱动的结果集获取数量(fetchSize)设置一个提示值。此参数只可以在查询设置中被覆盖。设置任意正值,没有默认值-->
<setting name="defaultFetchSize" value="100"/>
<!--允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为false。 默认false-->
<setting name="safeRowBoundsEnabled" value="false"/>
<!--允许在嵌套语句中使用分页(ResultHandler)。如果允许使用则设置为false。默认true-->
<setting name="safeResultHandlerEnabled" value="true"/>
<!--是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。默认为false-->
<setting name="mapUnderscoreToCamelCase" value="false"/>
<!--MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。
若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。-->
<setting name="localCacheScope" value="SESSION"/>
<!--当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。默认值OTHER-->
<setting name="jdbcTypeForNull" value="OTHER"/>
<!--指定哪个对象的方法触发一次延迟加载。用逗号分隔的方法列表。默认值:equals,clone,hashCode,toString -->
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
<!--声明类型的别名,可以将一个类,指定一个简单的名字,后面直接代替-->
<typeAliases>
<typeAlias alias="String" type="java.lang.String"/>
<typeAlias alias="Dict" type="ybs.mybatis.model.Dict"/>
</typeAliases>
<!--指定一个类型处理器,mybatis默认提供了基本类型的类型匹配器,除非不够用,自己可以自定义。-->
<typeHandlers>
<typeHandler handler="ExampleTypeHandler"/>
</typeHandlers>
<!--
MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。
默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。 如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现
继承DefaultObjectFactory来扩展
-->
<objectFactory type="ExampleObjectFactory">
<property name="someProperty" value="100"/>
</objectFactory>
<!--写一些插件,来拦截加入一些功能:自定义插件类implements Interceptor-->
<plugins>
<plugin interceptor="ExamplePlugin">
<property name="someProperty" value="100"/>
</plugin>
</plugins>
<!--配置环境-->
<!--
尽管可以配置多个环境,每个 SqlSessionFactory 实例只能选择其一
如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例
在初始化SqlSessionFactory时进行指定哪个environment
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
environment 参数为String,environment的id值
-->
<environments default="development">
<environment id="development">
<!--
事务管理器
在 MyBatis 中有两种类型的事务管理器(也就是 type=”[JDBC|MANAGED]”)
JDBC – 这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。
默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。
你可以使用 TransactionFactory 接口的实现类的完全限定名或类型别名代替它们。
-->
<!--如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器, 因为 Spring 模块会使用自带的管理器来覆盖前面的配置。-->
<transactionManager type="JDBC"/>
<!--
配置数据库连接、数据库连接池
有三种内建的数据源类型(也就是 type=”[UNPOOLED|POOLED|JNDI]”)
UNPOOLED– 这个数据源的实现只是每次被请求时打开和关闭连接。虽然有点慢,但对于在数据库连接可用性方面没有太高要求的简单应用程序来说,是一个很好的选择。
POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
JNDI – 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用
你可以通过实现接口 org.apache.ibatis.datasource.DataSourceFactory 来使用第三方数据源
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://10.27.164.193:3306/cfsdb"/>
<property name="username" value="devadmin"/>
<property name="password" value="KTaDN9eMHY"/>
</dataSource>
</environment>
<environment id="sit">
<!-- 事务管理器 -->
<transactionManager type="JDBC"/>
<!-- 配置数据库连接、数据库连接池 -->
<dataSource type="POOLED">
<!--
property属性可以利用占位符号表示,利用property文件指定值。
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);
Properties类型的参数
-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。-->
<databaseIdProvider type="DB_VENDOR">
<property name="SQL Server" value="sqlserver"/>
<property name="DB2" value="db2"/>
<property name="Oracle" value="oracle"/>
</databaseIdProvider>
<!--指定sql资源路径-->
<mappers>
<!-- 指定mapper下的包路径。
<package name="mapper" />
-->
<mapper resource="mapper/DictMapper.xml"/>
</mappers>
</configuration>
Mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<!--完整的解释mapper的配置项-->
<!--
cache – 给定命名空间的缓存配置。
cache-ref – 其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
parameterMap – 已废弃!老式风格的参数映射。内联参数是首选,这个元素可能在将来被移除,这里不会记录。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句
-->
<!-- Namespaces 命名空间 :在之前版本的 MyBatis 中是可选的,这样容易引起混淆因此毫无益处。
现在命名空间则是必须的,且意于简单地用更长的完全限定名来隔离语句。-->
<mapper>
<!--字段映射实体-->
<resultMap id="dictMap" type="ybs.mybatis.model.Dict" >
<id column="ID" property="id" jdbcType="BIGINT" />
<result column="NAME" property="name" jdbcType="VARCHAR" />
<result column="DICT_CODE" property="dictCode" jdbcType="VARCHAR" />
<result column="DICT_KEY" property="dictKey" jdbcType="VARCHAR" />
<result column="DICT_VALUE" property="dictValue" jdbcType="VARCHAR" />
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
<result column="CREATOR" property="creator" jdbcType="BIGINT" />
<result column="CREATED_TIME" property="createdTime" jdbcType="TIMESTAMP" />
<result column="MODIFER" property="modifer" jdbcType="BIGINT" />
<result column="MODIFIED_TIME" property="modifiedTime" jdbcType="TIMESTAMP" />
</resultMap>
<!--
查询语句,parameterType接受参数类型 resultType返回集合类型
#{id} 个预处理语句参数,通过 JDBC,这样的一个参数在 SQL 中会由一个“?”来标识
-->
<!--
select标签下,各种属性
id 在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType 将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。
parameterMap 这是引用外部 parameterMap 的已经被废弃的方法。使用内联参数映射和 parameterType 属性。
resultType 从这条语句中返回的期望类型的类的完全限定名或别名。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用 resultType 或 resultMap,但不能同时使用。
resultMap 外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,对其有一个很好的理解的话,许多复杂映射的情形都能迎刃而解。使用 resultMap 或 resultType,但不能同时使用。
flushCache 将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:false。
useCache 将其设置为 true,将会导致本条语句的结果被二级缓存,默认值:对 select 元素为 true。
timeout 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。
fetchSize 这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为 unset(依赖驱动)。
statementType STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
resultSetType FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一个,默认值为 unset (依赖驱动)。
databaseId 如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。
resultOrdered 这个设置仅针对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false。
resultSets 这个设置仅对多结果集的情况适用,它将列出语句执行后返回的结果集并每个结果集给一个名称,名称是逗号分隔的。
-->
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultType="ybs.mybatis.model.Dict">
select * from CF_DICT where id = #{id,jdbcType=BIGINT}
</select>
<!--
insert/update/delete 各种属性
id 命名空间中的唯一标识符,可被用来代表这条语句。
parameterType 将要传入语句的参数的完全限定类名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。
parameterMap 这是引用外部 parameterMap 的已经被废弃的方法。使用内联参数映射和 parameterType 属性。
flushCache 将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:true(对应插入、更新和删除语句)。
timeout 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。
statementType STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
useGeneratedKeys (仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。
keyProperty (仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
keyColumn (仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
databaseId 如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。
-->
<insert
id="insertAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
keyProperty=""
keyColumn=""
useGeneratedKeys="true"
timeout="20">
</insert>
<update
id="updateAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
</update>
<delete
id="deleteAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
</delete>
<!--这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。相当于sql片段,可以供公用-->
<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
<!--试用sql的地方,利用include标签
<include refid="userColumns">
<property name="prefix" value="Some"/>
<property name="include_target" value="sometable"/>
</include>
-->
<!--
MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。
默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:
映射语句文件中的所有 select 语句将会被缓存。
映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。
缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
-->
<cache/>
<!--
<cache
可用的收回策略有: 默认是LRU
LRU – 最近最少使用的:移除最长时间不被使用的对象。
FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象
eviction="FIFO"
每隔 60 秒刷新;flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
flushInterval="60000"
存数结果对象或列表的 512 个引用。引用数目:可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可用内存资源数目。默认值是 1024。
size="512"
返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会 导致冲突。
只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化) 。这会慢一些,但是安全,因此默认是 false。
readOnly="true"/>
-->
</mapper>
Mapper接口
/**
* 库表操作类
*
* @author yanbin
* @version 2018/3/29 11:14
*
**/
public interface DictMapper {
/**
* 根据主键获取结果
*
* @param id
* @return
*/
Dict selectByPrimaryKey(Long id);
/**
* 插入
*
* @param dict
* @return
*/
int insert(Dict dict);
/**
* 根据主键ID更新
*
* @param dict
* @return
*/
int updateByPrimaryKey(Dict dict);
/**
* 查询所有的记录
*
* @return
*/
List<Dict> selectAll();
}
Model类
/**
* 数据库表对应的实体类
*
* @author yanbin
* @version 2018/3/29 11:12
*
**/
public class Dict {
private Long id;
private String name;
private String dictCode;
private String dictKey;
private String dictValue;
private String description;
private Long creator;
private Date createdTime;
private Long modifer;
private Date modifiedTime;
getter();
setter();
}
业务执行操作类
/**
* 基本的mybatis操作,基于xml配置
*
* @author yanbin
* @version 2018/3/29 10:38
*
**/
public class BaseStart {
/**
* 最基本的操作mybatis的步骤。
*/
public void start() throws IOException {
// 1、获取配置,生成Configuration 对象
String resouce = "mybatis-config-base.xml";
InputStream inputStream = Resources.getResourceAsStream(resouce);
// 2、基于配置构建SqlSessionFactory对象
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 3、获取SqlSession对象
SqlSession sqlSession = sessionFactory.openSession();
try {
// 4、通过SqlSession,获取到对应的Mapper
// 老的API使用方式,
// Dict dict = (Dict)
// sqlSession.selectOne("ybs.mybatis.mapper.DictMapper.selectByPrimaryKey", 1l);
DictMapper dictMapper = sqlSession.getMapper(DictMapper.class);
System.out.println(dictMapper);
// 5、执行SQL操作
Dict dict = dictMapper.selectByPrimaryKey(202l);
System.out.println(dict.getId() + dict.getName());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 6、关闭sqlSession
sqlSession.close();
}
}
}