Complete MyBatis Example and Architecture Overview
The article presents a step‑by‑step MyBatis tutorial that creates a sample user table, adds Maven dependencies, configures MyBatis, defines mapper XML and Java interfaces, demonstrates a test program, and explains core components such as SqlSession, Executor, StatementHandler, ParameterHandler, and ResultSetHandler.
This article, authored by the Vivo Internet Server Team (Zhang Peng), provides a comprehensive, entry‑level demonstration of how MyBatis works, using a complete example that is referenced throughout the subsequent sections.
1. Database preparation
The example operates on a user table with the following DDL and sample data:
CREATE TABLE IF NOT EXISTS user (
id BIGINT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Id',
name VARCHAR(10) NOT NULL DEFAULT '' COMMENT '用户名',
age INT(3) NOT NULL DEFAULT 0 COMMENT '年龄',
address VARCHAR(32) NOT NULL DEFAULT '' COMMENT '地址',
email VARCHAR(32) NOT NULL DEFAULT '' COMMENT '邮件',
PRIMARY KEY (id)
) COMMENT = '用户表'; INSERT INTO user (name, age, address, email) VALUES ('张三', 18, '北京', '[email protected]'); INSERT INTO user (name, age, address, email) VALUES ('李四', 19, '上海', '[email protected]');2. Adding MyBatis
If you build the project with Maven, include the following dependency in pom.xml :
<dependency>
<groupId>org.Mybatis</groupId>
<artifactId>Mybatis</artifactId>
<version>x.x.x</version>
</dependency>3. MyBatis configuration
The minimal MyBatis-config.xml defines the environment, data source, and mapper location:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//Mybatis.org//DTD Config 3.0//EN"
"http://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://127.0.0.1:3306/spring_tutorial?serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="Mybatis/mapper/UserMapper.xml" />
</mappers>
</configuration>4. Mapper XML (UserMapper.xml)
The mapper defines a resultMap and CRUD statements that correspond one‑to‑one with the Java interface methods:
<mapper namespace="io.github.dunwu.spring.orm.mapper.UserMapper">
<resultMap id="BaseResultMap" type="io.github.dunwu.spring.orm.entity.User">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="age" jdbcType="INTEGER" property="age" />
<result column="address" jdbcType="VARCHAR" property="address" />
<result column="email" jdbcType="VARCHAR" property="email" />
</resultMap>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from user where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="io.github.dunwu.spring.orm.entity.User">
insert into user (id, name, age, address, email)
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{address,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR})
</insert>
<update id="updateByPrimaryKey" parameterType="io.github.dunwu.spring.orm.entity.User">
update user set name = #{name,jdbcType=VARCHAR}, age = #{age,jdbcType=INTEGER}, address = #{address,jdbcType=VARCHAR}, email = #{email,jdbcType=VARCHAR} where id = #{id,jdbcType=BIGINT}
</update>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select id, name, age, address, email from user where id = #{id,jdbcType=BIGINT}
</select>
<select id="selectAll" resultMap="BaseResultMap">
select id, name, age, address, email from user
</select>
</mapper>5. Mapper Java interface and entity
public interface UserMapper {
int deleteByPrimaryKey(Long id);
int insert(User record);
User selectByPrimaryKey(Long id);
List
selectAll();
int updateByPrimaryKey(User record);
} public class User {
private Long id;
private String name;
private Integer age;
private String address;
private String email;
}6. Test program (MyBatisDemo.java)
public class MyBatisDemo {
public static void main(String[] args) throws Exception {
// Load MyBatis configuration and create SqlSessionFactory
InputStream inputStream = Resources.getResourceAsStream("MyBatis/MyBatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
// Open a SqlSession
SqlSession sqlSession = factory.openSession();
// Execute a mapper method
Long params = 1L;
List
list = sqlSession.selectList("io.github.dunwu.spring.orm.mapper.UserMapper.selectByPrimaryKey", params);
for (User user : list) {
System.out.println("user name: " + user.getName());
}
// Output: user name: 张三
}
}7. SqlSession lifecycle
SqlSession is the top‑level API of MyBatis. It retrieves the MappedStatement by statement ID, creates a cache key, and delegates the actual execution to an Executor . The session should be opened per request or method and closed afterwards; it is not thread‑safe.
8. Executor component
The Executor handles dynamic SQL generation, cache management, and the final database call. Key methods include:
public
List
query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
BoundSql boundSql = ms.getBoundSql(parameter);
CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);
return query(ms, parameter, rowBounds, resultHandler, key, boundSql);
}It first checks the local cache; on a miss it calls queryFromDatabase , which invokes doQuery on a concrete executor (e.g., SimpleExecutor ).
9. StatementHandler
RoutingStatementHandler selects a concrete handler ( SimpleStatementHandler , PreparedStatementHandler , or CallableStatementHandler ) based on the statement type. The handler prepares the JDBC Statement , sets parameters via ParameterHandler , executes the SQL, and passes the ResultSet to ResultSetHandler .
public void parameterize(Statement statement) throws SQLException {
parameterHandler.setParameters((PreparedStatement) statement);
} public
List
query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return resultSetHandler.handleResultSets(ps);
}10. ParameterHandler
The DefaultParameterHandler iterates over ParameterMapping objects, resolves each value (including additional parameters, null handling, and type conversion), and invokes the appropriate TypeHandler to set the value on the PreparedStatement .
typeHandler.setParameter(ps, i + 1, value, jdbcType);11. ResultSetHandler
DefaultResultSetHandler processes the ResultSet according to the ResultMap configuration, converting rows into Java objects (e.g., User ) and handling nested result sets when necessary.
public List
handleResultSets(Statement stmt) throws SQLException { ... }12. References
The article lists official MyBatis repositories, integration projects (Spring, Spring‑Boot), popular extensions (MyBatis‑Plus, Mapper, PageHelper), and several in‑depth tutorials.
vivo Internet Technology
Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.