搭建一个最简单的 mybatis 3.3 demojava
新建一个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 的层次结构。
mysql
InputStream inputStream = Resources.getResourceAsStream(resource);//为何能够获得InputStream
进入Recources类sql
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; } }