自定义持久层框架的代码实现一

项目结构

  • 描述一下自定义持久层框架的项目结构?

    • .
      ├── IPersistence
      │   ├── IPersistence.iml
      │   ├── pom.xml
      │   └── src
      └── IPersistence_test
          ├── IPersistence_test.iml
          ├── pom.xml
          ├── src
          └── target
      

具体代码

sqlMapperConfig.xml 配置文件

<configuration>
    <!-- 存放数据库配置信息 -->
    <dataSource>
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/zdy_mybatis"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </dataSource>

    <!-- 存放mapper.xml全路径 -->
    <mapper resource="UserMapper.xml" />
</configuration>

UserMapper.xml 配置文件

<mapper namespace="user">
    <!-- sql的唯一标识:namespace.id组合:statementId -->
    <select id="selectList" resultType="com.terwergreen.pojo.User">
        select * from user
    </select>
    <select id="selectOne" resultType="com.terwergreen.pojo.User" parameterType="com.terwergreen.pojo.User">
        select * from user where id = #{id} and username = #{username}
    </select>
</mapper>

读取资源处理,Resources 类

/**
 * 资源处理类
 *
 * @name: Resource
 * @author: terwer
 * @date: 2022-03-14 12:57
 **/
public class Resources {
    /**
     * 根据配置文件的路径,将配置文件加载成字节输入流,存储到内存中
     *
     * @param path
     * @return
     */
    public static InputStream getResourceAsStream(String path) {
        InputStream inputStream = Resources.class.getClassLoader().getResourceAsStream(path);
        return inputStream;
    }
}

SqlSessionFactoryBuider 工厂构建对象

/**
 * 工厂构建对象
 *
 * @name: SqlSessionFactoryBuilder
 * @author: terwer
 * @date: 2022-03-14 15:18
 **/
public class SqlSessionFactoryBuilder {
    public SqlSessionFactory build(InputStream in) throws DocumentException, PropertyVetoException {
        // 1、解析配置文件,将解析出来的内容封装到Configuration中
        XmlConfigBuilder xmlConfigBuilder = new XmlConfigBuilder();
        Configuration configuration = xmlConfigBuilder.parse(in);

        // 2、创建SqlSessionFactory对象
        DefaultSqlSessionFactory sqlSessionFactory = new DefaultSqlSessionFactory(configuration);
        return sqlSessionFactory;
    }
}

配置文件解析

/**
 * @name: XmlConfigBuilder
 * @author: terwer
 * @date: 2022-03-14 15:40
 **/
public class XmlConfigBuilder {

    private Configuration configuration;

    public XmlConfigBuilder() {
        configuration = new Configuration();
    }

    /**
     * 使用dom4j将配置文件进行解析,封装Configuration
     *
     * @param in
     * @return
     */
    public Configuration parse(InputStream in) throws DocumentException, PropertyVetoException {
        Document document = new SAXReader().read(in);
        // <confiruration>
        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解析,拿到路径,加载成字节输入流,进行解析
        List<Element> mapperList= rootElement.selectNodes("//mapper");
        // <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;
    }
}

mapper 映射文件解析

/**
 * mapper解析器
 *
 * @name: XmlMapperBuilder
 * @author: terwer
 * @date: 2022-03-14 16:16
 **/
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);

        // <mapper>
        Element rootElement = document.getRootElement();
        String namespace = rootElement.attributeValue("namespace");

        List<Element> list = rootElement.selectNodes("//select");
        for (Element element : list) {
            String id = element.attributeValue("id");
            String resultType = element.attributeValue("resultType");
            String parameterType = element.attributeValue("parameterType");

            String sqlText = element.getTextTrim();

            MappedStatement mappedStatement = new MappedStatement();
            mappedStatement.setStatementId(id);
            mappedStatement.setResultType(resultType);
            mappedStatement.setParameterType(parameterType);
            mappedStatement.setSql(sqlText);

            Map<String, MappedStatement> mappedStatementMap = configuration.getMappedStatementMap();
            String statementId = namespace + "." + id;
            mappedStatementMap.put(statementId, mappedStatement);
        }
    }
}

SqlSession 的具体实现

/**
 * @name: SqlSession
 * @author: terwer
 * @date: 2022-03-14 16:35
 **/
public interface SqlSession {
    /**
     * 查询所有
     */
    public <E> List<E> selectList(String statementId, Object... params) throws Exception;

    /**
     * 查询单个
     */
    public <T> T selectOne(String statementId, Object... params) throws Exception;

    public <T> T getMapper(Class<?> mapperClass);
}

文章更新历史

2024/04/13 同步文章到其他平台

2022/05/08 feat: 优化代码

posted @ 2022-08-29 22:10  灯塔下的守望者  阅读(37)  评论(0编辑  收藏  举报