MyBatis XML 映射文件:select
, insert
, update
, delete
标签详解
大家好,我是你们的码农老司机,今天咱们不飙车,聊聊 MyBatis 里面那些看起来人畜无害,实则暗藏玄机的 XML 标签:select
, insert
, update
, delete
。 别看它们只有短短几个字母,但它们可是 MyBatis 的灵魂,是连接 Java 代码和数据库的桥梁,是让你的代码飞起来的关键!
准备好了吗? 系好安全带,咱们这就出发!
什么是 MyBatis XML 映射文件?
首先,咱们得搞清楚 MyBatis XML 映射文件是啥玩意儿。 简单来说,它就是一个 XML 文件,里面定义了 SQL 语句,以及 Java 方法和 SQL 语句之间的映射关系。 想象一下,你的 Java 代码想从数据库里查点东西,或者往数据库里塞点数据,总不能直接把 SQL 语句写在 Java 代码里吧? 那样代码就变成了一锅粥,可读性极差,维护起来更是噩梦。
MyBatis 的 XML 映射文件就像一个翻译官,它把你的 Java 方法调用翻译成 SQL 语句,然后执行 SQL 语句,再把结果翻译成 Java 对象,最后返回给你的 Java 代码。 这样,你的 Java 代码就不用直接跟 SQL 语句打交道了,代码更加清晰,维护起来也更加方便。
select
标签:查询小能手
select
标签是 MyBatis 中最常用的标签之一,它负责从数据库中查询数据。 咱们先来看一个简单的例子:
<select id="getUserById" parameterType="int" resultType="com.example.User">
SELECT id, name, age, email FROM user WHERE id = #{id}
</select>
这段 XML 代码定义了一个名为 getUserById
的 SQL 查询语句,它接受一个 int
类型的参数(用户的 ID),并返回一个 com.example.User
类型的对象。
id
属性:id
属性是这个select
标签的唯一标识符,它必须是唯一的,用于在 Java 代码中引用这个 SQL 语句。 相当于给这个 SQL 语句起了个名字。parameterType
属性:parameterType
属性指定了传递给 SQL 语句的参数类型。 在这个例子中,参数类型是int
,表示我们将会传递一个整数作为参数。resultType
属性:resultType
属性指定了 SQL 语句返回结果的类型。 在这个例子中,结果类型是com.example.User
,表示 SQL 语句将会返回一个User
类型的对象。 MyBatis 会自动将查询结果映射到User
对象的属性中。#{id}
: 这个是 MyBatis 的占位符,它会被替换成实际的参数值。 MyBatis 会自动处理 SQL 注入的问题,所以你不用担心安全问题。
使用 select
标签的 Java 代码:
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
User user = sqlSession.selectOne("getUserById", 1); // 1 是用户的 ID
System.out.println(user);
} finally {
sqlSession.close();
}
这段 Java 代码首先获取一个 SqlSession
对象,然后调用 selectOne
方法执行 getUserById
查询语句,并将用户的 ID (1) 作为参数传递给 SQL 语句。 最后,selectOne
方法返回一个 User
对象,我们可以把它打印出来。
select
标签的其他属性:
resultMap
属性: 如果你的数据库字段名和 Java 对象的属性名不一致,或者你需要进行一些复杂的映射,可以使用resultMap
属性来指定一个resultMap
。resultMap
可以让你更灵活地控制结果的映射过程。parameterMap
属性:parameterMap
属性已经不建议使用了,现在都使用parameterType
和#{}
占位符来传递参数。fetchSize
属性:fetchSize
属性可以指定每次从数据库中获取的数据行数。 这对于处理大型数据集非常有用,可以避免一次性加载所有数据导致内存溢出。timeout
属性:timeout
属性可以指定 SQL 语句的执行超时时间。 如果 SQL 语句执行时间超过了这个时间,MyBatis 会抛出一个异常。statementType
属性:statementType
属性可以指定 SQL 语句的类型。 默认值是PREPARED
,表示使用预编译的 SQL 语句。 还可以设置为STATEMENT
或CALLABLE
。resultSetType
属性:resultSetType
属性可以指定结果集的类型。 默认值是FORWARD_ONLY
,表示只能向前滚动结果集。 还可以设置为SCROLL_SENSITIVE
或SCROLL_INSENSITIVE
。flushCache
属性:flushCache
属性可以指定是否刷新缓存。 默认值是false
,表示不刷新缓存。useCache
属性:useCache
属性可以指定是否使用缓存。 默认值是true
,表示使用缓存。
使用 resultMap
的例子:
假设你的数据库字段名是 user_name
,而 Java 对象的属性名是 name
,那么你可以使用 resultMap
来进行映射:
<resultMap id="userResultMap" type="com.example.User">
<id property="id" column="id"/>
<result property="name" column="user_name"/>
<result property="age" column="age"/>
<result property="email" column="email"/>
</resultMap>
<select id="getUserById" parameterType="int" resultMap="userResultMap">
SELECT id, user_name, age, email FROM user WHERE id = #{id}
</select>
在这个例子中,我们定义了一个名为 userResultMap
的 resultMap
,它指定了 user_name
字段映射到 name
属性。 然后,我们在 select
标签中使用 resultMap
属性来引用这个 resultMap
。
insert
标签:数据插入专家
insert
标签负责向数据库中插入数据。 咱们来看一个例子:
<insert id="insertUser" parameterType="com.example.User">
INSERT INTO user (name, age, email) VALUES (#{name}, #{age}, #{email})
</insert>
这段 XML 代码定义了一个名为 insertUser
的 SQL 插入语句,它接受一个 com.example.User
类型的参数,并将用户的姓名、年龄和邮箱插入到 user
表中。
parameterType
属性:parameterType
属性指定了传递给 SQL 语句的参数类型。 在这个例子中,参数类型是com.example.User
,表示我们将会传递一个User
类型的对象作为参数。#{name}
,#{age}
,#{email}
: 这些是 MyBatis 的占位符,它们会被替换成User
对象的name
、age
和email
属性的值。
使用 insert
标签的 Java 代码:
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
User user = new User();
user.setName("张三");
user.setAge(20);
user.setEmail("[email protected]");
sqlSession.insert("insertUser", user);
sqlSession.commit(); // 提交事务
} finally {
sqlSession.close();
}
这段 Java 代码首先创建一个 User
对象,并设置用户的姓名、年龄和邮箱。 然后,调用 insert
方法执行 insertUser
插入语句,并将 User
对象作为参数传递给 SQL 语句。 最后,必须调用 sqlSession.commit()
提交事务,才能将数据真正插入到数据库中。
insert
标签的其他属性:
useGeneratedKeys
属性: 如果你的数据库支持自动生成主键,可以使用useGeneratedKeys
属性来告诉 MyBatis 使用数据库自动生成的主键。keyProperty
属性:keyProperty
属性指定了 Java 对象中用于存储自动生成的主键的属性名。keyColumn
属性:keyColumn
属性指定了数据库表中用于存储自动生成的主键的列名。
使用 useGeneratedKeys
的例子:
假设你的 user
表的 id
列是自动生成的,那么你可以这样使用 useGeneratedKeys
:
<insert id="insertUser" parameterType="com.example.User" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
INSERT INTO user (name, age, email) VALUES (#{name}, #{age}, #{email})
</insert>
在这个例子中,我们设置了 useGeneratedKeys
属性为 true
,keyProperty
属性为 id
,keyColumn
属性为 id
。 这样,MyBatis 会在执行完 insert
语句后,自动将数据库自动生成的主键值设置到 User
对象的 id
属性中。
update
标签:数据更新大师
update
标签负责更新数据库中的数据。 咱们来看一个例子:
<update id="updateUser" parameterType="com.example.User">
UPDATE user SET name = #{name}, age = #{age}, email = #{email} WHERE id = #{id}
</update>
这段 XML 代码定义了一个名为 updateUser
的 SQL 更新语句,它接受一个 com.example.User
类型的参数,并将用户的姓名、年龄和邮箱更新到 user
表中,更新的条件是用户的 ID。
parameterType
属性:parameterType
属性指定了传递给 SQL 语句的参数类型。 在这个例子中,参数类型是com.example.User
,表示我们将会传递一个User
类型的对象作为参数。#{name}
,#{age}
,#{email}
,#{id}
: 这些是 MyBatis 的占位符,它们会被替换成User
对象的name
、age
、email
和id
属性的值。
使用 update
标签的 Java 代码:
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
User user = new User();
user.setId(1); // 用户的 ID
user.setName("李四");
user.setAge(25);
user.setEmail("[email protected]");
sqlSession.update("updateUser", user);
sqlSession.commit(); // 提交事务
} finally {
sqlSession.close();
}
这段 Java 代码首先创建一个 User
对象,并设置用户的 ID、姓名、年龄和邮箱。 然后,调用 update
方法执行 updateUser
更新语句,并将 User
对象作为参数传递给 SQL 语句。 最后,必须调用 sqlSession.commit()
提交事务,才能将数据真正更新到数据库中。
delete
标签:数据删除终结者
delete
标签负责从数据库中删除数据。 咱们来看一个例子:
<delete id="deleteUserById" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>
这段 XML 代码定义了一个名为 deleteUserById
的 SQL 删除语句,它接受一个 int
类型的参数(用户的 ID),并从 user
表中删除指定 ID 的用户。
parameterType
属性:parameterType
属性指定了传递给 SQL 语句的参数类型。 在这个例子中,参数类型是int
,表示我们将会传递一个整数作为参数。#{id}
: 这个是 MyBatis 的占位符,它会被替换成实际的参数值(用户的 ID)。
使用 delete
标签的 Java 代码:
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
sqlSession.delete("deleteUserById", 1); // 1 是用户的 ID
sqlSession.commit(); // 提交事务
} finally {
sqlSession.close();
}
这段 Java 代码调用 delete
方法执行 deleteUserById
删除语句,并将用户的 ID (1) 作为参数传递给 SQL 语句。 最后,必须调用 sqlSession.commit()
提交事务,才能将数据真正从数据库中删除。
动态 SQL:让 SQL 语句灵活起来
有时候,你的 SQL 语句需要根据不同的条件动态生成。 例如,你可能需要根据用户的姓名、年龄和邮箱来查询用户,但你不知道用户会输入哪些条件。 这时候,你就需要使用 MyBatis 的动态 SQL 功能。
MyBatis 提供了以下几种动态 SQL 标签:
<if>
标签:if
标签用于判断条件是否成立,如果条件成立,则将if
标签中的 SQL 片段添加到 SQL 语句中。<choose>
(<when>
,<otherwise>
) 标签:choose
标签类似于 Java 中的switch
语句,它用于选择多个条件中的一个。<where>
标签:where
标签用于添加WHERE
子句,并且会自动处理AND
和OR
关键字。<set>
标签:set
标签用于添加SET
子句,并且会自动处理逗号。<trim>
标签:trim
标签可以自定义前缀、后缀和删除的前缀和后缀。<foreach>
标签:foreach
标签用于循环遍历集合,并生成 SQL 片段。
使用 <if>
标签的例子:
<select id="findUsers" parameterType="com.example.User" resultType="com.example.User">
SELECT id, name, age, email FROM user
<where>
<if test="name != null and name != ''">
name LIKE #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
<if test="email != null and email != ''">
AND email LIKE #{email}
</if>
</where>
</select>
在这个例子中,我们使用了三个 <if>
标签来判断用户的姓名、年龄和邮箱是否为空。 如果姓名不为空,则添加 name LIKE #{name}
条件。 如果年龄不为空,则添加 AND age = #{age}
条件。 如果邮箱不为空,则添加 AND email LIKE #{email}
条件。 where
标签会自动处理 AND
关键字,所以你不用担心 SQL 语句出错。
使用 <foreach>
标签的例子:
<select id="findUsersByIds" parameterType="java.util.List" resultType="com.example.User">
SELECT id, name, age, email FROM user
WHERE id IN
<foreach item="id" collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</select>
在这个例子中,我们使用了 <foreach>
标签来循环遍历一个 ID 列表,并生成 id IN (1, 2, 3)
这样的 SQL 片段。 item
属性指定了当前循环的元素名,collection
属性指定了要遍历的集合,open
属性指定了 SQL 片段的前缀,separator
属性指定了元素之间的分隔符,close
属性指定了 SQL 片段的后缀。
总结:
MyBatis 的 XML 映射文件是 MyBatis 的核心,它定义了 SQL 语句以及 Java 方法和 SQL 语句之间的映射关系。 select
, insert
, update
, delete
标签是 MyBatis 中最常用的标签,它们分别负责从数据库中查询数据、向数据库中插入数据、更新数据库中的数据和删除数据库中的数据。 动态 SQL 功能可以让你根据不同的条件动态生成 SQL 语句,让 SQL 语句更加灵活。
掌握了这些知识,你就可以轻松地使用 MyBatis 来操作数据库了。 希望这篇文章对你有所帮助,祝你编程愉快!
表格:MyBatis XML 映射文件标签属性总结
标签 | 常用属性 | 描述 |
---|---|---|
select |
id |
唯一标识符,用于在 Java 代码中引用这个 SQL 语句。 |
parameterType |
传递给 SQL 语句的参数类型。 | |
resultType |
SQL 语句返回结果的类型。 | |
resultMap |
用于指定一个 resultMap ,可以更灵活地控制结果的映射过程。 |
|
insert |
id |
唯一标识符,用于在 Java 代码中引用这个 SQL 语句。 |
parameterType |
传递给 SQL 语句的参数类型。 | |
useGeneratedKeys |
是否使用数据库自动生成的主键。 | |
keyProperty |
Java 对象中用于存储自动生成的主键的属性名。 | |
keyColumn |
数据库表中用于存储自动生成的主键的列名。 | |
update |
id |
唯一标识符,用于在 Java 代码中引用这个 SQL 语句。 |
parameterType |
传递给 SQL 语句的参数类型。 | |
delete |
id |
唯一标识符,用于在 Java 代码中引用这个 SQL 语句。 |
parameterType |
传递给 SQL 语句的参数类型。 |
再来个更加复杂的例子,整合动态 SQL 和 resultMap:
假设我们需要根据用户的姓名、年龄范围和邮箱模糊匹配来查询用户,并且将查询结果映射到 User
对象,但是 User
对象的 fullName
属性需要由数据库中的 firstName
和 lastName
字段拼接而成。
<resultMap id="userResultMap" type="com.example.User">
<id property="id" column="id"/>
<result property="firstName" column="first_name"/>
<result property="lastName" column="last_name"/>
<result property="fullName" column="first_name" select="getFullName"/>
<result property="age" column="age"/>
<result property="email" column="email"/>
</resultMap>
<select id="getFullName" parameterType="com.example.User" resultType="string">
SELECT CONCAT(first_name, ' ', last_name) FROM user WHERE id = #{id}
</select>
<select id="findUsers" parameterType="map" resultMap="userResultMap">
SELECT id, first_name, last_name, age, email FROM user
<where>
<if test="name != null and name != ''">
AND (first_name LIKE #{name} OR last_name LIKE #{name})
</if>
<if test="minAge != null">
AND age >= #{minAge}
</if>
<if test="maxAge != null">
AND age <= #{maxAge}
</if>
<if test="email != null and email != ''">
AND email LIKE #{email}
</if>
</where>
</select>
在这个例子中:
- 我们定义了一个
userResultMap
,将数据库字段映射到User
对象,并且使用<result property="fullName" column="first_name" select="getFullName"/>
来指定fullName
属性的值由getFullName
查询语句返回。 - 我们定义了一个
getFullName
查询语句,用于拼接用户的firstName
和lastName
。 - 我们定义了一个
findUsers
查询语句,使用了动态 SQL 的<if>
标签来根据不同的条件动态生成 SQL 语句。 findUsers
接收一个map
类型的参数,包含了查询条件,例如name
,minAge
,maxAge
,email
。
对应的 Java 代码:
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
Map<String, Object> params = new HashMap<>();
params.put("name", "%张%"); // 模糊匹配姓名包含"张"的用户
params.put("minAge", 20); // 最小年龄为 20
params.put("maxAge", 30); // 最大年龄为 30
params.put("email", "%@example.com%"); // 模糊匹配邮箱包含"@example.com"的用户
List<User> users = sqlSession.selectList("findUsers", params);
for (User user : users) {
System.out.println(user); // 打印用户信息,包括拼接后的 fullName
}
} finally {
sqlSession.close();
}
这个例子展示了 MyBatis 强大的灵活性,你可以根据实际需求灵活地使用 resultMap
和动态 SQL 来构建复杂的查询。
希望这些例子能帮助你更好地理解 MyBatis 的 XML 映射文件! 记住,实践是检验真理的唯一标准,多多练习才能真正掌握这些技巧。