MyBatis 的映射器(Mapper)是一个接口,它定义了一组与数据库交互的方法。这些方法通常对应于数据库的 CRUD 操作(创建、读取、更新、删除)。MyBatis 会动态地生成这个接口的实现,并在运行时使用这些方法来执行 SQL 语句。
映射器的主要作用是将 Java 方法映射到 SQL 语句,使得开发者可以通过简单的 Java 方法调用来实现对数据库的操作,而不需要直接编写和执行 SQL 语句。这样做的优点是提高了代码的可维护性,减少了模板 SQL 的编写,并且可以将 SQL 语句与 Java 代码分离,便于管理和维护。
下面是使用 MyBatis 映射器的基本步骤:
1、定义映射器接口:
创建一个接口,定义需要与数据库交互的方法。例如
public interface UserMapper {
User getUserById(int id);
List<User> getAllUsers();
void insertUser(User user);
void updateUser(User user);
void deleteUser(int id);
}
2、编写映射文件:
为映射器接口创建一个 XML 文件或使用注解,指定每个方法对应的 SQL 语句。例如,一个 XML 映射文件可能如下所示:
<mapper namespace="com.example.mapper.UserMapper">
<select id="getUserById" resultType="com.example.entity.User">
SELECT * FROM users WHERE id = #{id}
</select>
<select id="getAllUsers" resultType="com.example.entity.User">
SELECT * FROM users
</select>
<insert id="insertUser">
INSERT INTO users (name, email) VALUES (#{name}, #{email})
</insert>
<update id="updateUser">
UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}
</update>
<delete id="deleteUser">
DELETE FROM users WHERE id = #{id}
</delete>
</mapper>
3、映射文件语法解释
在mapper中写命名空间指向该映射文件对应的映射器接口
<mapper namespace="com.example.mapper.UserMapper">
3.1、常用的四种SQL语句
3.1.1、查询
<select id="selectByName" resultMap="DhyCommandResult">
select id, name from test where name = #{name}
</select>
<select id="selectByName" parameterType="java.lang.String" resultType="com.example.DhyCommand">
SELECT id, name FROM test WHERE name = #{name}
</select>
3.1.2、更新
<update id="updateById" parameterType="com.els.modules.price.entity.Test">
update test set name = #{name} where id = #{id}
</update>
3.1.3、新增
<insert id="insertUser">
INSERT INTO test (id, name) VALUES (#{id}, #{name})
</insert>
3.1.4、删除
<delete id="deleteByName">
DELETE FROM test WHERE name = #{name}
</delete>
3.2、映射文件中用于定义SQL语句的常用参数
下面是对映射文件中的SQL语句常用参数的解释,标红的是最常用的一些参数,下面会通过例子进行讲解
id:这个参数是必须的,它定义了SQL语句的唯一标识符,通常与Mapper接口中的方法名相匹配。MyBatis通过这个ID来将SQL语句与接口方法关联起来。
parameterType:这个参数指定了传入SQL语句的参数类型。如果不指定,MyBatis会根据传递给方法的参数自动推断类型。通常,当参数是简单类型(如整数、字符串)时,不需要显式指定parameterType。
resultType:这个参数指定了查询结果的类型。它通常是一个类的完全限定名,MyBatis会将查询结果映射为这个类的实例。如果结果是一个复杂的类型(如集合或自定义对象),则需要使用resultType。
resultMap:当查询结果与实体类的字段不完全对应,或者需要更复杂的映射逻辑时,可以使用resultMap来定义字段和属性之间的映射关系。resultMap是一个更强大的替代品,它可以提供更细粒度的控制。
flushCache:这个参数用于控制在执行查询时是否刷新缓存。默认值为false,如果设置为true,则在执行查询之前,MyBatis会清空一级和二级缓存。
useCache:这个参数用于控制在执行查询时是否使用缓存。默认值为true,如果设置为false,则MyBatis不会使用缓存,而是直接执行SQL语句。
timeout:这个参数指定了查询的超时时间。默认值为未设置,即没有超时限制。如果设置了超时时间,MyBatis会在超过这个时间后抛出异常。
fetchSize:这个参数用于指定每次从数据库中检索的结果行数。它通常用于处理大量数据的分批查询。
statementType:这个参数用于指定SQL语句的类型。可选值包括STATEMENT、PREPARED和CALLABLE。默认值为PREPARED,表示使用预处理语句。
resultSetType:这个参数用于指定结果集的类型。可选值包括FORWARD_ONLY、SCROLL_SENSITIVE和SCROLL_INSENSITIVE。默认值为FORWARD_ONLY,表示结果集只能向前滚动。
databaseId:这个参数用于指定特定的数据库厂商标识符,允许您为不同的数据库实现不同的SQL语句。
3.2.1、 参数:id
在映射器接口中定义这些方法
public interface UserMapper {
User getUserById(int id);
List<User> getAllUsers();
void insertUser(User user);
void updateUser(User user);
void deleteUser(int id);
}
在映射文件中,id作为唯一标识符,用于将SQL语句与映射器接口中的方法相对应。映射文件中的id属性的值必须与映射器接口中定义的方法一致。
<mapper namespace="com.example.mapper.UserMapper">
<select id="getUserById" resultType="com.example.entity.User">
SELECT * FROM users WHERE id = #{id}
</select>
<select id="getAllUsers" resultType="com.example.entity.User">
SELECT * FROM users
</select>
<insert id="insertUser">
INSERT INTO users (name, email) VALUES (#{name}, #{email})
</insert>
<update id="updateUser">
UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}
</update>
<delete id="deleteUser">
DELETE FROM users WHERE id = #{id}
</delete>
</mapper>
3.2.2、 参数:parameterType
parameterType参数用于指定传入SQL语句的参数类型。对于基础数据类型和一些常见的Java类型,parameterType参数值既可以使用他们的完全限定名,也可以使用简写形式。对于实体类的话需要使用完全限定名。
如果
<!--写法一-->
<select id="selectByName" parameterType="java.lang.String" resultType="com.example.DhyCommand">
SELECT id, name FROM test WHERE name = #{name}
</select>
<!--写法二-->
<select id="selectByName" parameterType="string" resultType="com.example.DhyCommand">
SELECT id, name FROM test WHERE name = #{name}
</select>
3.2.3、 参数:resultType
用于指定 SQL 查询结果的类型。这个属性告诉 MyBatis 如何将查询结果映射到 Java 对象(实体类)。MyBatis 会根据 resultType
指定的类型,自动将 SQL 查询返回的列映射到该类型的对象的属性上。
对于返回的数据如果只是某一个实体类中的属性的话,那么resultType
参数的值可以设置为该属性的类型或该实体类的全限定名(可以但是一般不用)。
public class User {
private String username;
// getters and setters
}
<--写法一:不常用-->
<select id="getUserName" parameterType="int" resultType="com.example.User">
SELECT user.name FROM user JOIN other_table ON user.id = other_table.user_id WHERE user.id = #{id}
</select>
<--写法二-->
<select id="getUserName" parameterType="int" resultType="string">
SELECT user.name FROM user JOIN other_table ON user.id = other_table.user_id WHERE user.id = #{id}
</select>
3.2.4、 参数:resultMap
resultMap
的主要作用是解决查询结果的列名与实体类属性名不匹配的情况,或者需要进行复杂的类型转换时。通过 resultMap
,你可以精确地控制每个列如何映射到实体类的属性上。
<resultMap type="DhySnack" id="DhySnackResult">
<id property="id" column="id" />
<result property="snackName" column="snack_name" />
<result property="snackType" column="snack_type" />
<result property="snackNumber" column="snack_number" />
<result property="snackPrice" column="snack_price" />
<result property="residueTime" column="residue_time" />
<result property="startTime" column="start_time" />
<result property="endTime" column="end_time" />
<result property="snackDuration" column="snack_duration" />
<result property="snackEvaluate" column="snack_evaluate" />
<result property="snackParticipants" column="snack_participants" />
<result property="snackUnit" column="snack_unit" />
</resultMap>
3.3、<sql>标签
用于定义可重用的 SQL 片段,这些片段可以在其他 SQL 语句中引用,以减少重复代码并提高维护性。通过 <sql>
元素,你可以创建一个模板或组件,它可以在多个 <select>
、<insert>
、<update>
或 <delete>
元素中使用。
<sql>
元素的id
属性是必需的,它用于在<include>
元素中引用这个 SQL 片段通过
<include>
元素引用了这个 SQL 片段,<include>
元素的refid
属性指向要引用的<sql>
片段的id
3.3.1、SQL片段
通过sql标签定义可重用的部分代码,id作为唯一标识符
<sql id="userColumns">
id, username, email, created_at, updated_at
</sql>
3.3.2、调用SQL片段
在include标签中通过refid属性匹配sql标签的id的属性值来调用指定的sql片段
<select id="selectUsers" resultType="com.example.User">
SELECT <include refid="userColumns"/> FROM users
</select>
<select id="selectUserById" parameterType="int" resultType="com.example.User">
SELECT <include refid="userColumns"/> FROM users WHERE id = #{id}
</select>