当前位置: 首页 > news >正文

04-08手写持久层框架——核心配置和映射配置文件解析

学习资料视频来源:https://www.bilibili.com/video/BV1R14y1W7yS

文章目录

  • 1. 项目介绍
    • 1.1 项目结构
    • 1.2 项目依赖
      • (1) ipersistent依赖
      • (2) ipersistent-test依赖
    • 1.3 配置文件
      • (1) 核心配置文件
      • (2) 映射配置文件
  • 2. 核心源码类
    • 2.1 ipersistent
      • Resources
      • Configuration
      • MappedStatement
      • XMLConfigBuilder
      • XMLMapperBuilder
      • SqlSessionFactoryBuilder
      • SqlSessionFactory
      • DefaultSqlSessionFactory
    • 2.2 ipersistent-test
      • 测试类

1. 项目介绍

1.1 项目结构

项目分为2个模块,ipersistent 和ipersistent-test。ipersistent为框架,ipersistent-test为框架使用端,ipersistent-test依赖ipersistent。视频里是使用maven管理项目,我这里是使用gradle管理项目。目录结构如下:
在这里插入图片描述

1.2 项目依赖

(1) ipersistent依赖

plugins {
    id 'java-library'
}

group = 'com.mql'

repositories {
    maven {
        url 'https://maven.aliyun.com/nexus/content/groups/public/'
    }
    mavenCentral()
}

dependencies {
    testImplementation platform('org.junit:junit-bom:5.10.0')
    testImplementation 'org.junit.jupiter:junit-jupiter'
    // 引入dom4j依赖,用于解析xml文件
    api 'dom4j:dom4j:1.6.1'
    runtimeOnly 'mysql:mysql-connector-java:5.1.40'
    //阿里德鲁伊数据库连接池
    implementation ('com.alibaba:druid:1.2.8') 
    implementation 'jaxen:jaxen:1.2.0' 
    annotationProcessor 'org.projectlombok:lombok:1.18.20'
    compileOnly 'org.projectlombok:lombok:1.18.20'
}

(2) ipersistent-test依赖

plugins {
    id 'java'
}

group = 'com.mql'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation platform('org.junit:junit-bom:5.10.0')
    testImplementation 'org.junit.jupiter:junit-jupiter'
    // 引用ipersistent
        implementation project(':ipersistent')
    implementation 'org.apache.logging.log4j:log4j-core:2.14.1'
    implementation 'org.apache.logging.log4j:log4j-api:2.14.1'
}

test {
    useJUnitPlatform()
}

1.3 配置文件

核心配置文件映射配置文件,都是在ipersistent-test提供。

(1) 核心配置文件

<configuration>
    <!-- 数据源配置 -->
    <datasource>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </datasource>
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

(2) 映射配置文件

<mapper namespace="user">

    <!--    唯一标识: namespace.id-->
    <!-- 查询所有用户 -->
    <select id="selectList" resultType="com.mqlyes.pojo.User">
        select * from user
    </select>

    <!-- 按条件查询用户 -->
    <!--    -->
    <select id="selectOne" resultType="com.mqlyes.pojo.User" parameterType="com.mqlyes.pojo.User">
        select * from user where id = #{id} and username = #{username}
    </select>
</mapper>

2. 核心源码类

2.1 ipersistent

Resources

作用:根据路径,加载配置文件,并转换成字节流,比较简单。

public class Resources {

    /**
     * 根据配置文件的路径加载配置文件存到内存中
     * @param path
     * @return
     */
    public static InputStream getResource(String path) {
        return Resources.class.getClassLoader().getResourceAsStream(path);
    }
}

Configuration

作用:Configuration存储核心配置和映射配置文件解析出的配置信息。分别对应dataSource和mappedStatementMap。


/**
 * 存数据库配置信息 从sqlMapper.xml中解析出的东西
 */
public class Configuration {
    // 数据源对象
    private DataSource dataSource;
    // key为 statementID
    private Map<String, MappedStatement> mappedStatementMap = new HashMap<>();

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public Map<String, MappedStatement> getMappedStatementMap() {
        return mappedStatementMap;
    }

    public void setMappedStatementMap(Map<String, MappedStatement> mappedStatementMap) {
        this.mappedStatementMap = mappedStatementMap;
    }
}

MappedStatement

作用:存储映射配置文件中解析出信息,一个MappedStatement对应一个xxxmapper.xml文件

public class MappedStatement {
    // 唯一标识
    private String StatementID;

    private String resultType;

    private String parameterType;

    private String sql;

    public String getStatementID() {
        return StatementID;
    }

    public void setStatementID(String statementID) {
        StatementID = statementID;
    }

    public String getResultType() {
        return resultType;
    }

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

    public String getParameterType() {
        return parameterType;
    }

    public void setParameterType(String parameterType) {
        this.parameterType = parameterType;
    }

    public String getSql() {
        return sql;
    }

    public void setSql(String sql) {
        this.sql = sql;
    }
}

XMLConfigBuilder

作用:先解析核心配置文件中数据库配置信息,封装成Datasource。再解析mapper文件所有路径
调用XMLMapperBuilder解析mapper文件,并封装进MappedStatement。解析二者的过程中,把Datasource和MappedStatement封装进Configuration。

public class XMLConfigBuilder {

    private Configuration configuration;

    public XMLConfigBuilder() {
        this.configuration = new Configuration();
    }

