在 MyBatis 中不将 SQL 放在循环里进行处理,可采用以下几种方法:
### 批量插入
使用 `<insert>` 标签结合 `<foreach>` 标签实现批量插入。以插入用户信息为例,示例代码如下:
```xml
<insert id="batchInsertUsers" parameterType="java.util.List">
INSERT INTO users (name, age)
VALUES
<foreach collection="list" item="user" separator=",">
(#{user.name}, #{user.age})
</foreach>
</insert>
```
在 Java 代码中调用:
```java
List<User> userList = new ArrayList<>();
// 添加用户信息到列表
userList.add(new User("John", 25));
userList.add(new User("Jane", 22));
sqlSession.insert("batchInsertUsers", userList);
sqlSession.commit();
```
### 批量更新
同样可以使用 `<foreach>` 标签实现批量更新。以下是一个更新用户信息的示例:
```xml
<update id="batchUpdateUsers" parameterType="java.util.List">
<foreach collection="list" item="user" separator=";">
UPDATE users
SET name = #{user.name}, age = #{user.age}
WHERE id = #{user.id}
</foreach>
</update>
```
Java 代码调用:
```java
List<User> userList = new ArrayList<>();
// 添加要更新的用户信息到列表
userList.add(new User(1, "UpdatedJohn", 26));
userList.add(new User(2, "UpdatedJane", 23));
sqlSession.update("batchUpdateUsers", userList);
sqlSession.commit();
```
### 使用存储过程
创建存储过程来处理批量操作,MyBatis 调用存储过程。例如,创建一个存储过程来批量插入用户信息:
```sql
DELIMITER //
CREATE PROCEDURE batch_insert_users(IN names TEXT, IN ages TEXT)
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE name_val TEXT;
DECLARE age_val INT;
DECLARE names_arr TEXT;
DECLARE ages_arr TEXT;
SET names_arr = CONCAT(names, ',');
SET ages_arr = CONCAT(ages, ',');
WHILE i <= LENGTH(names_arr) - LENGTH(REPLACE(names_arr, ',', '')) DO
SET name_val = SUBSTRING_INDEX(SUBSTRING_INDEX(names_arr, ',', i), ',', -1);
SET age_val = CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(ages_arr, ',', i), ',', -1) AS SIGNED);
INSERT INTO users (name, age) VALUES (name_val, age_val);
SET i = i + 1;
END WHILE;
END //
DELIMITER ;
```
MyBatis 的映射文件调用存储过程:
```xml
<select id="callBatchInsertProcedure" statementType="CALLABLE">
{call batch_insert_users(#{names, mode=IN, jdbcType=VARCHAR}, #{ages, mode=IN, jdbcType=VARCHAR})}
</select>
```
Java 代码调用:
```java
String names = "John,Jane";
String ages = "25,22";
Map<String, Object> params = new HashMap<>();
params.put("names", names);
params.put("ages", ages);
sqlSession.selectOne("callBatchInsertProcedure", params);
sqlSession.commit();
```
### 动态 SQL 拼接
利用 MyBatis 的动态 SQL 特性,根据传入的参数动态生成 SQL 语句。例如,根据用户 ID 列表查询用户信息:
```xml
<select id="getUsersByIds" parameterType="java.util.List" resultType="User">
SELECT * FROM users
WHERE id IN
<foreach item="id" collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</select>
```
Java 代码调用:
```java
List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
List<User> userList = sqlSession.selectList("getUsersByIds", idList);
```