MyBatis Persistence Framework with Mapper Interface and Maven Integration

MyBatis Persistence Framework with Mapper Interface and Maven Integration

Understanding MyBatis

MyBatis is a powerful persistence framework designed to simplify JDBC development. It operates within the three-tier architecture model:

  • Presentation Layer (UI)
  • Business Layer (Logic)
  • Persistence Layer (Database Operations)

The framework addresses common JDBC challenges:

  • Hardcoding Issues: Database drivers, connection details, and SQL statements are moved to configuration files
  • Complex Operations: Manual parameter setting and result set mapping are automated

Getting Started with MyBatis

Basic Query Example: Steps to Retrieve All Data from User Table

  1. Prepare the user table in your database
  2. Create a project module and add necessary dependencies
  3. Configure the MyBatis core configuration file to replace hardcoded connection information
  4. Create a SQL mapping file to centralize SQL statements
  5. Implement the code:
    1. Define a POJO (Plain Old Java Object) class representing the entity
    2. Load the core configuration file to obtain a SqlSessionFactory object
    3. Get a SqlSession object and execute SQL queries
    4. Release resources properly

Practical Implementation with Maven and MyBatis

POM.xml Dependency Configuration

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>mybatis-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>

        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>

        
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>

        
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.20</version>
        </dependency>
        
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>
Logback Configuration File

<configuration>
    
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%level] %blue(%d{HH:mm:ss.SSS})%cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern>
        </encoder>
    </appender>

    
    <logger name="com.example" level="DEBUG" additivity="false">
        
    </logger>
</configuration>
Entity Class Definition
package com.example.entity;

public class User {
    private int userId;
    private String userName;
    private String userPassword;
    private String userGender;
    private String userAddress;

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public String getUserGender() {
        return userGender;
    }

    public void setUserGender(String userGender) {
        this.userGender = userGender;
    }

    public String getUserAddress() {
        return userAddress;
    }

    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", userName='" + userName + '\'' +
                ", userPassword='" + userPassword + '\'' +
                ", userGender='" + userGender + '\'' +
                ", userAddress='" + userAddress + '\'' +
                '}';
    }
}
MyBatis Core Configuration File


<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mydb?useSSL=false"/>
                <property name="username" value="admin"/>
                <property name="password" value="securepassword"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        
        <mapper resource="com/example/mapper/UserMapper.xml"/>
    </mappers>
</configuration>
UserMapper XML Mapping File



<mapper namespace="com.example.mapper.UserMapper">
    <select id="fetchAllUsers" resultType="com.example.entity.User">
        SELECT user_id, user_name, user_password, user_gender, user_address 
        FROM users;
    </select>
</mapper>
MyBatis Demo Test Class
package com.example;

import com.example.entity.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MyBatisDemo {
    public static void main(String[] args) throws IOException {
        // 1. Load MyBatis core configuration file and get SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        
        // 2. Get SqlSession object
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        // 3. Execute SQL query
        List<User> users = sqlSession.selectList("com.example.mapper.UserMapper.fetchAllUsers");
        System.out.println(users);
        
        // 4. Release resources
        sqlSession.close();
    }
}

Mapper Interface Development

Steps for Mapper Interface Development

  1. Define a Mapper interface with the same name as the SQL mapping file, placing both in the same directory
  2. Set the namespace attribute in the SQL mapping file to the fully qualified name of the Mapper interface
  3. Define methods in the Mapper interface where method names match SQL statement IDs in the mapping file, with consistent parameter and return types
  4. Implementation:
    1. Obtain a proxy object of the Mapper interface using SqlSession's getMapper method
    2. Call the corresponding method to execute SQL

Continued Implementation with Maven, MyBatis, and Mapper

Updated MyBatis Configuration
<mappers>
    
    <package name="com.example.mapper"/>
</mappers>
Updated UserMapper XML Namespace



<mapper namespace="com.example.mapper.UserMapper">
    <select id="fetchAllUsers" resultType="com.example.entity.User">
        SELECT user_id, user_name, user_password, user_gender, user_address 
        FROM users;
    </select>
</mapper>
UserMapper Interface
package com.example.mapper;

import com.example.entity.User;
import java.util.List;

public interface UserMapper {
    // Returns a List containing multiple User entities
    List<User> fetchAllUsers();
}
Updated MyBatis Demo Test Class
package com.example;

import com.example.entity.User;
import com.example.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MyBatisMapperDemo {
    public static void main(String[] args) throws IOException {
        // 1. Load MyBatis core configuration file and get SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        
        // 2. Get SqlSession object
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        // 3. Get proxy object of UserMapper interface
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.fetchAllUsers();
        
        System.out.println(users);
        
        // 4. Release resources
        sqlSession.close();
    }
}

