MyBatis 是支援自定義 SQL、存儲過程、高級映射的優秀持久層框架。本文從零構建一個「用戶查詢/刪除」完整 Demo,涵蓋:實體類、Mapper XML、核心配置、測試類、目錄結構,適合初學者快速跑通第一個 MyBatis 程序。
src/
├── main/
│ ├── java/
│ │ ├── com.mybatis.po.User.java
│ │ └── com.mybatis.mapping.userMapper.xml
│ └── resources/
│ └── config.xml
└── test/
└── java/com.mybatis.test.Test.java
package com.mybatis.po;
public class User {
private String username;
private String password;
private int age;
// Getter/Setter 略
@Override public String toString() {
return "User{username='" + username + "', age=" + age + "}";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapping.userMapper">
<!-- 根據用戶名查詢單個用戶 -->
<select id="getUser" parameterType="java.lang.String" resultType="com.mybatis.po.User">
select * from user where username = #{username}
</select>
<!-- 根據用戶名刪除 -->
<delete id="deleteUser" parameterType="java.lang.String">
delete from user where username = #{username}
</delete>
<!-- 動態 SQL 示例:條件查詢 -->
<select id="findUsers" resultType="com.mybatis.po.User">
select * from user
<where>
<if test="username != null and username != ''">
and username like concat('%', #{username}, '%')
</if>
<if test="minAge != null">
and age >= #{minAge}
</if>
</where>
</select>
</mapper>
<?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.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/mybatis/mapping/userMapper.xml"/>
</mappers>
</configuration>
package com.mybatis.test;
import com.mybatis.po.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.InputStream;
import java.util.List;
public class Test {
public static void main(String[] args) throws Exception {
String resource = "config.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
try (SqlSession session = factory.openSession()) {
String ns = "com.mybatis.mapping.userMapper.";
// 查詢單個
User user = session.selectOne(ns + "getUser", "username1");
System.out.println("查詢結果:" + user);
// 條件查詢列表 (動態 SQL)
// User param = new User(); param.setUsername("a"); param.setMinAge(18);
// List list = session.selectList(ns + "findUsers", param);
// list.forEach(System.out::println);
// 刪除
// int del = session.delete(ns + "deleteUser", "username1");
// session.commit(); // 增刪改需提交事務
// System.out.println("刪除條數:" + del);
}
}
}
CREATE DATABASE test;
USE test;
CREATE TABLE user (
username VARCHAR(50) PRIMARY KEY,
password VARCHAR(50),
age INT
);
INSERT INTO user VALUES ('username1', '123456', 25);
INSERT INTO user VALUES ('username2', 'abcdef', 30);
<typeAliases> 定義別名)#{ } 預編譯佔位符 (防注入);${ } 字符串替換 (用於表名/排序列等無法預編譯處)session.commit(),或配置 Spring 事務管理器| 問題 | 原因 | 解決 |
|---|---|---|
| BindingException: Invalid bound statement | namespace/id 拼寫錯誤、XML 未被掃描 | 檢查 config.xml <mapper resource=...> 路徑、namespace 與接口一致 |
| 結果集映射失敗 | 字段名與屬性名不一致 (如 user_name vs username) | SQL 用別名 select user_name as username 或 <resultMap> 映射 |
| 動態 SQL where 多餘 and | 手寫 where 1=1 | 用 <where> 標籤自動去除首個 and/or |
| 批量插入慢 | 循環單條 insert | 用 <foreach collection="list" item="u" separator=",">(#{u.username},#{u.password},#{u.age})</foreach> |
生產建議:實際項目建議使用 Mapper 接口開發模式 (無需寫測試類手動獲取 SqlSession),配合 SpringBoot
@MapperScan自動掃描,配合 PageHelper 分頁插件、MyBatis-Plus 條件構造器,開發效率提升數倍。