Spring Architecture Series-5.Implementing Mybatis Integration

Introduction

MyBatis is a popular persistence framework that provides a flexible way to map SQL statements to Java objects.In this article, I’ll explore how to implements MyBatis integration in aSpring-like framework,base on my miniSpring project’s implementation.

Core Components

The MyBatis integration consists of several key components:

src/com/yaruyng/batis/
├── DefaultSqlSessionFactory.java
├── DefaultSqlSession.java
├── SqlSessionFactory.java
├── SqlSession.java
└── MapperNode.java
src/com/yaruyng/batis/
├── DefaultSqlSessionFactory.java
├── DefaultSqlSession.java
├── SqlSessionFactory.java
├── SqlSession.java
└── MapperNode.java
src/com/yaruyng/batis/ ├── DefaultSqlSessionFactory.java ├── DefaultSqlSession.java ├── SqlSessionFactory.java ├── SqlSession.java └── MapperNode.java

Enter fullscreen mode Exit fullscreen mode

SqlSessionFactory Implementation

The SqlSessionFactory is the entry point for creating SqlSession instance:

<span>public</span> <span>class</span> <span>DefaultSqlSessionFactory</span> <span>implements</span> <span>SqlSessionFactory</span> <span>{</span>
<span>@Autowired</span>
<span>JdbcTemplate</span> <span>jdbcTemplate</span><span>;</span>
<span>String</span> <span>mapperLocations</span><span>;</span>
<span>Map</span><span><</span><span>String</span><span>,</span> <span>MapperNode</span><span>></span> <span>mapperNodeMap</span> <span>=</span> <span>new</span> <span>HashMap</span><span><>();</span>
<span>public</span> <span>void</span> <span>init</span><span>()</span> <span>{</span>
<span>scanLocation</span><span>(</span><span>this</span><span>.</span><span>mapperLocations</span><span>);</span>
<span>// Initialize mapper nodes</span>
<span>}</span>
<span>@Override</span>
<span>public</span> <span>SqlSession</span> <span>openSession</span><span>()</span> <span>{</span>
<span>SqlSession</span> <span>newSqlSession</span> <span>=</span> <span>new</span> <span>DefaultSqlSession</span><span>();</span>
<span>newSqlSession</span><span>.</span><span>setJdbcTemplate</span><span>(</span><span>jdbcTemplate</span><span>);</span>
<span>newSqlSession</span><span>.</span><span>setSqlSessionFactory</span><span>(</span><span>this</span><span>);</span>
<span>return</span> <span>newSqlSession</span><span>;</span>
<span>}</span>
<span>}</span>
<span>public</span> <span>class</span> <span>DefaultSqlSessionFactory</span> <span>implements</span> <span>SqlSessionFactory</span> <span>{</span>
    <span>@Autowired</span>
    <span>JdbcTemplate</span> <span>jdbcTemplate</span><span>;</span>

    <span>String</span> <span>mapperLocations</span><span>;</span>
    <span>Map</span><span><</span><span>String</span><span>,</span> <span>MapperNode</span><span>></span> <span>mapperNodeMap</span> <span>=</span> <span>new</span> <span>HashMap</span><span><>();</span>

    <span>public</span> <span>void</span> <span>init</span><span>()</span> <span>{</span>
        <span>scanLocation</span><span>(</span><span>this</span><span>.</span><span>mapperLocations</span><span>);</span>
        <span>// Initialize mapper nodes</span>
    <span>}</span>

    <span>@Override</span>
    <span>public</span> <span>SqlSession</span> <span>openSession</span><span>()</span> <span>{</span>
        <span>SqlSession</span> <span>newSqlSession</span> <span>=</span> <span>new</span> <span>DefaultSqlSession</span><span>();</span>
        <span>newSqlSession</span><span>.</span><span>setJdbcTemplate</span><span>(</span><span>jdbcTemplate</span><span>);</span>
        <span>newSqlSession</span><span>.</span><span>setSqlSessionFactory</span><span>(</span><span>this</span><span>);</span>
        <span>return</span> <span>newSqlSession</span><span>;</span>
    <span>}</span>
<span>}</span>
public class DefaultSqlSessionFactory implements SqlSessionFactory { @Autowired JdbcTemplate jdbcTemplate; String mapperLocations; Map<String, MapperNode> mapperNodeMap = new HashMap<>(); public void init() { scanLocation(this.mapperLocations); // Initialize mapper nodes } @Override public SqlSession openSession() { SqlSession newSqlSession = new DefaultSqlSession(); newSqlSession.setJdbcTemplate(jdbcTemplate); newSqlSession.setSqlSessionFactory(this); return newSqlSession; } }

Enter fullscreen mode Exit fullscreen mode

key features:

