远方的灯塔 - 专注于服务端技术分享 远方的灯塔 - 专注于服务端技术分享
首页
  • Java SE
  • Struts2
  • Hibernate
  • MyBatis
  • JAX-WS
  • 并发
  • 分布式
  • Git
  • 文章分类
  • 文章标签
  • 文章归档
  • 《C程序设计语言》
心情随笔
友情链接
给我留言 (opens new window)
关于我
GitHub (opens new window)

Terwer Green

一个后端老菜鸟
首页
  • Java SE
  • Struts2
  • Hibernate
  • MyBatis
  • JAX-WS
  • 并发
  • 分布式
  • Git
  • 文章分类
  • 文章标签
  • 文章归档
  • 《C程序设计语言》
心情随笔
友情链接
给我留言 (opens new window)
关于我
GitHub (opens new window)
  • JavaSE

  • 开源框架

    • MyBatis

      • JDBC的问题分析
      • 自定义持久层框架的设计思路
      • 自定义持久层框架的代码实现一
        • 项目结构
        • 具体代码
          • sqlMapperConfig.xml配置文件
          • UserMapper.xml配置文件
          • 读取资源处理,Resources类
          • SqlSessionFactoryBuider工厂构建对象
          • 配置文件解析
          • mapper映射文件解析
          • SqlSession的具体实现
      • 自定义持久层框架的代码实现二
      • 使用getMapper方式对自定义持久层框架进行优化
      • MyBatis的基本介绍及优势
      • MyBatis的基本使用
      • Mybatis基本流程及配置文件解析
      • MyBatis复杂映射开发之一对一查询
      • MyBatis复杂映射开发之一对多查询
      • MyBatis复杂映射开发之多对多查询
      • MyBatis常用注解及基本增删改查的注解实现
      • MyBatis的注解实现复杂映射开发
      • MyBatis缓存的概念
      • MyBatis的一级缓存
      • MyBatis的二级缓存
      • MyBatis的二级缓存整合redis
      • MyBatis-RedisCache源码分析
  • Linux

  • Struts2

  • Hibernate

  • Webservice

  • 分布式

  • 分布式框架

  • 后端开发
  • 开源框架
  • MyBatis
terwer
2022-05-08
目录

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

# 项目结构

.
├── IPersistence
│   ├── IPersistence.iml
│   ├── pom.xml
│   └── src
└── IPersistence_test
    ├── IPersistence_test.iml
    ├── pom.xml
    ├── src
    └── target
1
2
3
4
5
6
7
8
9
10

# 具体代码

# 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>
1
2
3
4
5
6
7
8
9
10
11
12

# 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>
1
2
3
4
5
6
7
8
9

