《Java手写系列》-手写MyBatis框架
Posted IT老刘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Java手写系列》-手写MyBatis框架相关的知识,希望对你有一定的参考价值。
文章目录
下面接着第一章内容,手写MyBatis框架!
1.自定义Resources类
Resources类的作用是获取一个类加载器,根据配置文件的路径,将配置文件加载成字节输入流,存储在内存中。
package org.apache.ibatis.io;
import java.io.InputStream;
public class Resources {
/**
* 根据配置文件的路径,将配置文件加载成字节输入流,存储在内存中。
* @param path 文件路径
* @return 字节流
*/
public static InputStream getResourceAsStream(String path){
InputStream resourceAsStream = Resources.class.getClassLoader().getResourceAsStream(path);
return resourceAsStream;
}
}
2.自定义MappedStatement类
MappedStatement类作用是封装UserMapper.xml文件解析之后的SQL语句信息,在底层框架可以使用Dom4J进行解析!
package org.apache.ibatis.configration;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MappedStatement {
// id标识
private String id;
// 返回值类型
private String resultType;
// 参数值类型
private String parameterType;
// sql语句
private String sql;
}
3.自定义Configuration类
Configuration类是MyBatis框架的SQL配置封装类,后期使用Dom4J进行解析
package org.apache.ibatis.configration;
import com.google.common.collect.Maps;
import javax.sql.DataSource;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Configuration {
/**
* 数据源对象
*/
private DataSource dataSource;
/**
* key:statementId
* value:封装好的MappedStatement
*/
Map<String,MappedStatement> mappedStatementMap= Maps.newHashMap();
}
4.解析配置文件
4.1.解析mapper.xml
自定义类XMLMapperBuilder
package org.apache.ibatis.parser;
import com.google.common.collect.Lists;
import org.apache.ibatis.configration.Configuration;
import org.apache.ibatis.configration.MappedStatement;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.util.List;
/**
* mapper.xml文件解析类
*/
public class XMLMapperBuilder {
private Configuration configuration;
public XMLMapperBuilder(Configuration configuration) {
this.configuration = configuration;
}
public void parse(InputStream in) throws DocumentException {
Document document = new SAXReader().read(in);
Element rootElement = document.getRootElement();
String namespace = rootElement.attributeValue("namespace");
List<Element> selectList = rootElement.selectNodes("//select");
List<Element> insertList = rootElement.selectNodes("//insert");
List<Element> updateList = rootElement.selectNodes("//update");
List<Element> deleteList = rootElement.selectNodes("//delete");
List<Element> allList = Lists.newArrayList();
allList.addAll(selectList);
allList.addAll(insertList);
allList.addAll(updateList);
allList.addAll(deleteList);
for (Element element : allList) {
String id = element.attributeValue("id");
String resultType = element.attributeValue("resultType");
String parameterType = element.attributeValue("parameterType");
String sqlText = element.getTextTrim();
MappedStatement mappedStatement = new MappedStatement();
mappedStatement.setId(id);
mappedStatement.setResultType(resultType);
mappedStatement.setParameterType(parameterType);
mappedStatement.setSql(sqlText);
String key = namespace + "." + id;
configuration.getMappedStatementMap().put(key, mappedStatement);
}
}
}
测试mapper.xml解析
package com.bruce.test;
import org.apache.ibatis.configration.Configuration;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.parser.XMLMapperBuilder;
import org.dom4j.DocumentException;
import org.junit.Test;
import javax.annotation.Resource;
import java.io.InputStream;
public class TestMapperparser {
@Test
public void test1(){
try {
Configuration configuration=new Configuration();
InputStream resourceAsStream = Resources.getResourceAsStream("mappers/UserMapper.xml");
XMLMapperBuilder xmlMapperBuilder=new XMLMapperBuilder(configuration);
xmlMapperBuilder.parse(resourceAsStream);
System.out.println("mapper.xml解析完毕");
System.out.println(configuration);
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
4.2.解析mybatis-config.xml
自定义类XMLConfigBuilder
package org.apache.ibatis.parser;
import org.apache.ibatis.configration.Configuration;
/**
* 解析mybatis-config.xml
*/
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.ibatis.io.Resources;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.beans.PropertyVetoException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;
public class XMLConfigBuilder {
private Configuration configuration;
public XMLConfigBuilder() {
this.configuration = new Configuration();
}
/**
* 该方法就是使用dom4j对配置文件进行解析,封装成Configuration对象
* @param in 字节输入流
* @return Configuration
*/
public Configuration parseConfig(InputStream in) throws DocumentException, PropertyVetoException {
Document document = new SAXReader().read(in);
// <configuration>
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.setProperty(name, value);
}
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setDriverClass(properties.getProperty("driverClass"));
comboPooledDataSource.setJdbcUrl(properties.getProperty("jdbcUrl"));
comboPooledDataSource.setUser(properties.getProperty("username"));
comboPooledDataSource.setPassword(properties.getProperty("password"));
configuration.setDataSource(comboPooledDataSource);
// mapper.xml解析:拿到路径--字节输入流--dom4j进行解析
List<Element> mapperList = rootElement.selectNodes("//mapper");
for (Element element : mapperList) {
String mapperPath = element.attributeValue("resource");
InputStream resourceAsStream = Resources.getResourceAsStream(mapperPath);
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(configuration);
xmlMapperBuilder.parse(resourceAsStream);
}
return configuration;
}
}
测试mybatis-config.xml解析类:
package com.bruce.test;
import org.apache.ibatis.configration.Configuration;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.parser.XMLConfigBuilder;
import org.dom4j.DocumentException;
import org.junit.Test;
import java.beans.PropertyVetoException;
import java.io.InputStream;
public class TestConfigParser {
@Test
public void test1(){
try {
XMLConfigBuilder xmlConfigBuilder=new XMLConfigBuilder();
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
xmlConfigBuilder.parseConfig(resourceAsStream);
System.out.println("config.xml解析完毕");
System.out.println(xmlConfigBuilder);
}catch (Exception e) {
e.printStackTrace();
}
}
}
以上是关于《Java手写系列》-手写MyBatis框架的主要内容,如果未能解决你的问题,请参考以下文章