  1. Integration with Spring’s IoC container
  2. Mapper XML file scanning
  3. Session management

Mapper XML Parsing

The framework parse MyBatis mapper XML files:

<span>private</span> <span>Map</span><span><</span><span>String</span><span>,</span> <span>MapperNode</span><span>></span> <span>buildMapperNodes</span><span>(</span><span>String</span> <span>filePath</span><span>)</span> <span>{</span>
<span>SAXReader</span> <span>saxReader</span> <span>=</span> <span>new</span> <span>SAXReader</span><span>();</span>
<span>URL</span> <span>xmlPath</span> <span>=</span> <span>this</span><span>.</span><span>getClass</span><span>().</span><span>getClassLoader</span><span>().</span><span>getResource</span><span>(</span><span>filePath</span><span>);</span>
<span>try</span> <span>{</span>
<span>Document</span> <span>document</span> <span>=</span> <span>saxReader</span><span>.</span><span>read</span><span>(</span><span>xmlPath</span><span>);</span>
<span>Element</span> <span>rootElement</span> <span>=</span> <span>document</span><span>.</span><span>getRootElement</span><span>();</span>
<span>String</span> <span>namespace</span> <span>=</span> <span>rootElement</span><span>.</span><span>attributeValue</span><span>(</span><span>"namespace"</span><span>);</span>
<span>Iterator</span><span><</span><span>Element</span><span>></span> <span>nodes</span> <span>=</span> <span>rootElement</span><span>.</span><span>elementIterator</span><span>();</span>
<span>while</span> <span>(</span><span>nodes</span><span>.</span><span>hasNext</span><span>())</span> <span>{</span>
<span>Element</span> <span>node</span> <span>=</span> <span>nodes</span><span>.</span><span>next</span><span>();</span>
<span>String</span> <span>id</span> <span>=</span> <span>node</span><span>.</span><span>attributeValue</span><span>(</span><span>"id"</span><span>);</span>
<span>String</span> <span>parameterType</span> <span>=</span> <span>node</span><span>.</span><span>attributeValue</span><span>(</span><span>"parameterType"</span><span>);</span>
<span>String</span> <span>resultType</span> <span>=</span> <span>node</span><span>.</span><span>attributeValue</span><span>(</span><span>"resultType"</span><span>);</span>
<span>String</span> <span>sql</span> <span>=</span> <span>node</span><span>.</span><span>getText</span><span>();</span>
<span>MapperNode</span> <span>selectnode</span> <span>=</span> <span>new</span> <span>MapperNode</span><span>();</span>
<span>selectnode</span><span>.</span><span>setNamespace</span><span>(</span><span>namespace</span><span>);</span>
<span>selectnode</span><span>.</span><span>setId</span><span>(</span><span>id</span><span>);</span>
<span>selectnode</span><span>.</span><span>setParameterType</span><span>(</span><span>parameterType</span><span>);</span>
<span>selectnode</span><span>.</span><span>setResultType</span><span>(</span><span>resultType</span><span>);</span>
<span>selectnode</span><span>.</span><span>setSql</span><span>(</span><span>sql</span><span>);</span>
<span>selectnode</span><span>.</span><span>setParameter</span><span>(</span><span>""</span><span>);</span>
<span>this</span><span>.</span><span>mapperNodeMap</span><span>.</span><span>put</span><span>(</span><span>namespace</span> <span>+</span> <span>"."</span> <span>+</span> <span>id</span><span>,</span> <span>selectnode</span><span>);</span>
<span>}</span>
<span>}</span> <span>catch</span> <span>(</span><span>Exception</span> <span>ex</span><span>)</span> <span>{</span>
<span>ex</span><span>.</span><span>printStackTrace</span><span>();</span>
<span>}</span>
<span>return</span> <span>this</span><span>.</span><span>mapperNodeMap</span><span>;</span>
<span>}</span>
<span>private</span> <span>Map</span><span><</span><span>String</span><span>,</span> <span>MapperNode</span><span>></span> <span>buildMapperNodes</span><span>(</span><span>String</span> <span>filePath</span><span>)</span> <span>{</span>
    <span>SAXReader</span> <span>saxReader</span> <span>=</span> <span>new</span> <span>SAXReader</span><span>();</span>
    <span>URL</span> <span>xmlPath</span> <span>=</span> <span>this</span><span>.</span><span>getClass</span><span>().</span><span>getClassLoader</span><span>().</span><span>getResource</span><span>(</span><span>filePath</span><span>);</span>
    <span>try</span> <span>{</span>
        <span>Document</span> <span>document</span> <span>=</span> <span>saxReader</span><span>.</span><span>read</span><span>(</span><span>xmlPath</span><span>);</span>
        <span>Element</span> <span>rootElement</span> <span>=</span> <span>document</span><span>.</span><span>getRootElement</span><span>();</span>
        <span>String</span> <span>namespace</span> <span>=</span> <span>rootElement</span><span>.</span><span>attributeValue</span><span>(</span><span>"namespace"</span><span>);</span>

        <span>Iterator</span><span><</span><span>Element</span><span>></span> <span>nodes</span> <span>=</span> <span>rootElement</span><span>.</span><span>elementIterator</span><span>();</span>
        <span>while</span> <span>(</span><span>nodes</span><span>.</span><span>hasNext</span><span>())</span> <span>{</span>
            <span>Element</span> <span>node</span> <span>=</span> <span>nodes</span><span>.</span><span>next</span><span>();</span>
            <span>String</span> <span>id</span> <span>=</span> <span>node</span><span>.</span><span>attributeValue</span><span>(</span><span>"id"</span><span>);</span>
            <span>String</span> <span>parameterType</span> <span>=</span> <span>node</span><span>.</span><span>attributeValue</span><span>(</span><span>"parameterType"</span><span>);</span>
            <span>String</span> <span>resultType</span> <span>=</span> <span>node</span><span>.</span><span>attributeValue</span><span>(</span><span>"resultType"</span><span>);</span>
            <span>String</span> <span>sql</span> <span>=</span> <span>node</span><span>.</span><span>getText</span><span>();</span>

            <span>MapperNode</span> <span>selectnode</span> <span>=</span> <span>new</span> <span>MapperNode</span><span>();</span>
            <span>selectnode</span><span>.</span><span>setNamespace</span><span>(</span><span>namespace</span><span>);</span>
            <span>selectnode</span><span>.</span><span>setId</span><span>(</span><span>id</span><span>);</span>
            <span>selectnode</span><span>.</span><span>setParameterType</span><span>(</span><span>parameterType</span><span>);</span>
            <span>selectnode</span><span>.</span><span>setResultType</span><span>(</span><span>resultType</span><span>);</span>
            <span>selectnode</span><span>.</span><span>setSql</span><span>(</span><span>sql</span><span>);</span>
            <span>selectnode</span><span>.</span><span>setParameter</span><span>(</span><span>""</span><span>);</span>

            <span>this</span><span>.</span><span>mapperNodeMap</span><span>.</span><span>put</span><span>(</span><span>namespace</span> <span>+</span> <span>"."</span> <span>+</span> <span>id</span><span>,</span> <span>selectnode</span><span>);</span>
        <span>}</span>
    <span>}</span> <span>catch</span> <span>(</span><span>Exception</span> <span>ex</span><span>)</span> <span>{</span>
        <span>ex</span><span>.</span><span>printStackTrace</span><span>();</span>
    <span>}</span>
    <span>return</span> <span>this</span><span>.</span><span>mapperNodeMap</span><span>;</span>
<span>}</span>
private Map<String, MapperNode> buildMapperNodes(String filePath) { SAXReader saxReader = new SAXReader(); URL xmlPath = this.getClass().getClassLoader().getResource(filePath); try { Document document = saxReader.read(xmlPath); Element rootElement = document.getRootElement(); String namespace = rootElement.attributeValue("namespace"); Iterator<Element> nodes = rootElement.elementIterator(); while (nodes.hasNext()) { Element node = nodes.next(); String id = node.attributeValue("id"); String parameterType = node.attributeValue("parameterType"); String resultType = node.attributeValue("resultType"); String sql = node.getText(); MapperNode selectnode = new MapperNode(); selectnode.setNamespace(namespace); selectnode.setId(id); selectnode.setParameterType(parameterType); selectnode.setResultType(resultType); selectnode.setSql(sql); selectnode.setParameter(""); this.mapperNodeMap.put(namespace + "." + id, selectnode); } } catch (Exception ex) { ex.printStackTrace(); } return this.mapperNodeMap; }

Enter fullscreen mode Exit fullscreen mode

This implementation:

