Mybatis基础(2)——自定义Mybatis

本文详细介绍了如何自定义Mybatis,包括从类加载器读取配置文件、封装配置信息、解析XML或注解、创建SqlSessionFactory建造者、定义SqlSession接口及其实现,以及测试各种实现方式,如仅接口、接口+实现类和注解方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.自定义mybatis的预先分析

2.代码实现

2.1 使用类加载器读取配置文件返回流

2.2 封装从主配置文件中读取的信息的配置类

2.3 封装从Mapper配置文件中读取出来的信息的类

2.4 解析配置文件或注解的类

2.4 定义建造SqlSessionFactory的建造者类

2.5 定义SqlSession工厂接口和实现类

2.6 定义SqlSession接口和实现类

2.7 封装了获取连接的类

2.8 代理类

2.9 自定义Select注解类

2.10 测试

(1)使用读取配置文件的方式并且只定义接口,不使用接口的实现类

(2)使用读取配置文件的方式并且只定义接口,使用接口的实现类

(3)使用注解的方式

3.上述代码流程再分析并总结


1.自定义mybatis的预先分析

通过上一篇中最后实现类的编写我们可以发现:mybatis在使用代理mapper的方式实现增删改查时做的事:

  • 1.创建代理对象
  • 2.在代理对象中调用selectList方法

查询所有分析图:

创建代理对象的分析图:

2.代码实现

自定义的mybatis的结构:

由于下面要用到dom4j和jaxen,pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.edu.cqu</groupId>
    <artifactId>MybatisDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <!--    mybatis的驱动jar包的坐标    -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <!--    单元测试的jar包的坐标    -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

        <dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.1.6</version>
        </dependency>
    </dependencies>

</project>

2.1 使用类加载器读取配置文件返回流

package cn.cqu.mybatis.io;

import java.io.InputStream;

/**
 * 使用类加载器读取配置文件的类
 */
public class Resources {


    public static InputStream getResourceAsStream(String filePath){
        /**
         * 1.拿到当前类的字节码
         * 2.获取字节码的类加载器
         * 3.根据类加载器来读取配置
         */
        return Resources.class.getClassLoader().getResourceAsStream(filePath);
    }
}

2.2 封装从主配置文件中读取的信息的配置类

package cn.cqu.mybatis.cfg;

import java.util.HashMap;
import java.util.Map;

/**
 * 自定义mybatis的配置类
 */
public class Configuration {
    //连接数据库的信息
    private String driver;
    private String url;
    private String username;
    private String password;

    /**
     * 从mapper配置文件中读到的信息被封装之后的键值对,
     *
     * key:Mapper标签中namespace对应的全限定类名(映射的类)+点+select标签的id(映射的方法)
     * value:封装sql语句和映射的实体类全限定类名的Mapper对象
     */

    private Map<String,Mapper> mappers = new HashMap<>();

    public Map<String, Mapper> getMappers() {
        return mappers;
    }

    public void setMappers(Map<String, Mapper> mappers) {
        this.mappers.putAll(mappers);  //此处需要使用追加的方式
    }

    public String getDriver() {
        return driver;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

2.3 封装从Mapper配置文件中读取出来的信息的类

package cn.cqu.mybatis.cfg;

/**
 * 用于封装执行的sql语句和结果类型的全限定类名
 */
public class Mapper {
    //Sql语句
    private String queryString;
    //映射的实体类全限定类名
    private String resultType; 

    public String getQueryString() {
        return queryString;
    }

    public void setQueryString(String queryString) {
        this.queryString = queryString;
    }

    public String getResultType() {
        return resultType;
    }

    public void setResultType(String resultType) {
        this.resultType = resultType;
    }
}

2.4 解析配置文件或注解的类

package cn.cqu.mybatis.utiils;

import cn.cqu.mybatis.annotations.Select;
import cn.cqu.mybatis.cfg.Configuration;
import cn.cqu.mybatis.cfg.Mapper;
import cn.cqu.mybatis.io.Resources;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  用于解析配置文件,并把解析后的信息封装为Configuration对象
 */
public class XMLConfigBuilder {



    /**
     * 解析主配置文件,把里面的内容填充到DefaultSqlSession所需要的地方
     * 使用的技术:
     *      dom4j+xpath
     */
    public static Configuration loadConfiguration(InputStream config){
        try{
            //定义封装连接信息的配置对象(mybatis的配置对象)
            Configuration cfg = new Configuration();

            //1.获取SAXReader对象
            SAXReader reader = new SAXReader();
            //2.根据字节输入流获取Document对象
            Document document = reader.read(config);
            //3.获取根节点
            Element root = document.getRootElement();
            //4.使用xpath中选择指定节点的方式,获取所有property节点
            List<Element> propertyElements = root.selectNodes("//property");
            //5.遍历节点
            for(Element propertyElement : propertyElements){
                //判断节点是连接数据库的哪部分信息
                //取出name属性的值
                String name = propertyElement.attributeValue("name");
                if("driver".equals(name)){
                    //表示驱动
                    //获取property标签value属性的值
                    String driver = propertyElement.attributeValue("value");
                    cfg.setDriver(driver);
                }
                if("url".equals(name)){
                    //表示连接字符串
                    //获取property标签value属性的值
                    String url = propertyElement.attributeValue("
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值