mybatis3.2.x源码学习-1

1.下载源码

https://github.com/mybatis/mybatis-3/releases 切换分支 3.2.x

2.找一个测试类 BaseDataTest

刚找到代码,一般开源项目都会有test单元测试类的,mybatis测试的类有点多,我们在最外层发现最容易发现这个类BaseDataTest(说个题外话:我也是刚开始看源码,不是很懂,这个飘红不用管,好像是mock的依赖问题。看这个其实停摸不着头脑的,但是鲁迅曾经说过:如果你想干一件事情,不用管他会不会,先假装自己会,顺着自己的思路去做,时机到了,你自然就会了。不要因为恐惧未知,而不去迈出第一步,多大点事,如果你看到这句话了,就一起加油,共勉)
在这里插入图片描述
点开我们发现这是一个创建DataSource的工具类,我们在依次向上点方法,这个时候发现随便一个方法有很多地方都用到了,不用管,随便进去一个,我就进去BindingTest。

2.找到关键类:SqlSessionFactoryBuilder

等我们找到BindingTest。如下
在这里插入图片描述
我们就发现我们认识的主要的关键类SqlSessionFactoryBuilder。。我们从new SqlSessionFactoryBuilder().build(configuration);点进去build(),这个时候,我们就发现这个BindingTest 是通过 构建Configurtion 去实现sqlSssionFactory.查看这个类的方法,会有很多build构建,都是构建SqlSessionFactory的。像我们常见的demo例子,是通过配置MapperConfig.xml 的方式去构建的。下面我们看一下,我们常用的demo

3.写一个常用mybatis的demo
//这个demo看看就好了,方便理解
static SqlSessionFactory sqlSessionFactory = null;
static {
    sqlSessionFactory = MyBatisUtil.getSqlSEssionFactory();
}

@Test
public void testGetUser() throws Exception {
    //定义 SqlSession
    SqlSession sqlSession =null;
    try{
        //打开 SqlSession会话
        sqlSession= sqlSessionFactory.openSession();
        //执行相关代码
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.getUser(456l);
        System.out.println(JSON.toJSONString(user));
    }cacth(Exception ex){
        System.err.println(ex.getMessage());
       }finally{
        //在 finally 语句中确保资源被删除顺利并关闭
        if(sqlSession !=null){
            sqlSession.close();
        }
    }      
}
--------------------------------------------------------------------MyBatisUtil ------------------------------------------------
public class MyBatisUtil {


    private final static SqlSessionFactory sqlSEssionFactory;


    static {
        String resource = "spring_1_100/config_61_70/mybatis-config.xml";
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSEssionFactory = new SqlSessionFactoryBuilder().build(reader);


    }
    public static SqlSessionFactory getSqlSEssionFactory(){
        return sqlSEssionFactory;
    }
}