MyBatis Core Configuration

For comprehensive configuration options, refer to the official MyBatis documentation.

Practical Implementation Examples

Configuration-Based Development Approach

Entity Class
package com.example.entity;

public class Product {
    private Integer productId;
    private String productName;
    private String manufacturer;
    private Integer priority;
    private String description;
    private Integer status;

    // Getters and Setters
    // toString() method
}
Mapper Interface
package com.example.mapper;

import com.example.entity.Product;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface ProductMapper {

    /**
     * Fetch all products
     * @return List<Product>
     */
    List<Product> fetchAll();

    /**
     * Fetch product details by ID
     * @param id
     * @return Product
     */
    Product fetchById(int id);

    /**
     * Multi-condition dynamic query
     * Parameter接收方式:
     *     1.散装参数
     *     2.对象参数
     *     3.map集合参数
     * @param status
     * @param manufacturer
     * @param productName
     * @return List<Product>
     */
    List<Product> searchByCondition(@Param("status")int status, 
                                   @Param("manufacturer")String manufacturer, 
                                   @Param("productName")String productName);
    
    /**
     * Single condition dynamic query
     * @param product
     * @return
     */
    List<Product> searchByConditionSingle(Product product);

    /**
     * Add new product
     * @param product
     */
    void addProduct(Product product);

    /**
     * Update product information
     * @param product
     * @return
     */
    int updateProduct(Product product);

    /**
     * Batch delete products
     * @param ids
     */
    void deleteByIds(@Param("ids")int[] ids);
}
Mapper XML Configuration


<mapper namespace="com.example.mapper.ProductMapper">
    
    <resultMap id="productResultMap" type="com.example.entity.Product">
        <result column="product_name" property="productName"/>
        <result column="manufacturer" property="manufacturer"/>
    </resultMap>

    
    <select id="fetchAll" resultMap="productResultMap">
        SELECT *
        FROM products;
    </select>

    
    <select id="fetchById" resultMap="productResultMap">
        SELECT *
        FROM products
        WHERE id = #{id};
    </select>

    
    <select id="searchByCondition" resultMap="productResultMap">
        SELECT * FROM products
        <where>
            <if test="status != null">
                AND status = #{status}
            </if>
            <if test="manufacturer != null and manufacturer != ''">
                AND manufacturer LIKE #{manufacturer}
            </if>
            <if test="productName != null and productName != ''">
                AND productName LIKE #{productName}
            </if>
        </where>
    </select>

    
    <select id="searchByConditionSingle" resultMap="productResultMap">
        SELECT * FROM products
        <where>
            <choose>
                <when test="status != null">
                    status = #{status}
                </when>
                <when test="manufacturer != null and manufacturer != ''">
                    manufacturer LIKE #{manufacturer}
                </when>
                <when test="productName != null and productName != ''">
                    productName LIKE #{productName}
                </when>
            </choose>
        </where>
    </select>

    
    <insert id="addProduct" useGeneratedKeys="true" keyProperty="productId">
        INSERT INTO products (product_name, manufacturer, priority, description, status)
        VALUES (#{productName},#{manufacturer},#{priority},#{description},#{status});
    </insert>

    
    <update id="updateProduct">
        UPDATE products
        <set>
            <if test="productName != null and productName != ''">
                product_name = #{productName},
            </if>
            <if test="manufacturer != null and manufacturer != ''">
                manufacturer = #{manufacturer},
            </if>
            <if test="priority != null">
                priority = #{priority},
            </if>
            <if test="description != null and description != ''">
                description = #{description},
            </if>
            <if test="status != null">
                status = #{status},
            </if>
        </set>
        WHERE id = #{id};
    </update>

    
    <delete id="deleteByIds">
        DELETE FROM products
        WHERE id IN
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
</mapper>
Test Class
package com.example.test;

import com.example.entity.Product;
import com.example.mapper.ProductMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class ProductMapperTest {
    
    @Test
    public void testFetchAll() throws IOException {
        // 1. Load MyBatis core configuration file and get SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        
        // 2. Get SqlSession object
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        // 3. Get ProductMapper interface proxy object
        ProductMapper productMapper = sqlSession.getMapper(ProductMapper.class);
        
        // 4. Execute query and process results
        List<Product> products = productMapper.fetchAll();
        System.out.println(products);
        
        // 5. Release resources
        sqlSession.close();
    }
    
    @Test
    public void testFetchById() throws IOException {
        int id = 1;
        
        // 1. Load MyBatis core configuration file and get SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        
        // 2. Get SqlSession object
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        // 3. Get ProductMapper interface proxy object
        ProductMapper productMapper = sqlSession.getMapper(ProductMapper.class);
        
        // 4. Execute query and process results
        Product product = productMapper.fetchById(id);
        System.out.println(product);
        
        // 5. Release resources
        sqlSession.close();
    }
    
    @Test
    public void testSearchByCondition() throws IOException {
        int status = 1;
        String manufacturer = "TechCorp";
        String productName = "Smartphone";
        
        // Process parameters
        manufacturer = "%" + manufacturer + "%";
        productName = "%" + productName + "%";
        
        // 1. Load MyBatis core configuration file and get SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        
        // 2. Get SqlSession object
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        // 3. Get ProductMapper interface proxy object
        ProductMapper productMapper = sqlSession.getMapper(ProductMapper.class);
        
        // 4. Execute query and process results
        List<Product> products = productMapper.searchByCondition(status, manufacturer, productName);
        System.out.println(products);
        
        // 5. Release resources
        sqlSession.close();
    }
    
    @Test
    public void testAddProduct() throws IOException {
        // Simulate frontend parameters
        String productName = "New Gadget";
        String manufacturer = "InnovateCo";
        int priority = 5;
        String description = "Latest innovation in technology";
        int status = 1;
        
        // Process parameters
        Product product = new Product();
        product.setProductName(productName);
        product.setManufacturer(manufacturer);
        product.setPriority(priority);
        product.setDescription(description);
        product.setStatus(status);
        
        // 1. Load MyBatis core configuration file and get SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        
        // 2. Get SqlSession object with auto-commit
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        
        // 3. Get ProductMapper interface proxy object
        ProductMapper productMapper = sqlSession.getMapper(ProductMapper.class);
        
        // 4. Execute add operation
        productMapper.addProduct(product);
        
        // 5. Get auto-generated ID
        int generatedId = product.getProductId();
        System.out.println("Generated ID: " + generatedId);
        
        // 6. Release resources
        sqlSession.close();
    }
    
    @Test
    public void testUpdateProduct() throws IOException {
        // Simulate frontend parameters
        int id = 2;
        String productName = "Updated Gadget";
        int priority = 6;
        String description = "Updated with latest features";
        int status = 2;
        
        // Process parameters
        Product product = new Product();
        product.setProductId(id);
        product.setProductName(productName);
        product.setPriority(priority);
        product.setDescription(description);
        product.setStatus(status);
        
        // 1. Load MyBatis core configuration file and get SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        
        // 2. Get SqlSession object with auto-commit
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        
        // 3. Get ProductMapper interface proxy object
        ProductMapper productMapper = sqlSession.getMapper(ProductMapper.class);
        
        // 4. Execute update operation
        int affectedRows = productMapper.updateProduct(product);
        System.out.println("Affected rows: " + affectedRows);
        
        // 5. Release resources
        sqlSession.close();
    }
    
    @Test
    public void testDeleteByIds() throws IOException {
        int[] ids = {1, 3, 5};
        
        // 1. Load MyBatis core configuration file and get SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        
        // 2. Get SqlSession object with auto-commit
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        
        // 3. Get ProductMapper interface proxy object
        ProductMapper productMapper = sqlSession.getMapper(ProductMapper.class);
        
        // 4. Execute batch delete operation
        productMapper.deleteByIds(ids);
        
        // 5. Release resources
        sqlSession.close();
    }
}

Annotation-Based Development Approach

MyBatis also supports annotations for simple SQL operations:

  • Query: @Select
  • Insert: @Insert
  • Update: @Update
  • Delete: @Delete

Annotation-based development eliminates the need for XML mapping files. SQL statements are defined directly in interface methods:

package com.example.mapper;

import com.example.entity.Product;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface ProductAnnotationMapper {
    
    @Select("SELECT * FROM products WHERE id = #{id}")
    Product fetchById(int id);
    
    @Insert("INSERT INTO products (product_name, manufacturer, priority, description, status) " +
            "VALUES (#{productName}, #{manufacturer}, #{priority}, #{description}, #{status})")
    void addProduct(Product product);
    
    @Update("UPDATE products SET product_name = #{productName}, " +
            "manufacturer = #{manufacturer}, priority = #{priority}, " +
            "description = #{description}, status = #{status} WHERE id = #{id}")
    int updateProduct(Product product);
    
    @Delete("DELETE FROM products WHERE id = #{id}")
    int deleteById(int id);
}

Tags: MyBatis java Persistence Maven Mapper

Posted on Fri, 16 Oct 2026 16:50:47 +0000 by digitallookout