  1. Uses DOM4J for XML parsing
  2. Extracts SQL statements and metadata
  3. Creates MapperNode objects

MapperNode Structure

The MapperNode class represents a single SQL statement:

<span>public</span> <span>class</span> <span>MapperNode</span> <span>{</span>
<span>String</span> <span>namespace</span><span>;</span>
<span>String</span> <span>id</span><span>;</span>
<span>String</span> <span>parameterType</span><span>;</span>
<span>String</span> <span>resultType</span><span>;</span>
<span>String</span> <span>sql</span><span>;</span>
<span>String</span> <span>parameter</span><span>;</span>
<span>// Getters and setters</span>
<span>}</span>
<span>public</span> <span>class</span> <span>MapperNode</span> <span>{</span>
    <span>String</span> <span>namespace</span><span>;</span>
    <span>String</span> <span>id</span><span>;</span>
    <span>String</span> <span>parameterType</span><span>;</span>
    <span>String</span> <span>resultType</span><span>;</span>
    <span>String</span> <span>sql</span><span>;</span>
    <span>String</span> <span>parameter</span><span>;</span>

    <span>// Getters and setters</span>
<span>}</span>
public class MapperNode { String namespace; String id; String parameterType; String resultType; String sql; String parameter; // Getters and setters }

Enter fullscreen mode Exit fullscreen mode

Features:

  1. Namespace and ID for unique identification
  2. Parameter and result type information
  3. SQL statement storage
  4. Parameter mapping support

SqlSession Implementation

The DefaultSqlSession handles SQL execution:

<span>public</span> <span>class</span> <span>DefaultSqlSession</span> <span>implements</span> <span>SqlSession</span> <span>{</span>
<span>JdbcTemplate</span> <span>jdbcTemplate</span><span>;</span>
<span>SqlSessionFactory</span> <span>sqlSessionFactory</span><span>;</span>
<span>@Override</span>
<span>public</span> <span>Object</span> <span>selectOne</span><span>(</span><span>String</span> <span>sqlid</span><span>,</span> <span>Object</span><span>[]</span> <span>args</span><span>,</span>
<span>PreparedStatementCallBack</span> <span>pstmtcallback</span><span>)</span> <span>{</span>
<span>String</span> <span>sql</span> <span>=</span> <span>this</span><span>.</span><span>sqlSessionFactory</span><span>.</span><span>getMapperNode</span><span>(</span><span>sqlid</span><span>).</span><span>getSql</span><span>();</span>
<span>return</span> <span>jdbcTemplate</span><span>.</span><span>query</span><span>(</span><span>sql</span><span>,</span> <span>args</span><span>,</span> <span>pstmtcallback</span><span>);</span>
<span>}</span>
<span>}</span>
<span>public</span> <span>class</span> <span>DefaultSqlSession</span> <span>implements</span> <span>SqlSession</span> <span>{</span>
    <span>JdbcTemplate</span> <span>jdbcTemplate</span><span>;</span>
    <span>SqlSessionFactory</span> <span>sqlSessionFactory</span><span>;</span>

    <span>@Override</span>
    <span>public</span> <span>Object</span> <span>selectOne</span><span>(</span><span>String</span> <span>sqlid</span><span>,</span> <span>Object</span><span>[]</span> <span>args</span><span>,</span> 
            <span>PreparedStatementCallBack</span> <span>pstmtcallback</span><span>)</span> <span>{</span>
        <span>String</span> <span>sql</span> <span>=</span> <span>this</span><span>.</span><span>sqlSessionFactory</span><span>.</span><span>getMapperNode</span><span>(</span><span>sqlid</span><span>).</span><span>getSql</span><span>();</span>
        <span>return</span> <span>jdbcTemplate</span><span>.</span><span>query</span><span>(</span><span>sql</span><span>,</span> <span>args</span><span>,</span> <span>pstmtcallback</span><span>);</span>
    <span>}</span>
<span>}</span>
public class DefaultSqlSession implements SqlSession { JdbcTemplate jdbcTemplate; SqlSessionFactory sqlSessionFactory; @Override public Object selectOne(String sqlid, Object[] args, PreparedStatementCallBack pstmtcallback) { String sql = this.sqlSessionFactory.getMapperNode(sqlid).getSql(); return jdbcTemplate.query(sql, args, pstmtcallback); } }

Enter fullscreen mode Exit fullscreen mode

Key aspects:

  1. SQL statement retrieval
  2. Parameter binding
  3. Result mapping
  4. JDBC template integration

Integration with Spring Ioc:

The Mybatis integration leverages Spring’s IoC container:

<span>@Autowired</span>
<span>JdbcTemplate</span> <span>jdbcTemplate</span><span>;</span>
<span>@Autowired</span>
<span>JdbcTemplate</span> <span>jdbcTemplate</span><span>;</span>
@Autowired JdbcTemplate jdbcTemplate;

Enter fullscreen mode Exit fullscreen mode

Benefits:

  1. Automatic dependency injection
  2. Transaction management
  3. Connection pooling
  4. Resource management

XML Configuration

Example mapper XML configuration:

<span><?xml version="1.0" encoding="UTF-8" ?></span>
<span><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"></span>
<span><mapper</span> <span>namespace=</span><span>"com.example.UserMapper"</span><span>></span>
<span><select</span> <span>id=</span><span>"findById"</span> <span>parameterType=</span><span>"java.lang.Integer"</span>
<span>resultType=</span><span>"com.example.User"</span><span>></span>
SELECT * FROM users WHERE id = ?
<span></select></span>
<span></mapper></span>
<span><?xml version="1.0" encoding="UTF-8" ?></span>
<span><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"></span>
<span><mapper</span> <span>namespace=</span><span>"com.example.UserMapper"</span><span>></span>
    <span><select</span> <span>id=</span><span>"findById"</span> <span>parameterType=</span><span>"java.lang.Integer"</span> 
            <span>resultType=</span><span>"com.example.User"</span><span>></span>
        SELECT * FROM users WHERE id = ?
    <span></select></span>
<span></mapper></span>
<?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.example.UserMapper"> <select id="findById" parameterType="java.lang.Integer" resultType="com.example.User"> SELECT * FROM users WHERE id = ? </select> </mapper>

Enter fullscreen mode Exit fullscreen mode

Usage Example

Here’s how to use the Mybatis integration:

<span>@Repository</span>
<span>public</span> <span>class</span> <span>UserDao</span> <span>{</span>
<span>@Autowired</span>
<span>private</span> <span>SqlSessionFactory</span> <span>sqlSessionFactory</span><span>;</span>
<span>public</span> <span>User</span> <span>findById</span><span>(</span><span>Integer</span> <span>id</span><span>)</span> <span>{</span>
<span>SqlSession</span> <span>session</span> <span>=</span> <span>sqlSessionFactory</span><span>.</span><span>openSession</span><span>();</span>
<span>try</span> <span>{</span>
<span>return</span> <span>(</span><span>User</span><span>)</span> <span>session</span><span>.</span><span>selectOne</span><span>(</span>
<span>"com.example.UserMapper.findById"</span><span>,</span>
<span>new</span> <span>Object</span><span>[]{</span><span>id</span><span>},</span>
<span>new</span> <span>UserRowMapper</span><span>()</span>
<span>);</span>
<span>}</span> <span>finally</span> <span>{</span>
<span>session</span><span>.</span><span>close</span><span>();</span>
<span>}</span>
<span>}</span>
<span>}</span>
<span>@Repository</span>
<span>public</span> <span>class</span> <span>UserDao</span> <span>{</span>
    <span>@Autowired</span>
    <span>private</span> <span>SqlSessionFactory</span> <span>sqlSessionFactory</span><span>;</span>

    <span>public</span> <span>User</span> <span>findById</span><span>(</span><span>Integer</span> <span>id</span><span>)</span> <span>{</span>
        <span>SqlSession</span> <span>session</span> <span>=</span> <span>sqlSessionFactory</span><span>.</span><span>openSession</span><span>();</span>
        <span>try</span> <span>{</span>
            <span>return</span> <span>(</span><span>User</span><span>)</span> <span>session</span><span>.</span><span>selectOne</span><span>(</span>
                <span>"com.example.UserMapper.findById"</span><span>,</span>
                <span>new</span> <span>Object</span><span>[]{</span><span>id</span><span>},</span>
                <span>new</span> <span>UserRowMapper</span><span>()</span>
            <span>);</span>
        <span>}</span> <span>finally</span> <span>{</span>
            <span>session</span><span>.</span><span>close</span><span>();</span>
        <span>}</span>
    <span>}</span>
<span>}</span>
@Repository public class UserDao { @Autowired private SqlSessionFactory sqlSessionFactory; public User findById(Integer id) { SqlSession session = sqlSessionFactory.openSession(); try { return (User) session.selectOne( "com.example.UserMapper.findById", new Object[]{id}, new UserRowMapper() ); } finally { session.close(); } } }

Enter fullscreen mode Exit fullscreen mode

Key Features