    /**
     * 解析配置文件 封装到Configuration中
     *
     * @param inputStream
     * @return
     */
    public Configuration parse(InputStream inputStream) throws DocumentException {
        Document document = new SAXReader().read(inputStream);
        Element rootElement = document.getRootElement();
        List<Element> list = rootElement.selectNodes("//property");
        Properties properties = new Properties();
        for (Element element : list) {
            String name = element.attributeValue("name");
            String value = element.attributeValue("value");
            properties.put(name, value);
        }
        // 创建数据源对象
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(properties.getProperty("driver"));
        druidDataSource.setUrl(properties.getProperty("url"));
        druidDataSource.setUsername(properties.getProperty("username"));
        druidDataSource.setPassword(properties.getProperty("password"));
        configuration.setDataSource(druidDataSource);
        // 获取映射配置文件路径
        List<Element> mapperList = rootElement.selectNodes("//mapper");
        for (Element element : mapperList) {
            String mapperPath = element.attributeValue("resource");
            InputStream resource = Resources.getResource(mapperPath);
            XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(configuration);
            xmlMapperBuilder.parse(resource);
        }
        return configuration;
    }
}

XMLMapperBuilder


public class XMLMapperBuilder {

    private Configuration configuration;

    public XMLMapperBuilder(Configuration configuration) {
        this.configuration = configuration;
    }

  public   void parse(InputStream inputStream) throws DocumentException {
        Document document = new SAXReader().read(inputStream);
        Element rootElement = document.getRootElement();
        String namespace = rootElement.attributeValue("namespace");
        List<Element> elements = rootElement.selectNodes("//select");
        for (Element element : elements) {
            String id = element.attributeValue("id");
            String resultType = element.attributeValue("resultType");
            String parameterType = element.attributeValue("parameterType");
            String sql = element.getTextTrim();
            MappedStatement mappedStatement = new MappedStatement();
            mappedStatement.setStatementID(namespace + "." + id);
            mappedStatement.setSql(sql);
            mappedStatement.setResultType(resultType);
            mappedStatement.setParameterType(parameterType);
            configuration.getMappedStatementMap().put(mappedStatement.getStatementID(), mappedStatement);
        }

    }
}

SqlSessionFactoryBuilder

public class SqlSessionFactoryBuilder {

    public SqlSessionFactory build(InputStream inputStream) throws DocumentException {
        XMLConfigBuilder xmlConfigBuilder = new XMLConfigBuilder();
        Configuration configuration = xmlConfigBuilder.parse(inputStream);
        // 创建SqlSessionFactory工厂对想
        DefaultSqlSessionFactory defaultSqlSessionFactory = new DefaultSqlSessionFactory(configuration);
        return defaultSqlSessionFactory;
    }

}

SqlSessionFactory

public interface SqlSessionFactory {
}

DefaultSqlSessionFactory


public class DefaultSqlSessionFactory implements SqlSessionFactory {
    private Configuration configuration;

    public DefaultSqlSessionFactory(Configuration configuration) {
        this.configuration = configuration;
    }
}

2.2 ipersistent-test

测试类

使用端目前只有一个测试类,看返回结果中的configuration对象信息是否完整。

public class IpersistentTest {

    @Test
    public void test1() throws Exception {
        InputStream resource = Resources.getResource("sqlMapConfig.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resource);
        System.out.println(build);
    }
}

http://www.dtcms.com/a/108639.html

相关文章:

  • 从零构建大语言模型全栈开发指南:第四部分:工程实践与部署-4.2.1视觉-语言模型(VLM)架构设计(CLIP与Flamingo模式)
  • HarmonyOS 基础组件和基础布局的介绍
  • Nyquist插件基础:LISP语法-条件语句
  • 数据量管理系统
  • 光学关键尺寸量测设备市场报告:2024年全球市场销售额达到了14.75亿美元
  • 鸿蒙NEXT开发土司工具类(ArkTs)
  • 前端中rem,vh,vw
  • 网约车APP评价系统从0到1
  • 红宝书第二十六讲:详解Web Workers:专用、共享、Service Worker
  • PyTorch中Linear全连接层
  • 视频设备轨迹回放平台EasyCVR如何搭建公共娱乐场所远程视频监控系统
  • 铁路语义分割数据下载RailSem19: A Dataset for Semantic Rail Scene Understanding
  • 使用Android 原生LocationManager获取经纬度
  • 教育软件 UI 设计:打造吸睛又实用的学习入口
  • SELinux
  • Leetcode-100 二分查找常见操作总结
  • 数据点燃创新引擎:数据驱动的产品开发如何重塑未来?
  • Airflow量化入门系列:第一章 Apache Airflow 基础
  • 红宝书第二十五讲:客户端存储(Cookie、localStorage、IndexedDB):浏览器里的“记忆盒子”
  • Leetcode 6233 -- DFS序列 | 两遍DFS
  • Vue中JSEncrypt 数据加密和解密处理
  • Firefox账号同步书签不一致(火狐浏览器书签同步不一致)
  • wireshak抓手机包 wifi手机抓包工具
  • linux 时钟
  • 【爬虫】网页抓包工具--Fiddler
  • 【Audio开发二】Android原生音量曲线调整说明
  • LInux基础指令(二)
  • 【VS+Qt】vs2022打开 vs2015项目
  • FastAPI中Pydantic异步分布式唯一性校验
  • 机器视觉调试——现场链接相机(解决各种相机链接问题)