首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

MyBatis 實戰總結:從環境搭建到 CRUD 核心操作全流程

     編輯:Java 綜合教學

MyBatis 核心定位

MyBatis 是半自動 ORM 持久層框架:支持原生 SQL、存儲過程、高級映射,消除 95%+ JDBC 樣板代碼(連接獲取、參數綁定、結果集映射、資源關閉)。通過 XML 或註解將接口方法映射為 SQL,POJO 自動映射查詢結果。

Maven 專案快速初始化


<dependencies>
    <!-- MyBatis 核心 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.13</version>
    </dependency>
    <!-- MySQL 驅動 -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.0.33</version>
    </dependency>
    <!-- JUnit 5 測試 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.10.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

核心配置文件

mybatis-config.xml(全局配置)


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo?useSSL=false&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

關鍵點:JDBC URL 必須使用 localhost(非 127.0.0.1)以避免某些環境下的連接超時;POOLED 數據源內置連接池,生產建議替換為 HikariCP。

Mapper XML(SQL 映射)


<mapper namespace="com.demo.mapper.UserMapper">
    <resultMap id="userMap" type="com.demo.entity.User">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="email" column="email"/>
        <result property="createTime" column="create_time"/>
    </resultMap>

    <select id="selectById" resultMap="userMap">
        SELECT * FROM t_user WHERE id = #{id}
    </select>

    <select id="selectAll" resultMap="userMap">
        SELECT * FROM t_user
    </select>

    <insert id="insert" parameterType="com.demo.entity.User" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO t_user(username, email) VALUES(#{username}, #{email})
    </insert>

    <update id="update" parameterType="com.demo.entity.User">
        UPDATE t_user SET username=#{username}, email=#{email} WHERE id=#{id}
    </update>

    <delete id="deleteById" parameterType="Long">
        DELETE FROM t_user WHERE id = #{id}
    </delete>
</mapper>

實體類與 Mapper 接口


// User.java
@Data @NoArgsConstructor @AllArgsConstructor
public class User {
    private Long id;
    private String username;
    private String email;
    private LocalDateTime createTime;
}

// UserMapper.java
public interface UserMapper {
    User selectById(Long id);
    List<User> selectAll();
    int insert(User user);
    int update(User user);
    int deleteById(Long id);
}

SqlSession 生命週期與線程安全

  • SqlSessionFactory:線程安全,應用啟動時構建一次,單例保存
  • SqlSession:**非線程安全**,每請求/事務一個,用完必須 close() 歸還連接
  • Spring 整合時由 SqlSessionTemplate 代理管理,自動綁定事務

// 獨立模式標準用法
try (SqlSession session = factory.openSession()) {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectById(1L);
    session.commit(); // 寫操作需提交
    return user;
}

JUnit 5 測試驗證


@BeforeEach void init() throws IOException {
    String resource = "mybatis-config.xml";
    InputStream is = Resources.getResourceAsStream(resource);
    factory = new SqlSessionFactoryBuilder().build(is);
}

@Test void testCRUD() {
    try (SqlSession session = factory.openSession(true)) { // autoCommit=true
        UserMapper mapper = session.getMapper(UserMapper.class);
        
        // Insert
        User u = new User(null, "test", "test@demo.com", null);
        assertEquals(1, mapper.insert(u));
        assertNotNull(u.getId()); // 回寫自增主鍵
        
        // Select
        User found = mapper.selectById(u.getId());
        assertEquals("test", found.getUsername());
        
        // Update
        found.setEmail("updated@demo.com");
        assertEquals(1, mapper.update(found));
        
        // Delete
        assertEquals(1, mapper.deleteById(u.getId()));
        assertNull(mapper.selectById(u.getId()));
    }
}

進階映射技巧

  • resultMap:解決列名與屬性名不匹配(如 create_time → createTime)、關聯查詢(association/collection)、構造方法注入(constructor)
  • 動態 SQL:<where>、<if>、<choose/when/otherwise>、<foreach> 批量插入/IN 查詢
  • 緩存:一級緩存(SqlSession 級)、二級緩存(Mapper 級,需實體實現 Serializable)
  • TypeHandler:自定義類型轉換(如 JSON 字符串 ↔ Object、枚舉 ↔ 代碼)

最佳實踐清單

  1. Mapper 接口與 XML 同包同名,利用 mapperLocations 掃描自動綁定
  2. 參數多於 1 個時必須用 @Param 或封裝 POJO/Map
  3. #{} 預編譯防注入,${} 直接拼接(僅用於表名、排序列等不可預編譯場景)
  4. 分頁查詢使用 PageHelper 插件或數據庫原生 LIMIT/OFFSET
  5. 事務邊界在 Service 層控制(Spring @Transactional),DAO 單純執行 SQL
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved