欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Mybatis映射器接口代理对象的方式 运行过程

程序员文章站 2022-07-02 13:02:14
查询一张表的所有数据。 环境: 使用工具IntelliJ IDEA 2018.2版本。 创建Maven工程不用骨架 1.pom.xml 2.表-类 3.映射器 4.映射器配置文件 5.数据库核心配置文件 6.测试类 7.项目结构 8..在测试类打断点,开始deBug跟踪,从这里开始。首先得到User ......

查询一张表的所有数据。

环境:

使用工具intellij idea 2018.2版本。

创建maven工程不用骨架

1.pom.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <project xmlns="http://maven.apache.org/pom/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
 4          xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelversion>4.0.0</modelversion>
 6 
 7     <groupid>com.jxjdemo</groupid>
 8     <artifactid>day33_mybatis1_quicksta</artifactid>
 9     <version>1.0-snapshot</version>
10 
11     <properties>
12     <project.build.sourceencoding>utf-8</project.build.sourceencoding>
13     <maven.compiler.source>1.8</maven.compiler.source>
14     <maven.compiler.target>1.8</maven.compiler.target>
15 </properties>
16 
17 <dependencies>
18         <!--mysql数据库-->
19         <dependency><!-- 依赖  -->
20             <groupid>mysql</groupid><!--公司名/组织名groupid:域名倒写 -->
21             <artifactid>mysql-connector-java</artifactid><!--项目包/包名 -->
22             <version>5.1.47</version><!--版本号version:1.0-snapshot 开发版   1.0-release稳定发行版 -->
23         </dependency>
24             <!--mybatis的jar包-->
25         <dependency>
26             <groupid>org.mybatis</groupid>
27             <artifactid>mybatis</artifactid>
28             <version>3.5.2</version>
29         </dependency>
30             <!--日志包-->
31         <dependency>
32             <groupid>log4j</groupid>
33             <artifactid>log4j</artifactid>
34             <version>1.2.17</version>
35         </dependency>
36             <!--单元测试-->
37         <dependency>
38             <groupid>junit</groupid>
39             <artifactid>junit</artifactid>
40             <version>4.12</version>
41             <scope>test</scope>  <!--加test单元测试只能写在test内-->
42         </dependency>
43     </dependencies>
44 
45 </project>

2.表-类

 1 package com.jxjdemo.domain;
 2 
 3 import java.util.date;
 4 
 5 public class user {
 6     private integer id;
 7     private string username;
 8     private date birthday;   //导包,框架自动帮我们转可以这样写。
 9     private string sex;
10     private string address;
11 
12     @override
13     public string tostring() {
14         return "user{" +
15                 "id=" + id +
16                 ", username='" + username + '\'' +
17                 ", birthday=" + birthday +
18                 ", sex='" + sex + '\'' +
19                 ", address='" + address + '\'' +
20                 '}';
21     }
22 //省略get与set方法

3.映射器

1 package com.jxjdemo.dao;
2 import com.jxjdemo.domain.user;
3 import java.util.list;
4 /**
5  * 映射器:dao层的接口
6  */
7 public interface userdao {
8       list<user> queryall();
9 }

4.映射器配置文件

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!doctype mapper
 3         public "-//mybatis.org//dtd mapper 3.0//en"
 4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <!--
 6    上面为引入的约束
 7  _____________________________________________________________
 8 下面的mapper:映射器配置
 9     namespace:映射器的全限定类名
10 -->
11 <mapper namespace="com.jxjdemo.dao.userdao">
12     <!--
13        statement:映射器里面每个方法的配置信息,叫做statement
14        select标签:用于查询
15        insert标签:用于插入
16        update标签:用于修改
17        delete标签:用于删除
18 
19         以上四个标签都有的属性:
20         id:映射器里面写 方法的名称
21         resulttype 结果集封装的类型
22     -->
23     <select id="queryall" resulttype="com.jxjdemo.domain.user">
24           select * from user
25     </select>
26 </mapper>

5.数据库核心配置文件

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!doctype configuration
 3         public "-//mybatis.org//dtd config 3.0//en"
 4         "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <!--mybatis的核心配置文件,主要配置数据库连接信息-->
 6 <configuration><!--根标签-->
 7     <!--enxironments 可以配置多个数据库环境-->
 8     <environments default="mysql"><!--default 默认使用的数据库-->
 9         <environment id="mysql"><!--environment每一个数据库连接(配置)信息-->
10             <transactionmanager type="jdbc"/><!--事物管理方式-->
11             <datasource type="pooled"><!--数据源。不使用un连接池pooled,pooled使用连接池,jndi查找数据源配置文件-->
12                 <property name="driver" value="com.mysql.jdbc.driver"/>
13                 <property name="url" value="jdbc:mysql://localhost:端口号/库名"/>
14                 <property name="username" value="账号"/>
15                 <property name="password" value="密码"/>
16             </datasource>
17         </environment>
18     </environments>
19     <mappers><!--映射器-->
20         <mapper resource="com/jxjdemo/dao/userdao.xml" />
21     </mappers>
22 </configuration>

6.测试类

 1 package com.jxjtest.test;
 2 
 3 import com.jxjdemo.dao.userdao;
 4 import com.jxjdemo.domain.user;
 5 
 6 import org.apache.ibatis.io.resources;
 7 import org.apache.ibatis.session.sqlsession;
 8 import org.apache.ibatis.session.sqlsessionfactory;
 9 import org.apache.ibatis.session.sqlsessionfactorybuilder;
10 import org.junit.test;
11 
12 import java.io.ioexception;
13 import java.io.inputstream;
14 import java.util.list;
15 
16 public class quickstarttest { //quickstart快速开始
17     @test
18     public void testquickstart() throws ioexception {
19         //1.读取配置文件
20         inputstream is = resources.getresourceasstream("sqlmapconfig.xml"); //抛出异常
21 
22         //2.读取到sqlsession对象.要从sqlsessionfactory里面生产sqlsession对象
23         sqlsessionfactory facyory = new sqlsessionfactorybuilder().build(is);
24         //new一个工厂,给他传流,返回一个工厂对象
25         sqlsession session = facyory.opensession();//有了工厂对象,就用opensession得到session
26 
27         //3.操作数据库
28         userdao userdao = session.getmapper(userdao.class);//使用getmapper返回userdao对象,动态代理有接口就行。创建代理对象
29         list<user> userlist = userdao.queryall();
30         for (user user : userlist) {
31             system.out.println(user);
32         }
33         //4.释放资源
34         session.close();
35         is.close();
36     }
37 }

7.项目结构

Mybatis映射器接口代理对象的方式 运行过程

8..在测试类打断点,开始debug跟踪,从这里开始。首先得到userdao,dao对象是一个代理对象。

1  userdao userdao = session.getmapper(userdao.class);//使用getmapper返回userdao对象
2 list<user> userlist = userdao.queryall();

9.到mapperproxy.java里的invole方法

 1  @override
 2   public object invoke(object proxy, method method, object[] args) throws throwable {
 3     try {
 4       if (object.class.equals(method.getdeclaringclass())) {//1.
 5         return method.invoke(this, args);
 6       } else if (method.isdefault()) {//2.
 7         return invokedefaultmethod(proxy, method, args);
 8       }
 9     } catch (throwable t) {
10       throw exceptionutil.unwrapthrowable(t);
11     }
12     final mappermethod mappermethod = cachedmappermethod(method);//3.
13     return mappermethod.execute(sqlsession, args);//4.开始执行映射器的方法进入方法
14   }

10.到了mappermethod.java中

 1 public object execute(sqlsession sqlsession, object[] args) {
 2     object result;
 3     switch (command.gettype()) {//1.判断登陆类型
 4       case insert: {
 5         object param = method.convertargstosqlcommandparam(args);
 6         result = rowcountresult(sqlsession.insert(command.getname(), param));
 7         break;
 8       }
 9       case update: {
10         object param = method.convertargstosqlcommandparam(args);
11         result = rowcountresult(sqlsession.update(command.getname(), param));
12         break;
13       }
14       case delete: {
15         object param = method.convertargstosqlcommandparam(args);
16         result = rowcountresult(sqlsession.delete(command.getname(), param));
17         break;
18       }
19       case select:
20         if (method.returnsvoid() && method.hasresulthandler()) {
21           executewithresulthandler(sqlsession, args);//2.执行查询,就是select
22           result = null;
23         } else if (method.returnsmany()) {//3.根据方法返回值判断,returnsmany()返回多个
24           result = executeformany(sqlsession, args);//4.调了executeformany进入
25         } else if (method.returnsmap()) {
26           result = executeformap(sqlsession, args);
27         } else if (method.returnscursor()) {
28           result = executeforcursor(sqlsession, args);
29         } else {
30           object param = method.convertargstosqlcommandparam(args);
31           result = sqlsession.selectone(command.getname(), param);
32           if (method.returnsoptional()
33               && (result == null || !method.getreturntype().equals(result.getclass()))) {
34             result = optional.ofnullable(result);
35           }
36         }
37         break;

11.到了executeformany

1 private <e> object executeformany(sqlsession sqlsession, object[] args) {
2     list<e> result;
3     object param = method.convertargstosqlcommandparam(args);//1.准备方法的参数
4     if (method.hasrowbounds()) {//2.因为查询全部,没有参数,所以参数是null
5       rowbounds rowbounds = method.extractrowbounds(args);
6       result = sqlsession.selectlist(command.getname(), param, rowbounds);
7     } else {
8       result = sqlsession.selectlist(command.getname(), param);//到了这里setlectlist与
9     }

12.剩余请看步骤截图。与https://www.cnblogs.com/jxearlier/p/11625253.html从11步开始。

13.完整流程如下。

Mybatis映射器接口代理对象的方式 运行过程