  1. Mapper XML Support
    • XML-Based SQL configuration
    • Dynamic SQL support
    • Parameter mapping
  2. Session Management
    • Connection handing
    • Transaction boundaries
    • Resource cleanup
  3. Result Mapping
    • Object mapping
    • Type conversion
    • Collection handing
  4. Spring Integration
    • IoC container support
    • Transaction management
    • Resource management

Implementation Details

  1. Mapper Scanning
<span>private</span> <span>void</span> <span>scanLocation</span><span>(</span><span>String</span> <span>location</span><span>)</span> <span>{</span>
<span>String</span> <span>sLocation</span> <span>=</span> <span>this</span><span>.</span><span>getClass</span><span>().</span><span>getClassLoader</span><span>()</span>
<span>.</span><span>getResource</span><span>(</span><span>""</span><span>).</span><span>getPath</span><span>()</span> <span>+</span> <span>location</span><span>;</span>
<span>File</span> <span>dir</span> <span>=</span> <span>new</span> <span>File</span><span>(</span><span>sLocation</span><span>);</span>
<span>for</span> <span>(</span><span>File</span> <span>file</span> <span>:</span> <span>dir</span><span>.</span><span>listFiles</span><span>())</span> <span>{</span>
<span>if</span> <span>(</span><span>file</span><span>.</span><span>isDirectory</span><span>())</span> <span>{</span>
<span>scanLocation</span><span>(</span><span>location</span> <span>+</span> <span>"/"</span> <span>+</span> <span>file</span><span>.</span><span>getName</span><span>());</span>
<span>}</span> <span>else</span> <span>{</span>
<span>buildMapperNodes</span><span>(</span><span>location</span> <span>+</span> <span>"/"</span> <span>+</span> <span>file</span><span>.</span><span>getName</span><span>());</span>
<span>}</span>
<span>}</span>
<span>}</span>
<span>private</span> <span>void</span> <span>scanLocation</span><span>(</span><span>String</span> <span>location</span><span>)</span> <span>{</span>
    <span>String</span> <span>sLocation</span> <span>=</span> <span>this</span><span>.</span><span>getClass</span><span>().</span><span>getClassLoader</span><span>()</span>
            <span>.</span><span>getResource</span><span>(</span><span>""</span><span>).</span><span>getPath</span><span>()</span> <span>+</span> <span>location</span><span>;</span>
    <span>File</span> <span>dir</span> <span>=</span> <span>new</span> <span>File</span><span>(</span><span>sLocation</span><span>);</span>
    <span>for</span> <span>(</span><span>File</span> <span>file</span> <span>:</span> <span>dir</span><span>.</span><span>listFiles</span><span>())</span> <span>{</span>
        <span>if</span> <span>(</span><span>file</span><span>.</span><span>isDirectory</span><span>())</span> <span>{</span>
            <span>scanLocation</span><span>(</span><span>location</span> <span>+</span> <span>"/"</span> <span>+</span> <span>file</span><span>.</span><span>getName</span><span>());</span>
        <span>}</span> <span>else</span> <span>{</span>
            <span>buildMapperNodes</span><span>(</span><span>location</span> <span>+</span> <span>"/"</span> <span>+</span> <span>file</span><span>.</span><span>getName</span><span>());</span>
        <span>}</span>
    <span>}</span>
<span>}</span>
private void scanLocation(String location) { String sLocation = this.getClass().getClassLoader() .getResource("").getPath() + location; File dir = new File(sLocation); for (File file : dir.listFiles()) { if (file.isDirectory()) { scanLocation(location + "/" + file.getName()); } else { buildMapperNodes(location + "/" + file.getName()); } } }

Enter fullscreen mode Exit fullscreen mode

