搭建一个最简单的 mybatis 3.3 demo
新建一个jdbc.properties文件,内容为:jdbc_driverClassName=com.mysql.jdbc.Driverjdbc_url=jdbc:mysql://localhost:3307/person_blog?characterEncoding=utf8&zeroDateTimeBehavior=convertToNulljdbc_username=xxxxjdbc_password=xxx
新建一个配置文件 configuration.xml,内容为:
写根据实体写一个简单的 BlogMapper.xml 文件
新建一个实体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; }}