长沙银行网站建设,长沙县建设局网站,googleplay,石墨网站开发0.MyBatis执行流程1.第一个MyBatis查询1.创建数据库和表1.2.添加MyBatis框架依赖【新项目】1.3.添加MyBatis框架依赖【旧项目】1.4.配置连接数据库1.5.配置MyBatis的XML路径2.MyBatis模式开发2.1 添加MyBatis的xml配置 3.增查改删#xff08;CRUD#xff09;5.1.增加操作5.2.… 0.MyBatis执行流程1.第一个MyBatis查询1.创建数据库和表1.2.添加MyBatis框架依赖【新项目】1.3.添加MyBatis框架依赖【旧项目】1.4.配置连接数据库1.5.配置MyBatis的XML路径2.MyBatis模式开发2.1 添加MyBatis的xml配置 3.增查改删CRUD5.1.增加操作5.2.修改操作5.3 删除操作 6.查询操作6.1单表查询 6.2 参数占位符 #{} 与 ${} 区别6.2.1.SQL注入问题6.2.2 like查询6.2.3 属性名和字段名不一致 6.3 resultType6.3.1 resultMap6.3.2 多表查询 7.动态SQL7.1 if 标签7.2 trim 标签7.3 where 标签7.4 set 标签7.5 foreach 标签 MyBatis是什么
MyBatis 是⼀款优秀的持久层框架它⽀持⾃定义 SQL、存储过程以及⾼级映射。MyBatis 去除了⼏乎所有的 JDBC 代码以及设置参数和获取结果集的⼯作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接⼝和 Java POJOPlain Old Java Objects普通⽼式 Java 对象作为数据库中的记录。通过使用MyBatis开发人员可以方便地执行CRUD操作创建、读取、更新和删除以及复杂的数据库查询和存储过程的调用。
【MyBatis官网】
简单来说MyBatis是一个简单、灵活和强大的持久层框架和数据库交互的工具广泛应用于Java开发中使得数据访问变得更加便捷和高效。
0.MyBatis执行流程 大概流程前端发生Ajax请求给控制器控制器调用服务层服务层进行编排服务层调用mybatismybatis调用数据库再逐层返回。
MyBatis在interface中声明方法在xml中实现方法。mybatis是基于这两个实现的。
1.第一个MyBatis查询
MyBatis 也是⼀个 ORM 框架ORMObject Relational Mapping即对象关系映射。在⾯向
对象编程语⾔中将关系型数据库中的数据与对象建⽴起映射关系进⽽⾃动的完成数据与对象的互相转换 将输⼊数据即传⼊对象SQL 映射成原⽣ SQL 将结果集映射为返回对象即输出对象ORM 把数据库映射为对象
数据库表table– 类class记录record⾏数据– 对象object字段field -- 对象的属性attribute
⼀般的 ORM 框架会将数据库模型的每张表都映射为⼀个 Java 类。
也就是说使⽤ MyBatis 可以像操作对象⼀样来操作数据库中的表可以实现对象和数据库表之间
的转换。
1.创建数据库和表
打开MySQL客户端进行登录后直接拷贝下面代码复制粘贴就行。
代码如下
-- 创建数据库
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8mb4;-- 使用数据数据
use mycnblog;-- 创建表[用户表]
drop table if exists userinfo;
create table userinfo(id int primary key auto_increment,username varchar(100) not null,password varchar(32) not null,photo varchar(500) default ,createtime timestamp default current_timestamp,updatetime timestamp default current_timestamp,state int default 1
) default charset utf8mb4;-- 创建文章表
drop table if exists articleinfo;
create table articleinfo(id int primary key auto_increment,title varchar(100) not null,content text not null,createtime timestamp default current_timestamp,updatetime timestamp default current_timestamp,uid int not null,rcount int not null default 1,state int default 1
)default charset utf8mb4;-- 创建视频表
drop table if exists videoinfo;
create table videoinfo(vid int primary key,title varchar(250),url varchar(1000),createtime timestamp default current_timestamp,updatetime timestamp default current_timestamp,uid int
)default charset utf8mb4;-- 添加一个用户信息
INSERT INTO mycnblog.userinfo (id, username, password, photo, createtime, updatetime, state) VALUES
(1, admin, admin, , 2021-12-06 17:10:48, 2021-12-06 17:10:48, 1);-- 文章添加测试数据
insert into articleinfo(title,content,uid)values(Java,Java正文,1);-- 添加视频
insert into videoinfo(vid,title,url,uid) values(1,java title,http://www.baidu.com,1);1.2.添加MyBatis框架依赖【新项目】
在创建新Spring Boot项目时添加依赖
在SQL中添加MyBatis Framework 和 MySQL Driver 1.3.添加MyBatis框架依赖【旧项目】
在旧项目中添加新依赖
!-- 添加 MyBatis 框架 --
dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion2.1.4/version
/dependency
!-- 添加 MySQL 驱动 --
dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.38/versionscoperuntime/scope
/dependency1.4.配置连接数据库
application.yml添加如下内容
spring:datasource:url: jdbc:mysql://localhost:3306/mycnblog?characterEncodingutf8useSSLfalseusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver# 设置MyBatis
mybatis:mapper-locations:- classpath:/mybatis/*Mapper.xml#打印MyBatis 执行SQLconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:level:com.example.demo: debug 注意如果使用mysql-connector-java是5.x之前的使用的是“ com.mysql.jdbc.Driver ” 如果是⼤于 5.x使⽤的是“ com.mysql.cj.jdbc.Driver ” 。 有些主机useSSLfalse 会报错设置成true就行。username,password要写自己mysql的用户名的和密码。如果不配置启动项目是报错 1.5.配置MyBatis的XML路径
application.yml添加如下内容
# 设置MyBatis
#保存路径 /mybatis
#保存文件后缀 名 Mapper.xml
mybatis.mapper-locationsclasspath:/mybatis/*Mapper.xmlclasspath:当前项目的根路径classpath:/mybatis当前项目的根路径下的文件夹叫mybatis*Mapper.xml所有与mybatis相关的xml文件都叫做某某Mapper.xml。比如与用户有关的叫做UserMapper.xml。
2.MyBatis模式开发 MyBatis模式开发由两部分组成
Interface其他层可以注入使用的接口。.xml实现Interface的方法,而SQL语句就在xml文件中。
运行到MyBatis这块Mybatis会生成一个代理对象代理对象会将interface的方法声明和xml中的方法实现组合成代理对象的方法进行填充。实际上服务层调用MyBatis时调用的就是这个代理对象代理对象就是一个普通类普通类自然而然就有方法和方法实现。 1.新建一个mybatis文件夹 2.添加实体类 package com.example.demo.entity;import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;import java.time.LocalDateTime;Data //自动添加set和get方法
public class UserInfoEntity {private Integer id;private String username;private String password;private String photo;//时间格式化JsonFormat(pattern yyyy-MM-dd HH:mm:ss,timezone GMT8)private LocalDateTime createTime;private LocalDateTime updateTime;
}
注意属性名和数据库中的字段名保持一致MyBatis会自动把类和数据库中的数据关联。 3.创建Mapper 在demo下创建mapper包再创建相应的Interface【添加Mapper注解】 添加接口方法用于查询
package com.example.demo.mapper;import com.example.demo.entity.UserInfoEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;Mapper //注意添加注解
public interface UserMapper {ListUserInfoEntity getAll();
}
没有在xml中实现接口中的方法会默认报错。
2.1 添加MyBatis的xml配置
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.demo.mapper.UserMapper/mappernamespace路径要与当前xml实现的接口路径一致。含全包名类名在每个xxxMapper.xml中都需要添加这个xml配置 4.在mybati文件夹下创建一个xxxMapper.xml此处创建UserMapper.xml用于查询用户操作。 添加sql语句 select idgetAll resultTypecom.example.demo.entity.UserInfoEntityselect * from userinfo/selectid 当前xml实现的接口中需要实现的方法的名字。resultType返回结果当前xml实现的接口中对应的方法返回的对象的路径。(如果方法返回的是一个集合只用写集合里的对象) 5.添加Service 咱们说服务器是调用的所以使用Service调用
package com.example.demo.service;import com.example.demo.entity.UserInfoEntity;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;Service
public class UserService {Autowiredprivate UserMapper userMapper;public ListUserInfoEntity getAll() {return userMapper.getAll();}
}
注入 uerMapperMyBatis允许使用Interface因为最终实现这行的是由代理对象来填充的。Service层调用然后使用xml文件来实现Interface里的方法具体实现。 6.添加Controller package com.example.demo.controller;import com.example.demo.entity.UserInfoEntity;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;RestController
RequestMapping(/user)
public class UserController {AutowiredUserService userService;RequestMapping(/getAll)public ListUserInfoEntity getAll(){return userService.getAll();}
} 7.运行项目输入url地址 3.增查改删CRUD
⽤户的增加、删除和修改的操作对应使⽤ MyBatis 的标签如下 insert标签插⼊语句 update标签修改语句 delete标签删除语句
5.1.增加操作
mapper 接口方法 实现代码 int add(Param(username) String username,Param(password) String password);
xml的sql语句具体实现
默认情况下返回的是受影响的⾏号。
insert idaddinsert into userinfo(username,password)value(#{username},#{password})
/insert
#{}是替换符。
service代码
public int add(Param(username) String username, Param(password) String password){return userMapper.add(username,password);
}controller代码
RequestMapping(/add)
public int add(Param(username) String username, Param(password) String password){return userService.add(username,password);
}重新运行项目输入url输入参数: 查询数据库看是否添加成功
5.2.修改操作
因为除了controller里的代码和sql语句会有些不同其余层代码基本一致【照着增加操作模仿】所以以下只写controller代码和SQL语句
Controller代码
RequestMapping(/update)
public int update(Param(id)Integer id,Param(username) String username){return userService.update(id,username);
}XML中的SQL语句:
update idupdateupdate userinfo set username#{username} where id#{id}
/update运行结果 5.3 删除操作
其他代码雷同SQL语句
delete iddelByIddelete from userinfo where id#{id}
/delete6.查询操作
6.1单表查询
实现根据用户id查询用户信息的功能
Controller代码如下
RequestMapping(/getuser)
public UserInfoEntity getUserById(Integer id) {return userService.getUserById(id);
}XML的SQL语句实现如下
select idgetUserById resultTypecom.example.demo.entity.UserInfoEntityselect * from userinfo where id#{id}
/select6.2 参数占位符 #{} 与 ${} 区别
在MyBatis中#{} 和 ${} 是参数占位符用于在SQL语句中插入参数值。它们的主要区别在于如何处理参数。 #{} 预编译处理 MyBatis 在处理#{}时会将 SQL 中的 #{} 替换为?号使⽤ PreparedStatement 的 set ⽅法来赋值。 使用 #{} 时MyBatis会将参数值作为预编译的参数进行处理可以有效防止SQL注入攻击。 #{} 会自动进行参数类型转换和安全处理使得传递参数更加方便和安全。 #{} 可以直接在SQL语句中使用例如 WHERE column_name #{paramName}。 ${} 直接替换处理 MyBatis 在处理 ${} 时就是把 ${} 简单的替换成变量的值不做任何的特殊处理比如 ${}不会自动添加 号,而#{}会自动加上号。使用 ${} 时MyBatis会将参数值直接拼接到SQL语句中类似于字符串替换。${} 不会对参数进行安全处理或类型转换可能存在SQL注入风险。${} 可以用于动态生成SQL语句的部分内容例如表名、列名等。
综上所述#{} 和 ${} 的区别主要在于参数的处理方式和安全性
#{} 是推荐的使用方式能够提供更好的安全性和可读性并且支持参数类型转换。${} 可以用于一些特殊场景例如动态生成SQL语句的部分内容但需要注意潜在的SQL注入问题。
在编写MyBatis的SQL语句时请根据具体需求选择合适的参数占位符以确保代码的安全和稳定性。
请注意有些特殊情况下例如在动态SQL中可能需要结合使用 #{} 和 ${} 来实现更灵活的功能。
6.2.1.SQL注入问题
SQL注入是一种常见的安全漏洞攻击者可以在应用程序中的输入点插入恶意的SQL代码来执行未经授权的操作或获取敏感数据。以下是一个简单的SQL注入示例
假设有一个简单的登录功能用户可以通过输入用户名和密码进行身份验证
RequestMapping(/islogin)
public UserInfoEntity isLogin(String username,String password){return userService.isLogin(username,password);
}XML代码
select idisLogin resultTypecom.example.demo.entity.UserInfoEntityselect * from userinfo where username${username} and password${password}
/select在上述代码中使用直接替换的方式将用户输入内容直接替换到SQL查询语句中。如果攻击者在用户名或密码输入框中输入恶意的值就可以构造出恶意的SQL语句例如
localhost:8080/user/islogin?usernamelisipasswordor 11 and id 5假设MySQL的userinfo表如下
使用postman演示 最终构成的代码是
SELECT * FROM userinfo WHERE username lisi AND password or 11 and id 5上述sql语句表示查询userinfo表username是lisi 并且 password为空或者 11 并且id5。username’lisi‘为真password是空为假但是11and id5 为真于是不需要密码就查询到了结果。
这个恶意的SQL语句绕过了正常的身份验证逻辑使得查询条件始终为真因此可以绕过登录功能并返回所有用户的数据。要防止SQL注入攻击可以使用参数化查询使用#{}参数占位符或预编译语句来构建SQL语句。
6.2.2 like查询
简单使用#{} 进行like查询会无结果的: select idfindUserByName resultTypecom.example.demo.entity.UserInfoEntityselect * from userinfo where username like %#{username}%/select在上述示例中#{username}是占位符%是通配符。如果传递username值为“lisi”相当于select * from userinfo where username like %lisi%;是查询不到结果的。
进行like查询需要使用#{},加上配合mysql内置函数 concat()来实现
select idfindUserByName resultTypecom.example.demo.entity.UserInfoEntityselect * from userinfo where username like concat(%,#{usernam
e});
/select在上述示例中#{username}是占位符可以通过参数传递具体的值。使用CONCAT()函数将占位符和%通配符连接在一起实现以指定值开头的模糊匹配。
6.2.3 属性名和字段名不一致
如果是增、删、改返回受影响的⾏数那么在 mapper.xml 中是可以不设置返回的类型的因为默认是返回受影响的行数如下图所示 但是查询操作不设置返回类型则会报错 select idgetById select * from userinfo where id#{id}/select运行结果
显示运行了一个查询但没有找到结果映射也就是说对于 select 查询标签至少需要两个属性
id属性:用于标识实现接口中的某个方法结果映射属性有两种实现标签 resultMap 与 resultType
6.3 resultType
大多数情况下都可以使用resultType原因是使用方便直接定义到某个实体类的路径就行 select idgetAll resultTypecom.example.demo.entity.UserInfoEntityselect * from userinfo/select表示将查询结果映射到UserInfoEntity对象。
6.3.1 resultMap
resultMap使用场景
字段名和程序中属性名不一致可使用resultMap配置映射。一对一和一对多关系可以使用resultMap映射并查询数据。
resultMap iduserResultMap typecom.example.Userid propertyid columnuser_id/idresult propertyusername columnuser_name]/resultresult propertyemail columnuser_email/result!-- 其他映射关系 --!-- ..... --/resultMapselect idgetAll resultMapuserResultMapselect * from userinfo
/select在上述示例中resultMap定义了User类与查询结果的映射关系。具体解释如下
property 属性property属性指定Java对象属性的名称。column 属性column属性指定数据库表中对应字段的列名。id 属性主键result属性普通字段和属性
通过配置合适的resultMap可以灵活地定义不同查询的映射关系以满足特定业务需求。
使用时只需要将ResultMap配置的id名添加到相应的位置如上述代码中 select 标签
java类属性如下
数据库字段如下
虽然属性和字段名不一致但通过上述resultMap配置后一样可以成功映射 6.3.2 多表查询
ArticleInfo类
package com.example.demo.entity;import lombok.Data;import java.time.LocalDateTime;Data
public class ArticleInfo {private int id;private String title;private String content;private LocalDateTime createtime;private LocalDateTime updatatime;private int uid;Overridepublic String toString() {return ArticleInfo{ id id , title title \ , content content \ , createtime createtime , updatatime updatatime , uid uid };}
}
ArticleInfoVO类
package com.example.demo.entity.vo;import com.example.demo.entity.ArticleInfo;
import lombok.Data;Data
public class ArticleInfoVO extends ArticleInfo {private String username;Overridepublic String toString() {return ArticleInfoVO{ username username \ } super.toString();}
}
ArticleMapper:
package com.example.demo.mapper;import com.example.demo.entity.vo.ArticleInfoVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;Mapper
public interface ArticleMapper {//查询文章详情ArticleInfoVO getDetail(Param(id)Integer id);
}XML:重点还是sql语句
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.demo.mapper.ArticleMapperselect idgetDetail resultTypecom.example.demo.entity.vo.ArticleInfoVOselect a.*,u.username from articleinfo aleft join userinfo u on u.ida.uidwhere a.id#{id}/select
/mapperTest测试类
这是一个单元测试的类 package com.example.demo.mapper;import com.example.demo.entity.vo.ArticleInfoVO;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;import static org.junit.jupiter.api.Assertions.*;SpringBootTest
class ArticleMapperTest {Autowiredprivate ArticleMapper articleMapper;Testvoid getDetail() {ArticleInfoVO articleInfoVO articleMapper.getDetail(2);System.out.println(articleInfoVO);}
}测试类运行结果: 7.动态SQL
MyBatis提供了强大的动态SQL功能可以根据不同的条件来动态生成SQL语句。大白话就是允许我们在xml进行条件判断。
【mybatis】
7.1 if 标签
假设在注册一个账号时需要输入账户和密码【必填字段】而性别可以选择性填写【非必填字段】那么如果有不确定的字段传入这个时候就需要使用动态标签 if 来判断了比如性别sex可为非必填字段具体实现如下
insert idaddinsert into userinfovalue(#{username},#{password},if testsex ! nullsex #{sex},/if#{age})/insert在上述示例中if标签被嵌套在inser语句内部。if标签中的test属性指定了条件表达式test中传入的是对象属性满足条件时才会包含对应的SQL代码。
在示例中如果传入的userinfo对象的sex属性不为空则生成一个sex #{sex},的条件这样就可以根据不同情况拼接不同的查询条件。
if标签还支持更复杂的条件判断可以使用比较运算符、逻辑运算符、调用对象方法等。
需要注意的是在使用if时需要遵循以下几点
条件表达式必须是合法的OGNL表达式。在条件表达式中使用null时要使用 ! null进行判断不能直接使用。条件表达式中的字符串比较要注意处理空字符串比如if testname ! null and name ! 。
7.2 trim 标签
trim标签是用于处理SQL语句中多余的空格和逗号的XML元素。它可以根据需要添加或移除SQL语句中的前缀、后缀、前后缀或者连接词。
trim标签有以下属性可用
prefix在SQL语句开头添加的前缀。prefixOverrides需要移除的前缀内容。suffix在SQL语句末尾添加的后缀。suffixOverrides需要移除的后缀内容。
下面是一个使用trim标签的示例
select idgetUserList parameterTypecom.example.User resultTypecom.example.UserSELECT * FROM usersWHERE id #{id} and trim prefixAND prefixOverridesORif testname ! null and name ! OR name #{name}/ifif testage ! nullOR age #{age}/if/trim
/select在上述示例中trim标签被嵌套在where语句内部。trim标签根据指定的条件添加或移除相应的前缀和前缀内容。
在示例中如果传入的User对象的name属性不为空则生成一个前缀为AND的条件,并移除前缀中多余的OR,也就是AND name #{name}如果age属性不为空则生成一个前缀为AND的条件,并移除前缀中多余的OR,也就是AND age #{age}。这样可以动态地拼接多个条件。当然也可以拼, 号(号、)号。
比如
insert idaddinsert into user
trim prefix( suffix) suffixOverrides,if testusername ! nullusername,/ifif testpassword ! nullpassword,/if/trimtrim prefixvalues ( suffix) suffixOverrides,if testusername ! null#{username},/ifif testpassword ! null#{password},/if/trim
/insert上述代码在第一个 trim标签在语句开始部分会加上(如果传入的username不为空则会生成一个username并把,去掉如果传入的password不为空则会生成一个password并把,去掉最后加上)
在第二个 trim标签在语句开始部分会加上values (如果传入的username不为空则会生成一个username并把,去掉如果传入的password不为空则会生成一个password并把,去掉最后加上)
7.3 where 标签
where标签是用于动态生成SQL语句中的WHERE。它可以根据条件判断自动生成和连接各个查询条件并且能够处理多余的逻辑运算符如AND、OR。
下面是一个使用where标签的示例
select idgetUserList parameterTypecom.example.User resultTypecom.example.UserSELECT * FROM userswhereif testname ! null and name ! AND name #{name}/ifif testage ! nullAND age #{age}/if/where
/select在上述示例中where标签包含了两个if标签每个if标签表示一个查询条件。当条件满足时该条件会被添加到WHERE子句中。
如果传入的User对象的name属性不为空则生成一个条件 name #{name}会自动把多余的AND去掉如果age属性不为空则生成一个条件AND age #{age}此处的AND是有效的就不会去掉了。 使用where标签能够动态生成合理的WHERE子句避免因为没有查询条件而导致的无效或错误的SQL语句。 需要注意的是where标签会自动处理多余的逻辑运算符例如只有一个条件时生成的SQL语句不会包含前置的AND。
7.4 set 标签
set标签是用于动态生成UPDATE语句中SET子句的XML元素。它可以根据条件判断自动生成要更新的字段和对应的值并且能够处理多余的逗号,。
下面是一个使用set标签的示例
update idupdateUser parameterTypecom.example.UserUPDATE userssetif testname ! null and name ! name #{name},/ifif testage ! nullage #{age},/if/setWHERE id #{id}
/update在上述示例中set标签包含了两个if标签每个if标签表示一个要更新的字段和对应的值。再次强调test传入的就是对象属性当条件满足时该字段和值会被添加到SET子句中。
如果传入的User对象的name属性不为空则生成一条更新语句name #{name},如果age属性不为空则生成一条更新语句age #{age},,并会自动的去掉最后一个逗号(,)。 使用set标签能够动态生成合理的SET子句避免因为没有更新字段而导致的无效或错误的SQL语句。同时set标签会自动处理多余的逗号确保生成的UPDATE语句的语法正确。 需要注意的是在编写UPDATE语句时set标签应该位于WHERE子句之前。
7.5 foreach 标签
foreach标签是用于在SQL语句中循环遍历集合或数组的XML元素。它可以方便地将集合或数组中的元素插入到SQL语句中生成批量操作的语句。
对集合进⾏遍历时可以使⽤该标签。 foreach 标签有如下属性 collection指定要遍历的集合或数组如 ListSetMap或数组对象 item指定在每次迭代中将集合或数组的元素赋值给的变量名。 index指定在每次循环迭代中集合中的当前索引将被赋值给的变量。 open语句块开头的字符串 close语句块结束的字符串 separator指定每个循环迭代之间的分隔符。
下面是一个使用foreach标签的示例
insert idaddListINSERT INTO users (name, age) VALUESforeach collectionlist itemuser separator,(#{user.name}, #{user.age})/foreach
/insert在上述示例中foreach标签是在INSERT语句中遍历List类型的参数list。每次迭代都将取出集合中的元素赋值给user变量然后将该元素的属性name和age插入到VALUES子句中。 通过使用foreach标签可以轻松实现对集合或数组进行批量操作如批量插入、批量更新等。 需要注意的是foreach标签也支持一些其他属性例如index属性表示当前迭代的索引位置open和close属性用于定义在循环的开头和结尾添加的字符串。
以下是一个使用open和close属性的示例
select idgetUsersByIdList parameterTypejava.util.List resultTypecom.example.UserSELECT * FROM usersWHERE id INforeach collectionlist itemid open( close) separator,#{id}/foreach
/selectopen属性定义了循环的开头字符串它会在整个循环的最前面被插入。一般情况下我们可以将它用来添加开始的括号、引号等。如果不需要在开头添加任何字符串可以将open属性设置为空字符串或省略不写。
在上述示例中我们想要查询一组用户的信息这组用户的ID存储在一个List类型的参数 list中。通过使用foreach标签我们将每个ID作为查询条件的一部分将它们以逗号分隔放在括号内。
假设list中包含了三个ID那么生成的SQL语句将类似于
SELECT * FROM users WHERE id IN (1, 2, 3);通过在foreach标签中使用open和close属性我们可以方便地添加括号使查询条件得到正确的语法结构。 文章转载自: http://www.morning.rongxiaoman.com.gov.cn.rongxiaoman.com http://www.morning.crqpl.cn.gov.cn.crqpl.cn http://www.morning.ctfwl.cn.gov.cn.ctfwl.cn http://www.morning.mrfgy.cn.gov.cn.mrfgy.cn http://www.morning.zczkm.cn.gov.cn.zczkm.cn http://www.morning.rbnp.cn.gov.cn.rbnp.cn http://www.morning.trjr.cn.gov.cn.trjr.cn http://www.morning.dmnqh.cn.gov.cn.dmnqh.cn http://www.morning.kmbgl.cn.gov.cn.kmbgl.cn http://www.morning.wscfl.cn.gov.cn.wscfl.cn http://www.morning.blbys.cn.gov.cn.blbys.cn http://www.morning.thnpj.cn.gov.cn.thnpj.cn http://www.morning.tcsdlbt.cn.gov.cn.tcsdlbt.cn http://www.morning.smmrm.cn.gov.cn.smmrm.cn http://www.morning.sgtq.cn.gov.cn.sgtq.cn http://www.morning.tgtwy.cn.gov.cn.tgtwy.cn http://www.morning.qrwjb.cn.gov.cn.qrwjb.cn http://www.morning.mmxnb.cn.gov.cn.mmxnb.cn http://www.morning.mwwnz.cn.gov.cn.mwwnz.cn http://www.morning.hmtft.cn.gov.cn.hmtft.cn http://www.morning.cbnjt.cn.gov.cn.cbnjt.cn http://www.morning.lwxsy.cn.gov.cn.lwxsy.cn http://www.morning.lhzqn.cn.gov.cn.lhzqn.cn http://www.morning.sqmbb.cn.gov.cn.sqmbb.cn http://www.morning.jhzct.cn.gov.cn.jhzct.cn http://www.morning.xyhql.cn.gov.cn.xyhql.cn http://www.morning.lslin.com.gov.cn.lslin.com http://www.morning.rjjjk.cn.gov.cn.rjjjk.cn http://www.morning.ykyfq.cn.gov.cn.ykyfq.cn http://www.morning.dmfdl.cn.gov.cn.dmfdl.cn http://www.morning.jgzmr.cn.gov.cn.jgzmr.cn http://www.morning.plgbh.cn.gov.cn.plgbh.cn http://www.morning.sfzwm.cn.gov.cn.sfzwm.cn http://www.morning.lqlfj.cn.gov.cn.lqlfj.cn http://www.morning.pjrgb.cn.gov.cn.pjrgb.cn http://www.morning.tgnwt.cn.gov.cn.tgnwt.cn http://www.morning.bpwz.cn.gov.cn.bpwz.cn http://www.morning.hwtb.cn.gov.cn.hwtb.cn http://www.morning.dqcpm.cn.gov.cn.dqcpm.cn http://www.morning.txlnd.cn.gov.cn.txlnd.cn http://www.morning.mzcrs.cn.gov.cn.mzcrs.cn http://www.morning.rlkgc.cn.gov.cn.rlkgc.cn http://www.morning.ztmnr.cn.gov.cn.ztmnr.cn http://www.morning.wfpmt.cn.gov.cn.wfpmt.cn http://www.morning.hmktd.cn.gov.cn.hmktd.cn http://www.morning.cjwkf.cn.gov.cn.cjwkf.cn http://www.morning.dnvhfh.cn.gov.cn.dnvhfh.cn http://www.morning.egmux.cn.gov.cn.egmux.cn http://www.morning.wsyq.cn.gov.cn.wsyq.cn http://www.morning.xpgwz.cn.gov.cn.xpgwz.cn http://www.morning.mhnrx.cn.gov.cn.mhnrx.cn http://www.morning.gtqws.cn.gov.cn.gtqws.cn http://www.morning.lflsq.cn.gov.cn.lflsq.cn http://www.morning.ejknty.cn.gov.cn.ejknty.cn http://www.morning.gczzm.cn.gov.cn.gczzm.cn http://www.morning.hqlnp.cn.gov.cn.hqlnp.cn http://www.morning.dnqpq.cn.gov.cn.dnqpq.cn http://www.morning.flpjy.cn.gov.cn.flpjy.cn http://www.morning.mkbc.cn.gov.cn.mkbc.cn http://www.morning.gkdhf.cn.gov.cn.gkdhf.cn http://www.morning.pgzgy.cn.gov.cn.pgzgy.cn http://www.morning.zlnkq.cn.gov.cn.zlnkq.cn http://www.morning.qcsbs.cn.gov.cn.qcsbs.cn http://www.morning.csnmd.cn.gov.cn.csnmd.cn http://www.morning.zpzys.cn.gov.cn.zpzys.cn http://www.morning.bpmnz.cn.gov.cn.bpmnz.cn http://www.morning.gsdbg.cn.gov.cn.gsdbg.cn http://www.morning.mtbth.cn.gov.cn.mtbth.cn http://www.morning.nqlnd.cn.gov.cn.nqlnd.cn http://www.morning.rkhhl.cn.gov.cn.rkhhl.cn http://www.morning.swsrb.cn.gov.cn.swsrb.cn http://www.morning.dmlsk.cn.gov.cn.dmlsk.cn http://www.morning.hrtwt.cn.gov.cn.hrtwt.cn http://www.morning.wjlhp.cn.gov.cn.wjlhp.cn http://www.morning.kggxj.cn.gov.cn.kggxj.cn http://www.morning.syssdz.cn.gov.cn.syssdz.cn http://www.morning.nqyzg.cn.gov.cn.nqyzg.cn http://www.morning.wnpps.cn.gov.cn.wnpps.cn http://www.morning.bpmz.cn.gov.cn.bpmz.cn http://www.morning.rrms.cn.gov.cn.rrms.cn