如何进行Java Mybatis中的Mapper原理分析
导读:本文共4619.5字符,通常情况下阅读需要15分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 准备1.pom文件<dependencies><!--mybatis坐标--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5&l... ...
目录
(为您整理了一些要点),点击可以直达。准备
1.pom文件
<dependencies><!--mybatis坐标--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><!--mysql驱动坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version><scope>runtime</scope></dependency><!--单元测试坐标--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!--日志坐标--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.2</version><scope>provided</scope></dependency></dependencies>
2.user类-数据库
3.实体类
@Getter@Setter@ToString@NoArgsConstructorpublicclassuser{privateintid;privateStringusername;privateStringpassword;}
4.dao 层
publicinterfaceuserDao{List<user>findAll();}
5.Mapper 文件
<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="dao.userDao"><selectid="findAll"resultType="mode.user">select*fromuser</select></mapper>
核心配置文件
<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTDConfig3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!--通过properties标签加载外部properties文件--><propertiesresource="jdbc.properties"></properties><!--自定义别名--><typeAliases><typeAliastype="mode.user"alias="user"></typeAlias></typeAliases><!--数据源环境--><environmentsdefault="developement"><environmentid="developement"><transactionManagertype="JDBC"></transactionManager><dataSourcetype="POOLED"><propertyname="driver"value="${jdbc.driver}"/><propertyname="url"value="${jdbc.url}"/><propertyname="username"value="${jdbc.username}"/><propertyname="password"value="${jdbc.password}"/></dataSource></environment></environments><!--加载映射文件--><mappers><mapperresource="userMapper.xml"></mapper></mappers></configuration>
核心代码
importdao.userDao;importmode.user;importorg.apache.ibatis.io.Resources;importorg.apache.ibatis.session.SqlSession;importorg.apache.ibatis.session.SqlSessionFactory;importorg.apache.ibatis.session.SqlSessionFactoryBuilder;importjava.io.IOException;importjava.io.InputStream;importjava.util.List;publicclassTestMapper{publicstaticvoidmain(String[]args)throwsIOException{//加载核心配置文件InputStreamresourceAsStream=Resources.getResourceAsStream("SqlMapConfig.xml");//获得sqlSession工厂对象SqlSessionFactorysqlSessionFactory=newSqlSessionFactoryBuilder().build(resourceAsStream);//获得sqlSession对象SqlSessionsqlSession=sqlSessionFactory.openSession();//执行sql语句userDaomapper=sqlSession.getMapper(userDao.class);List<user>userList=mapper.findAll();//打印结果System.out.println(userList);//释放资源sqlSession.close();}}
源码分析
1.断点
2.查看源码
DefaultSqlSession:
Configuration:
这是Configuration 类。我们主要看getMapper()方法
MapperRegistry:
关键代码:mapperProxyFactory.newInstance(sqlSession);
MapperProxyFactory:
返回的是MapperProxy 对象
MapperProxy:
源码:
//Sourcecoderecreatedfroma.classfilebyIntelliJIDEA//(poweredbyFernFlowerdecompiler)//packageorg.apache.ibatis.binding;importjava.io.Serializable;importjava.lang.invoke.MethodHandles.Lookup;importjava.lang.reflect.Constructor;importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.util.Map;importorg.apache.ibatis.lang.UsesJava7;importorg.apache.ibatis.reflection.ExceptionUtil;importorg.apache.ibatis.session.SqlSession;publicclassMapperProxy<T>implementsInvocationHandler,Serializable{privatestaticfinallongserialVersionUID=-6424540398559729838L;privatefinalSqlSessionsqlSession;privatefinalClass<T>mapperInterface;privatefinalMap<Method,MapperMethod>methodCache;publicMapperProxy(SqlSessionsqlSession,Class<T>mapperInterface,Map<Method,MapperMethod>methodCache){this.sqlSession=sqlSession;this.mapperInterface=mapperInterface;this.methodCache=methodCache;}publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{try{if(Object.class.equals(method.getDeclaringClass())){returnmethod.invoke(this,args);}if(this.isDefaultMethod(method)){returnthis.invokeDefaultMethod(proxy,method,args);}}catch(Throwablevar5){throwExceptionUtil.unwrapThrowable(var5);}MapperMethodmapperMethod=this.cachedMapperMethod(method);returnmapperMethod.execute(this.sqlSession,args);}privateMapperMethodcachedMapperMethod(Methodmethod){MapperMethodmapperMethod=(MapperMethod)this.methodCache.get(method);if(mapperMethod==null){mapperMethod=newMapperMethod(this.mapperInterface,method,this.sqlSession.getConfiguration());this.methodCache.put(method,mapperMethod);}returnmapperMethod;}@UsesJava7privateObjectinvokeDefaultMethod(Objectproxy,Methodmethod,Object[]args)throwsThrowable{Constructor<Lookup>constructor=Lookup.class.getDeclaredConstructor(Class.class,Integer.TYPE);if(!constructor.isAccessible()){constructor.setAccessible(true);}Class<?>declaringClass=method.getDeclaringClass();return((Lookup)constructor.newInstance(declaringClass,15)).unreflectSpecial(method,declaringClass).bindTo(proxy).invokeWithArguments(args);}privatebooleanisDefaultMethod(Methodmethod){return(method.getModifiers()&1033)==1&&method.getDeclaringClass().isInterface();}}
在invoke方法中可以看到,如果我们调用的是Object中的方法,不做任何处理,直接调用,否则执行:
mapperMethod.execute(this.sqlSession, args);
MapperMethod:
在MapperMethod 中对SQL语句进行分类反射
MapperProxyFactory中,使用JDK的动态代理生成Mapper接口的代理代理类
由动态处理器MapperProxy中调用MapperMethod中的方法处理执行SQL
最后,在MapperMethod中根据执行的方法返回值决定调用SqlSession中的对应方法执行SQL
</div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
如何进行Java Mybatis中的Mapper原理分析的详细内容,希望对您有所帮助,信息来源于网络。