mybatis 3.3 源码阅读(一)

原创
2016/03/23 10:54
阅读数 246

                                                                   搭建一个最简单的 mybatis 3.3 demo

新建一个jdbc.properties文件,内容为:
jdbc_driverClassName=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3307/person_blog?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull
jdbc_username=xxxx
jdbc_password=xxx
新建一个配置文件 configuration.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 resource="com/debug/mybaits/jdbc.properties">
	</properties>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc_driverClassName}" />
				<property name="url" value="${jdbc_url}" />
				<property name="username" value="${jdbc_username}" />
				<property name="password" value="${jdbc_password}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<!-- <mapper resource="com/debug/mybaits/BlogMapper.xml" />
			<mapper resource="com/debug/mybaits/XueMapper.xml" /> -->
			<package name="com.debug.mybaits"></package>
	</mappers>
</configuration>

    

写根据实体写一个简单的 BlogMapper.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 namespace="com.debug.mybaits.BlogMapper">
	 <select id="selectBlog" parameterType="int" resultType="com.debug.mybaits.Blog">
		select * from Blog where blog_id = #{blog_id}
	</select> 
</mapper>
新建一个实体bean
    public class Blog {
	private int blog_id;
	private String blog_title;
	public int getBlog_id() {
		return blog_id;
	}
	public void setBlog_id(int blog_id) {
		this.blog_id = blog_id;
	}
	public String getBlog_title() {
		return blog_title;
	}
	public void setBlog_title(String blog_title) {
		this.blog_title = blog_title;
	}
}
定义一个BlogMapper 接口

public interface BlogMapper {
//	@Select("select *from Blog where blog_id = #{blog_id}")
	Blog selectBlog(int blog_id);
}
查询一次结果是否正确
    public class Main {
	public static void main(String args[]) throws IOException{
		String resource = "com/debug/mybaits/configuration.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		try {
			BlogMapper mapper = session.getMapper(BlogMapper.class);
			Blog blog=	mapper.selectBlog(1);
			XueMapper mapper1 = session.getMapper(XueMapper.class);
			Xue xue=	mapper1.selectXue(20);
		System.out.println(blog.getBlog_title()+" "+xue.getGrade());
		} finally {
		session.close();
		}
	
	}
}

    前面是为了说明我分析源码之前的用法,后面根据用法来分析mybatis 的层次结构。

    

InputStream inputStream = Resources.getResourceAsStream(resource);//为什么可以得到InputStream

    进入Recources类

public class Resources {

  private static ClassLoaderWrapper classLoaderWrapper = new ClassLoaderWrapper();
  ......
    public static InputStream getResourceAsStream(String resource) throws IOException {
    return getResourceAsStream(null, resource);
  } 
  public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {
    //这个地方发现mybatis的具体获取InputStream 是委托给了ClassLoaderWrapper 
    InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader);
    if (in == null) {
      throw new IOException("Could not find resource " + resource);//如果没有找到的话就报的错
    }
    return in;
  }
 }

    进入ClassLoaderWrapper类:

public class ClassLoaderWrapper {

  ClassLoader defaultClassLoader;
  ClassLoader systemClassLoader;
  
  public InputStream getResourceAsStream(String resource, ClassLoader classLoader) {
    return getResourceAsStream(resource, getClassLoaders(classLoader));//这个就是委托的
  }
   ClassLoader[] getClassLoaders(ClassLoader classLoader) {
    return new ClassLoader[]{
        classLoader,//按照指定的顺序返回一个classLoader数组,为什么要这个顺序我也没有搞清楚
        defaultClassLoader,
        Thread.currentThread().getContextClassLoader(),
        getClass().getClassLoader(),
        systemClassLoader};
  }
  
  InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
    for (ClassLoader cl : classLoader) {
      if (null != cl) {

        // try to find the resource as passed
        InputStream returnValue = cl.getResourceAsStream(resource);//就是实际获取流的地方

        // now, some class loaders want this leading "/", so we'll add it and try again if we didn't find the resource
        if (null == returnValue) {
          returnValue = cl.getResourceAsStream("/" + resource);
        }

        if (null != returnValue) {
          return returnValue;
        }
      }
    }
    return null;
  }
}

    

展开阅读全文
打赏
1
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
1
分享
返回顶部
顶部