  1. SQL Execution
<span>public</span> <span>Object</span> <span>selectOne</span><span>(</span><span>String</span> <span>sqlid</span><span>,</span> <span>Object</span><span>[]</span> <span>args</span><span>,</span>
<span>PreparedStatementCallBack</span> <span>pstmtcallback</span><span>)</span> <span>{</span>
<span>String</span> <span>sql</span> <span>=</span> <span>this</span><span>.</span><span>sqlSessionFactory</span><span>.</span><span>getMapperNode</span><span>(</span><span>sqlid</span><span>).</span><span>getSql</span><span>();</span>
<span>return</span> <span>jdbcTemplate</span><span>.</span><span>query</span><span>(</span><span>sql</span><span>,</span> <span>args</span><span>,</span> <span>pstmtcallback</span><span>);</span>
<span>}</span>
<span>public</span> <span>Object</span> <span>selectOne</span><span>(</span><span>String</span> <span>sqlid</span><span>,</span> <span>Object</span><span>[]</span> <span>args</span><span>,</span> 
        <span>PreparedStatementCallBack</span> <span>pstmtcallback</span><span>)</span> <span>{</span>
    <span>String</span> <span>sql</span> <span>=</span> <span>this</span><span>.</span><span>sqlSessionFactory</span><span>.</span><span>getMapperNode</span><span>(</span><span>sqlid</span><span>).</span><span>getSql</span><span>();</span>
    <span>return</span> <span>jdbcTemplate</span><span>.</span><span>query</span><span>(</span><span>sql</span><span>,</span> <span>args</span><span>,</span> <span>pstmtcallback</span><span>);</span>
<span>}</span>
public Object selectOne(String sqlid, Object[] args, PreparedStatementCallBack pstmtcallback) { String sql = this.sqlSessionFactory.getMapperNode(sqlid).getSql(); return jdbcTemplate.query(sql, args, pstmtcallback); }

Enter fullscreen mode Exit fullscreen mode

Best Practice

  1. Resource Management
    • Proper session cleanup
    • Connection pooling
    • Transaction boundaries
  2. Error Handling
    • SQL exception handling
    • Resource cleanup in finally blocks
    • Proper error propagation
  3. Performance Optimization
    • Statement caching
    • Connection pooling
    • Batch processing support

Common Challenges and Solutions

  1. Connection Management
    • Use connection pooling
    • Implement proper cleanup
    • Handle transaction boundaries
  2. SQL Mapping
    • Proper parameter binding
    • Result type conversion
    • Collection handling
  3. Transaction Management
    • Spring transaction integration
    • Proper isolation levels
    • Rollback handling

Conclusion

Implementing MyBatis integration in a Spring-like framework provides:

  • Clean separation of concerns
  • Flexible SQL mapping
  • Transaction management
  • Resource optimization Key takeaways:
  • Understanding MyBatis core concepts
  • Spring integration patterns
  • Resource management
  • Performance considerations

This implementation demonstrates how to create a robust ORM framework integration while maintaining simplicity and flexibility.

原文链接:Spring Architecture Series-5.Implementing Mybatis Integration

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
The world is like a mirror: Frown at itand it frowns at you; smile, and it smiles too.
世界犹如一面镜子:朝它皱眉它就朝你皱眉,朝它微笑它也吵你微笑
评论 抢沙发

请登录后发表评论

    暂无评论内容