目录
1、概述
MyBatis 映射文件是用于定义 SQL 查询、插入、更新、删除等操作的 XML 文件。这些文件包含了 SQL 语句以及它们与 Java 方法之间的映射关系。通过映射文件,MyBatis 可以将 Java 对象与数据库表之间进行映射,并提供了灵活的配置选项来满足各种需求。
在整个应用程序中,可以有多个映射文件,每个映射文件对应于一个或多个相关联的数据访问接口。通过这些映射文件,MyBatis 提供了一种优雅的方式来进行数据库操作,同时也提供了良好的可维护性和可扩展性。
一个典型的 MyBatis 映射文件通常包括以下内容:
-
命名空间(Namespace):
<mapper>
标签中的 namespace 属性用于唯一标识这个映射文件,通常是对应于一个 Java 接口的全限定名。 -
SQL 语句定义:在
<select>
、<insert>
、<update>
和<delete>
标签中分别定义了查询、插入、更新和删除操作的 SQL 语句。这些标签的 id 属性指定了方法的名称,parameterType 属性指定了方法参数的类型,而 resultType 或 resultMap 属性指定了查询结果的返回类型。 -
参数映射:SQL 语句中可以使用
#{...}
占位符引用 Java 方法中的参数,从而实现动态 SQL 的生成。 -
结果映射:通过 resultType 或 resultMap 属性指定查询结果的返回类型,MyBatis 可以将数据库查询结果映射为对应的 Java 对象。
-
其他配置选项:映射文件还支持一些高级特性,如动态 SQL、结果映射、缓存配置等,以满足各种复杂的需求。
2、常用元素
属性 | 说明 |
---|---|
mapper | 映射文件的根元素,有一个必需的属性 namespace ,用于指定映射文件的命名空间。命名空间的作用是唯一标识这个映射文件,通常会与一个 Java 接口的全限定名相关联。 |
cache | 可选元素,用于配置二级缓存。二级缓存是在多个会话(session)之间共享的缓存。 |
cache-ref | 从其他命名空间进入缓存配置 |
resultMap | 建立数据库结果集和对象的映射 |
sql | 可以重用SQL语句,也可以被使用 |
insert | 映射插入语句 |
delete | 映射删除语句 |
update | 映射更新语句 |
select | 映射查询语句 |
①mapper
<mapper>
是 MyBatis 映射文件中的根元素,用于定义一个映射文件。,<mapper>
元素中的 namespace
属性用于指定映射文件的命名空间。
namespace的作用
-
唯一标识映射文件:命名空间为映射文件提供了唯一的标识符。每个映射文件都应该有一个唯一的命名空间,以便 MyBatis 可以正确地加载和解析它们。
-
关联 Java 接口:命名空间通常与一个 Java 接口的全限定名相关联。通过命名空间,MyBatis 可以将映射文件中定义的 SQL 操作与对应的 Java 接口进行关联。这样,Java 代码就可以方便地调用映射文件中定义的 SQL 操作,实现数据访问与业务逻辑的分离。
-
组织和管理映射文件:命名空间有助于组织和管理映射文件。通常情况下,映射文件的命名空间与相应的 Java 接口的名称和包路径保持一致,这样可以使得映射文件更加清晰地组织,并且方便开发人员进行查找和维护。
-
命名空间的继承:在 MyBatis 中,可以使用
<mapper>
元素的namespace
属性来继承其他映射文件的命名空间。这样可以使得一个映射文件可以重用另一个映射文件中定义的 SQL 操作,从而提高代码的复用性和可维护性。
<mapper namespace="org.example.pojo.User">
<!--id ="接口中的方法名"
parameterType="传入的参数类型"
resultType = "返回实体类对象,使用包.类名"-->
<select id="findById"
parameterType="int"
resultType="org.example.pojo.User">
select * from users where uid = #{id}
</select>
</mapper>
②resultMap
<resultMap>
元素是 MyBatis 中用于定义查询结果映射规则的重要元素之一。它可以帮助将数据库查询结果映射到 Java 对象的属性上,以便于在代码中直接操作。
在MySQL中
create table users(
sid int primary key auto_increment,
sname varchar(50),
s_email varchar(50));
在实体类中
public class Uses{
private integer id;
private String name;
private String email;
}
在映射文件中
<!-- 定义结果映射规则 -->
<resultMap id="userMap" type="org.example.pojo.User">
<!-- 映射主键属性 -->
<id property="id" column="sid" />
<!-- 映射普通属性 -->
<result property="username" column="sname"/>
<result property="email" column="s_email"/>
</resultMap>
<!-- 查询语句,使用了上面定义的结果映射规则 -->
<select id="findById" resultMap="userMap">
<!-- 注意:这里的查询语句应该根据需要筛选特定的用户,而不是查询所有用户 -->
select * from users
</select>
③sql
<sql>
可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值。
1.参数静态
<sql id="userColumns">
id, username, email
</sql>
<select id="getUser" parameterType="int" resultType="org.example.pojo.User">
SELECT <include refid="userColumns"/> FROM users WHERE id = #{id}
</select>
2.参数动态
<sql id="users">users</sql>
<!-- 定义用户表的列名 SQL 片段 -->
<sql id="useColumns">
id, uname, email
</sql>
<!-- 定义一个动态引入的 SQL 片段 -->
<sql id="someinclude">
from
<!-- 使用 include_target 属性来动态指定要引入的 SQL 片段 -->
<include refid="${include_target}"/>
</sql>
<!-- 查询用户信息的 SQL 语句 -->
<select id="findById" parameterType="int" resultType="org.example.pojo.user">
select
<!-- 引入用户表的列名 SQL 片段 -->
<include refid="userColumns"></include>
<!-- 引入动态 SQL 片段,并使用 property 元素为 include_target 属性赋值 -->
<include refid="someinclude">
<property name="include_target" value="users"></property>
</include>
</select>
④insert
<insert>
元素用于定义 SQL 插入操作,即向数据库中插入新的数据行。在执行完定义的SQL语句后,会返回插入记录的数量。
基本结构
<insert id="insertUser" parameterType="org.example.pojo.User">
INSERT INTO users (id, username, email) VALUES (#{id}, #{username}, #{email})
</insert>
你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置为目标属性就 OK 了。
1.使用支持主键自动增长的数据库获取主键值
<insert id="insertUser" parameterType="org.example.pojo.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users (id, username, email) VALUES (#{id}, #{username}, #{email})
</insert>
2.使用不支持主键自动增长的数据库获取主键值
<insert id="insertUser" parameterType="org.example.pojo.User">
<!--order 属性指定了 <selectKey> 元素的执行顺序,在插入语句之前还是之后执行,这里设置为 "BEFORE",表示在执行插入操作之前执行 <selectKey> 元素。-->
<selectKey
keyProperty="id"
resultType="int"
order="BEFORE">
INSERT INTO users (id, username, email) VALUES (#{id}, #{username}, #{email})
</insert>
如果你的数据库还支持多行插入, 你也可以传入一个 Author
数组或集合,并返回自动生成的主键。
<insert id="insertUser" parameterType="org.example.pojo.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users ( username, email) VALUES
<foreach item="item" collection="list" separator=",">
(#{item.username}, #{item.email})
</foreach>
</insert>
⑤delete
<delete>
元素用于定义 SQL 删除操作,即从数据库中删除数据行。
<delete id="deleteUser" parameterType="int">
DELETE FROM users WHERE id = #{id}
</delete>
⑥update
<update>
元素用于定义 SQL 更新操作,即更新数据库中已有的数据行。
基本结构
<update id="updateUser" parameterType="org.example.pojo.User">
update users set
username = #{username},
email = #{email}
where id = #{id}
</update>
⑦select
<select>
元素是 MyBatis 映射文件中的一个重要元素,用于定义 SQL 查询操作。它指定了一个 SQL 查询语句,并将其与 Java 方法进行映射,从而实现数据库查询操作。
基本结构
<select id="findById" parameterType="int" resultType="org.example.pojo.User">
select * from users where uid = #{id}
</select>
<!--#{id},告诉 MyBatis 创建一个预处理语句(PreparedStatement)参数,
在 JDBC 中,这样的一个参数在 SQL 中会由一个“?”来标识,并被传递到一个新的预处理语句中.-->
<!--
// 近似的 JDBC 代码,非 MyBatis 代码...
String selectPerson = "SELECT * FROM PERSON WHERE ID=?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);
-->
这个语句名为 findById,接受一个 int(或 Integer)类型的参数,并返回指定了查询结果的返回类型为
org.example.pojo.User
,其中的键是列名,值便是结果行中的对应值。
常用属性
属性 | 描述 |
---|---|
id | 用于唯一标识该查询操作的名称。 |
parameterType | 指定了方法参数的类型。 |
resultType | 指定查询结果的返回类型,resultType 和 resultMap 之间只能同时使用一个。 |
resultMap | 指定一个预先定义好的结果映射。 |
flushCache | 将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。 |
timeout | 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。 |
useCache | 将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true。 |