欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > 手写mybatis之Mapper XML的解析和注册使用

手写mybatis之Mapper XML的解析和注册使用

2024/10/25 21:22:16 来源:https://blog.csdn.net/CSDN_LiMingfly/article/details/142704915  浏览:    关键词:手写mybatis之Mapper XML的解析和注册使用

前言


你是怎么面对功能迭代的?
很多程序员在刚开始做编程或者新加入一家公司时,都没有多少机会可以做一个新项目,大部分时候都是在老项目上不断的迭代更新。在这个过程你可能要学习N个前人留下的各式各样的风格迥异的代码片段,在这些纵横交错的流程中,找到一席之地,把自己的ifelse加进去。
但说回来,其实不能逐步清理一片屎山,让代码在你的手上逐步清晰、整洁、干净,很多时候也是作为码农自身经验的不足,不懂得系统重构、不了解设计原则、不熟悉业务背景、不清楚产品走向等等原因造成的。所以最好的办法是提升自身的能力,每接到一次需求都有一些技术上的改变,既然它是屎山,那就当做打怪升级了,修一点、改一块、补一片,总会在你手上越来越易于维护和扩展的。
设计
上一章节我们使用了 MapperRegistry 对包路径进行扫描注册映射器,并在 DefaultSqlSession 中进行使用。那么在我们可以把这些命名空间、SQL描述、映射信息统一维护到每一个 DAO 对应的 Mapper XML 的文件以后,其实 XML 就是我们的源头了。通过对 XML 文件的解析和处理就可以完成 Mapper 映射器的注册和 SQL 管理。
在这里插入图片描述

XML 解析和注册类实现关系
在这里插入图片描述
1:SqlSessionFactoryBuilder 作为整个 Mybatis 的入口,提供建造者工厂,包装 XML 解析处理,并返回对应 SqlSessionFactory 处理类。
2:通过解析把 XML 信息注册到 Configuration 配置类中,再通过传递 Configuration 配置类到各个逻辑处理类里,包括 DefaultSqlSession 中,这样就可以在获取映射器和执行SQL的时候,从配置类中拿到对应的内容了。
构建SqlSessionFactory建造者工厂