一个xml 模板(这个xml和前面自定义demo 没关系了,就是看看用的 源码中的案例方便理解src\test\java\org\apache\ibatis\builder\MapperConfig.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!--

       Copyright 2009-2012 the original author or authors.

       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
       You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.

-->

<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

  <properties resource="databases/blog/blog-derby.properties"/>

  <settings>
    <setting name="cacheEnabled" value="true"/>
    <setting name="lazyLoadingEnabled" value="false"/>
    <setting name="multipleResultSetsEnabled" value="true"/>
    <setting name="useColumnLabel" value="true"/>
    <setting name="useGeneratedKeys" value="false"/>
    <setting name="defaultExecutorType" value="SIMPLE"/>
    <setting name="defaultStatementTimeout" value="25"/>
  </settings>

  <typeAliases>
    <typeAlias alias="Author" type="domain.blog.Author"/>
    <typeAlias alias="Blog" type="domain.blog.Blog"/>
    <typeAlias alias="Comment" type="domain.blog.Comment"/>
    <typeAlias alias="Post" type="domain.blog.Post"/>
    <typeAlias alias="Section" type="domain.blog.Section"/>
    <typeAlias alias="Tag" type="domain.blog.Tag"/>
  </typeAliases>

  <typeHandlers>
    <typeHandler javaType="String" jdbcType="VARCHAR" handler="org.apache.ibatis.builder.ExampleTypeHandler"/>
  </typeHandlers>

  <objectFactory type="org.apache.ibatis.builder.ExampleObjectFactory">
    <property name="objectFactoryProperty" value="100"/>
  </objectFactory>

  <plugins>
    <plugin interceptor="org.apache.ibatis.builder.ExamplePlugin">
      <property name="pluginProperty" value="100"/>
    </plugin>
  </plugins>

  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC">
        <property name="" value=""/>
      </transactionManager>
      <dataSource type="UNPOOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>

  <mappers>
    <mapper resource="org/apache/ibatis/builder/AuthorMapper.xml"/>
    <mapper resource="org/apache/ibatis/builder/BlogMapper.xml"/>
    <mapper resource="org/apache/ibatis/builder/CachedAuthorMapper.xml"/>
    <mapper resource="org/apache/ibatis/builder/PostMapper.xml"/>
    <mapper resource="org/apache/ibatis/builder/NestedBlogMapper.xml"/>
  </mappers>

</configuration>

通过demo,我们知道我们的sqlSEssionFactory 是通过reader数据源去执行,这段关键代码 sqlSEssionFactory = new SqlSessionFactoryBuilder().build(reader);那么,我们再来看SqlSessionFactoryBuilder类构造器中的build方法,可以看到,主要是通过这个方法去实现:
在这里插入图片描述

4. XMLConfigBuilder-通过名字大概知道是分析xml的Config构造器

接下来,就可以看到关键方法parser.parse(),点进去看一下,找到关键代码,看看。这每个方法就是一个关键逻辑,由于我是刚开始看,我在网上看了别人的介绍,注释我沾上来了,方便理解。
在这里插入图片描述
在这段代码中,看见XMLConfigBuilder 会对xml配置进行解析,通过每个XNode parent 节点,去设置Configuration 对象。感觉不用每个去看,挑个主要的mapper去看看。
在这里插入图片描述
就这个,我们随便进个主要的解析看看 mapperParser.parse();


5. XMLMapperBuilder-通过名字大概知道是分析xml的mapper构造器

进入 mapperParser.parse();这个类XMLMapperBuilder的parse()方法,我们继续往下看,此时先贴一个AuthorMapper.xml(源码里面的src\test\java\org\apache\ibatis\builder\AuthorMapper.xml)方便理解

<?xml version="1.0" encoding="UTF-8" ?>
<!--
       Copyright 2009-2012 the original author or authors.

       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
       You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.
-->
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="domain.blog.mappers.AuthorMapper">

	<parameterMap id="selectAuthor" type="domain.blog.Author">
		<parameter property="id" />
	</parameterMap>

	<resultMap id="selectAuthor" type="domain.blog.Author">
		<id column="id" property="id" />
		<result property="username" column="username" />
		<result property="password" column="password" />
		<result property="email" column="email" />
		<result property="bio" column="bio" />
		<result property="favouriteSection" column="favourite_section" />
	</resultMap>

	<resultMap id="selectImmutableAuthor" type="domain.blog.ImmutableAuthor">
		<constructor>
			<idArg column="id" javaType="_int" />
			<arg column="username" javaType="string" />
			<arg column="password" javaType="string" />
			<arg column="email" javaType="string" />
			<arg column="bio" javaType="string" />
			<arg column="favourite_section" javaType="domain.blog.Section" />
		</constructor>
	</resultMap>

	<resultMap id="complexAuthorId" type="domain.blog.ComplexImmutableAuthorId">
		<constructor>
			<idArg column="id" javaType="_int" />
			<idArg column="username" javaType="string" />
			<idArg column="password" javaType="string" />
			<idArg column="email" javaType="string" />
		</constructor>
	</resultMap>

	<resultMap id="selectComplexImmutableAuthor" type="domain.blog.ComplexImmutableAuthor">
		<constructor>
			<idArg javaType="domain.blog.ComplexImmutableAuthorId"
				resultMap="complexAuthorId" />
			<arg column="bio" javaType="string" />
			<arg column="favourite_section" javaType="domain.blog.Section" />
		</constructor>
	</resultMap>

	<select id="selectAllAuthors" resultType="domain.blog.Author">
		select * from author
	</select>

	<select id="selectAllAuthorsSet" resultType="domain.blog.Author">
		select * from author
	</select>

	<select id="selectAllAuthorsVector" resultType="domain.blog.Author">
		select * from author
	</select>

	<select id="selectAllAuthorsLinkedList" resultType="domain.blog.Author">
		select * from author
	</select>

	<select id="selectAllAuthorsArray" resultType="domain.blog.Author">
		select * from author
	</select>

	<select id="selectComplexAuthors" resultMap="selectComplexImmutableAuthor">
		select * from author
	</select>

	<select id="selectAuthor" parameterMap="selectAuthor" resultMap="selectAuthor">
		select id, username, password, email, bio, favourite_section
		from author where id = ?
	</select>

	<select id="selectImmutableAuthor" parameterMap="selectAuthor"
		resultMap="selectImmutableAuthor">
		select id, username, password, email, bio, favourite_section
		from author where id = ?
	</select>

	<select id="selectAuthorWithInlineParams" parameterType="int"
		resultType="domain.blog.Author">
		select * from author where id = #{id}
	</select>

	<insert id="insertAuthor" parameterType="domain.blog.Author">
		insert into Author (id,username,password,email,bio)
		values (#{id},#{username},#{password},#{email},#{bio})
	</insert>

	<update id="updateAuthor" parameterType="domain.blog.Author">
		update Author
		set username=#{username,
		javaType=String},
		password=#{password},
		email=#{email},
		bio=#{bio}
		where id=#{id}
	</update>

	<delete id="deleteAuthor" parameterType="int">
		delete from Author where id = #{id}
	</delete>


	<update id="updateAuthorIfNecessary" parameterType="domain.blog.Author">
		update Author
		<set>
			<if test="username != null">username=#{username},</if>
			<if test="password != null">password=#{password},</if>
			<if test="email != null">email=#{email},</if>
			<if test="bio != null">bio=#{bio}</if>
		</set>
		where id=#{id}
	</update>


</mapper>

然后上XMLMapperBuilder的parse()方法:
在这里插入图片描述
可以进入第一方法 简单看看configurationElement()
在这里插入图片描述

我们发现,XMLMapperBuilder的 MapperBuilderAssistant builderAssistant;这个属性是用来保存每个mapper的属性设置。等到外层的下面三个方法进行加载再到configuration的配置属性中。

6. XMLStatementBuilder-通过名字大概知道是分析xml的语句构造器

通过 buildStatementFromContext(context.evalNodes(“select|insert|update|delete”));这个方法,我们进去看看执行sql的配置类
一层一层点进去 找到 XMLStatementBuilder()的这个方法,就是设置sql语句的构造器

在这里插入图片描述
在这里插入图片描述

通过这个方法一层层设置,最后保存在 configuration中的 protected final Map<String, MappedStatement> mappedStatements = new StrictMap(“Mapped Statements collection”);这个属性

7. DefaultSqlSessionFactory-默认SqlSessionFactory的实现类

回到前面 sqlSEssionFactory = new SqlSessionFactoryBuilder().build(reader);这个方法构造。当我们设置完configuration,就默认建立一个DefaultSqlSessionFactory默认sqlSesion工厂,里面关键参数configuration。
在这里插入图片描述
未完待续…

============================================================================================
mybatis3.2.x源码学习-1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值