# 读取资源处理,Resources类

    /**
     * 资源处理类
     *
     * @name: Resource
     * @author: terwer
     * @date: 2022-05-08 15:57
     */
    object Resources {
        /**
         * 根据配置文件的路径,将配置文件加载成字节输入流,存储到内存中
         *
         * @param path
         * @return
         */
        @JvmStatic
        fun getResourceAsStream(path: String?): InputStream {
            return Resources::class.java.classLoader.getResourceAsStream(path)
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /**
     * 资源处理类
     *
     * @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;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // Make sure to add code blocks to your code group

    # SqlSessionFactoryBuider工厂构建对象

      /**
       * 工厂构建对象
       *
       * @name: SqlSessionFactoryBuilder
       * @author: terwer
       * @date: 2022-05-08 15:18
       */
      class SqlSessionFactoryBuilder {
          @Throws(DocumentException::class, PropertyVetoException::class)
          fun build(ips: InputStream?): SqlSessionFactory {
              // 1、解析配置文件,将解析出来的内容封装到Configuration中
              val xmlConfigBuilder = XmlConfigBuilder()
              val configuration = xmlConfigBuilder.parse(ips)
      
              // 2、创建SqlSessionFactory对象
              return DefaultSqlSessionFactory(configuration)
          }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      /**
       * 工厂构建对象
       *
       * @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;
          }
      
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      // Make sure to add code blocks to your code group

      # 配置文件解析

        /**
         * @name: XmlConfigBuilder
         * @author: terwer
         * @date: 2022-03-14 15:40
         */
        class XmlConfigBuilder {
            private val configuration: Configuration
        
            init {
                configuration = Configuration()
            }
        
            /**
             * 使用dom4j将配置文件进行解析,封装Configuration
             *
             * @param in
             * @return
             */
            @Throws(DocumentException::class, PropertyVetoException::class)
            fun parse(ips: InputStream?): Configuration {
                val document = SAXReader().read(ips)
                // <confiruration>
                val rootElement = document.rootElement
                val list: List<Element?> = rootElement.selectNodes("//property")
                val properties = Properties()
                for (element in list) {
                    val name = element!!.attributeValue("name")
                    val value = element.attributeValue("value")
                    properties.setProperty(name, value)
                }
                val comboPooledDataSource = ComboPooledDataSource()
                comboPooledDataSource.driverClass = properties.getProperty("driverClass")
                comboPooledDataSource.jdbcUrl = properties.getProperty("jdbcUrl")
                comboPooledDataSource.user = properties.getProperty("username")
                comboPooledDataSource.password = properties.getProperty("password")
                configuration.dataSource = comboPooledDataSource
        
                // mapper.xml解析,拿到路径,加载成字节输入流,进行解析
                val mapperList: List<Element?> = rootElement.selectNodes("//mapper")
                // <mapper>
                for (element in mapperList) {
                    val mapperPath = element!!.attributeValue("resource")
                    val resourceAsStream = Resources.getResourceAsStream(mapperPath)
                    val xmlMapperBuilder = XmlMapperBuilder(configuration)
                    xmlMapperBuilder.parse(resourceAsStream)
                }
                return configuration
            }
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        /**
         * @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;
            }
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        // Make sure to add code blocks to your code group

        # mapper映射文件解析

          /**
           * mapper解析器
           *
           * @name: XmlMapperBuilder
           * @author: terwer
           * @date: 2022-05-08 16:16
           */
          class XmlMapperBuilder(private val configuration: Configuration) {
              @Throws(DocumentException::class)
              fun parse(`in`: InputStream?) {
                  val document = SAXReader().read(`in`)
          
                  // <mapper>
                  val rootElement = document.rootElement
                  val namespace = rootElement.attributeValue("namespace")
                  val list: List<Element?> = rootElement.selectNodes("//select")
                  for (element in list) {
                      val id = element!!.attributeValue("id")
                      val resultType = element.attributeValue("resultType")
                      val parameterType = element.attributeValue("parameterType")
                      val sqlText = element.textTrim
                      val mappedStatement = MappedStatement()
                      mappedStatement.statementId = id
                      mappedStatement.resultType = resultType
                      mappedStatement.parameterType = parameterType
                      mappedStatement.sql = sqlText
                      val mappedStatementMap = configuration.mappedStatementMap
                      val statementId = "$namespace.$id"
                      mappedStatementMap[statementId] = mappedStatement
                  }
              }
          }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          /**
           * 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);
                  }
              }
          }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          // Make sure to add code blocks to your code group

          # SqlSession的具体实现

            /**
             * @name: SqlSession
             * @author: terwer
             * @date: 2022-05-08 16:35
             */
            interface SqlSession {
                /**
                 * 查询所有
                 */
                @Throws(Exception::class)
                fun <E> selectList(statementId: String?, vararg params: Any?): List<E>?
            
                /**
                 * 查询单个
                 */
                @Throws(Exception::class)
                fun <T> selectOne(statementId: String?, vararg params: Any?): T
                fun <T> getMapper(mapperClass: Class<*>?): T
            }
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            /**
             * @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);
            }
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            // Make sure to add code blocks to your code group

            文章更新历史

            2022/05/08 feat:增加Kotlin实现。

            编辑 (opens new window)
            #配置文件#项目#结构#具体#代码
            上次更新: 2023/02/22, 13:47:25
            自定义持久层框架的设计思路
            自定义持久层框架的代码实现二

            ← 自定义持久层框架的设计思路 自定义持久层框架的代码实现二→

            最近更新
            01
            解决css部分border被圆角切掉之后圆角的边框消失问题
            03-18
            02
            使用TypeScript开发一个自定义的Node-js前端开发脚手架
            03-08
            03
            Github-Actions使用release-please实现自动发版
            03-06
            更多文章>
            Theme by Vdoing | Copyright © 2011-2023 Terwer Green | MIT License | 粤ICP备2022020721号-1 | 百度统计
            • 跟随系统
            • 浅色模式
            • 深色模式
            • 阅读模式