package com.lm.mybatis.session;public class SqlSessionFactoryBuilder {public SqlSessionFactory build(Reader reader) {XMLConfigBuilder xmlConfigBuilder = new XMLConfigBuilder(reader);return build(xmlConfigBuilder.parse());}public SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);}}
package com.lm.mybatis.builder.xml;import com.lm.mybatis.builder.BaseBuilder;
import org.dom4j.Element;public class XMLConfigBuilder extends BaseBuilder {private Element root;public XMLConfigBuilder(Reader reader) {// 1. 调用父类初始化Configurationsuper(new Configuration());// 2. dom4j 处理 xmlSAXReader saxReader = new SAXReader();try {Document document = saxReader.read(new InputSource(reader));root = document.getRootElement();} catch (DocumentException e) {e.printStackTrace();}}/*** 解析配置;类型别名、插件、对象工厂、对象包装工厂、设置、环境、类型转换、映射器** @return Configuration*/public Configuration parse() {try {// 解析映射器mapperElement(root.element("mappers"));} catch (Exception e) {throw new RuntimeException("Error parsing SQL Mapper Configuration. Cause: " + e, e);}return configuration;}private void mapperElement(Element mappers) throws Exception {List<Element> mapperList = mappers.elements("mapper");for (Element e : mapperList) {String resource = e.attributeValue("resource");Reader reader = Resources.getResourceAsReader(resource);SAXReader saxReader = new SAXReader();Document document = saxReader.read(new InputSource(reader));Element root = document.getRootElement();//命名空间String namespace = root.attributeValue("namespace");// SELECTList<Element> selectNodes = root.elements("select");for (Element node : selectNodes) {String id = node.attributeValue("id");String parameterType = node.attributeValue("parameterType");String resultType = node.attributeValue("resultType");String sql = node.getText();// ? 匹配Map<Integer, String> parameter = new HashMap<>();Pattern pattern = Pattern.compile("(#\\{(.*?)})");Matcher matcher = pattern.matcher(sql);for (int i = 1; matcher.find(); i++) {String g1 = matcher.group(1);String g2 = matcher.group(2);parameter.put(i, g2);sql = sql.replace(g1, "?");}String msId = namespace + "." + id;String nodeName = node.getName();SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));MappedStatement mappedStatement = new MappedStatement.Builder(configuration, msId, sqlCommandType, parameterType, resultType, sql, parameter).build();// 添加解析 SQLconfiguration.addMappedStatement(mappedStatement);}// 注册Mapper映射器configuration.addMapper(Resources.classForName(namespace));}}}
package com.lm.mybatis.io;import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;public class Resources {public static Reader getResourceAsReader(String resource) throws IOException {return new InputStreamReader(getResourceAsStream(resource));}private static InputStream getResourceAsStream(String resource) throws IOException {ClassLoader[] classLoaders = getClassLoaders();for (ClassLoader classLoader : classLoaders) {InputStream inputStream = classLoader.getResourceAsStream(resource);if (null != inputStream) {return inputStream;}}throw new IOException("Could not find resource " + resource);}private static ClassLoader[] getClassLoaders() {return new ClassLoader[]{ClassLoader.getSystemClassLoader(),Thread.currentThread().getContextClassLoader()};}public static Class<?> classForName(String className) throws ClassNotFoundException {return Class.forName(className);}}
package com.lm.mybatis.mapping;import com.lm.mybatis.session.Configuration;import java.util.Map;public class MappedStatement {private Configuration configuration;private String id;private SqlCommandType sqlCommandType;private String parameterType;private String resultType;private String sql;private Map<Integer, String> parameter;MappedStatement() {// constructor disabled}/*** 建造者*/public static class Builder {private MappedStatement mappedStatement = new MappedStatement();public Builder(Configuration configuration, String id, SqlCommandType sqlCommandType, String parameterType, String resultType, String sql, Map<Integer, String> parameter) {mappedStatement.configuration = configuration;mappedStatement.id = id;mappedStatement.sqlCommandType = sqlCommandType;mappedStatement.parameterType = parameterType;mappedStatement.resultType = resultType;mappedStatement.sql = sql;mappedStatement.parameter = parameter;}public MappedStatement build() {assert mappedStatement.configuration != null;assert mappedStatement.id != null;return mappedStatement;}}public Configuration getConfiguration() {return configuration;}public void setConfiguration(Configuration configuration) {this.configuration = configuration;}public String getId() {return id;}public void setId(String id) {this.id = id;}public SqlCommandType getSqlCommandType() {return sqlCommandType;}public void setSqlCommandType(SqlCommandType sqlCommandType) {this.sqlCommandType = sqlCommandType;}public String getParameterType() {return parameterType;}public void setParameterType(String parameterType) {this.parameterType = parameterType;}public String getResultType() {return resultType;}public void setResultType(String resultType) {this.resultType = resultType;}public String getSql() {return sql;}public void setSql(String sql) {this.sql = sql;}public Map<Integer, String> getParameter() {return parameter;}public void setParameter(Map<Integer, String> parameter) {this.parameter = parameter;}}
package com.lm.mybatis.mapping;public enum SqlCommandType {/*** 未知*/UNKNOWN,/*** 插入*/INSERT,/*** 更新*/UPDATE,/*** 删除*/DELETE,/*** 查找*/SELECT;}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lm.test.dao.IUserDao"><select id="queryUserInfoById" parameterType="java.lang.Long" resultType="com.lm.test.pojo.User">SELECT id, userId, userHead, createTimeFROM userwhere id = #{id}</select></mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><mappers><mapper resource="mapper/User_Mapper.xml"/></mappers></configuration>
package com.lm.test;import com.lm.mybatis.binding.MapperProxyFactory;
import com.lm.mybatis.binding.MapperRegistry;
import com.lm.mybatis.io.Resources;
import com.lm.mybatis.session.SqlSession;
import com.lm.mybatis.session.SqlSessionFactory;
import com.lm.mybatis.session.SqlSessionFactoryBuilder;
import com.lm.mybatis.session.defaults.DefaultSqlSessionFactory;
import com.lm.test.dao.IUserDao;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;public class TestApi {private Logger logger = LoggerFactory.getLogger(TestApi.class);@Testpublic void test_SqlSessionFactory() throws IOException {// 1. 从SqlSessionFactory中获取SqlSessionReader reader = Resources.getResourceAsReader("mybatis-config-datasource.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);SqlSession sqlSession = sqlSessionFactory.openSession();// 2. 获取映射器对象IUserDao userDao = sqlSession.getMapper(IUserDao.class);// 3. 测试验证String res = userDao.queryUserInfoById("10001");logger.info("测试结果:{}", res);}}
package com.lm.test.pojo;import java.util.Date;public class User {private Long id;private String userId;          // 用户IDprivate String userHead;        // 头像private Date createTime;        // 创建时间private Date updateTime;        // 更新时间public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUserId() {return userId;}public void setUserId(String userId) {this.userId = userId;}public String getUserHead() {return userHead;}public void setUserHead(String userHead) {this.userHead = userHead;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}public Date getUpdateTime() {return updateTime;}public void setUpdateTime(Date updateTime) {this.updateTime = updateTime;}}

在这里插入图片描述

好了到这里就结束了手写mybatis之Mapper XML的解析和注册使用的学习,大家一定要跟着动手操作起来。需要的源码的 可si我获取;

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com