一、mybatis配置文件概述
mybatis的核心配置文件配置了很多影响mybatis行为的信息,这些信息通常只会配置在一个文件中,并且不会轻易改动。但是,与spring框架整合后,mybatis的核心配置文件信息将配置到spring的配置文件中。不过也需要了解mybatis的核心配置文件中的元素。
模板很多,借助网上大佬的模板总结
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 属性 -->
<properties />
<!-- 设置 -->
<settings>
<setting name="" value=""/>
</settings>
<!-- 类型的别名 -->
<typeAliases />
<!-- 类型处理器 -->
<typeHandlers />
<!-- 对象工厂 -->
<objectFactory type="" />
<!-- 插件 -->
<plugins>
<plugin interceptor=""></plugin>
</plugins>
<!-- 配置环境 -->
<environments default="">
<!-- 环境变量 -->
<environment id="">
<!-- 事务管理器 -->
<transactionManager type=""/>
<!-- 数据源 -->
<dataSource type=""/>
</environment>
</environments>
<!-- 数据库厂商标识 -->
<databaseIdProvider type=""/>
<!-- 映射器,告诉MyBatis到哪里去找映射文件 -->
<mappers>
<mapper resource="../../xxMapper.xml"/>
</mappers>
</configuration>
配置文件中元素的配置顺序不能颠倒,一旦颠倒,在 MyBatis 启动阶段将发生异常
二、映射器概述
映射器是mybatis最复杂且最重要的组件,由一个接口加上XML文件(SQL映射文件)组成。mybatis的映射器也可以使用注解完成,但注解复杂SQL不适用、可读性较差等缺点在实际应用并不广泛。
SQL映射文件常用配置元素
元素名称 | 描述 | 备注 |
---|---|---|
select | 查询语句,最常用、最复杂的元素之一 | 可以自定义参数,返回结果集 |
insert | 插入语句 | 执行后返回一个整数,代表插入的行数 |
update | 更新语句 | 执行后返回一个整数,代表更新的行数 |
delete | 删除语句 | 执行后返回一个整数,代表删除的行数 |
sql | 定义一部分SQL,在多个位置被引用 | 例如一张表,列名一次定义,可以在多个SQL语句中使用 |
resultMap | 用来描述从数据库结果集来加载对象,是最复杂、最强大元素 | 提供映射规则 |
2.1 <select>元素-----select
<select>元素的常用属性
属性名称 | 描述 |
---|---|
id | 它和Mapper的命名空间组合起来使用,是唯一标识符,供MyBatis调用 |
parameterType | 表示传入SQL语句的参数类型的全限定名或别名。它是一个可选属性,MyBatis能推断出具体传入语句的参数 |
resultType | SQL语句执行后的返回类型(全限定名或者别名)。如果是集合类型,返回的是集合元素的类型,返回是可使用resultType或resultType之一。 |
resultMap | 它是映射集的引用,与<resultMap>元素一起使用,返回时可以使用resultType或resultMap之一 |
flushCache | 用于设置在调用SQL语句后是否要求mybatis清空之前查询的本地缓存和二级缓存,默认值为false |
useCache | 启动二级缓存的开关,默认为true,表示将查询结果存入二级缓存 |
timeout | 用于设置超时参数,单位是秒(s),超时将抛出异常 |
fetchSize | 获取记录的总条数设定 |
statementType | 告诉mybatis使用哪个jdbc的statement工作 |
resultSetType | 针对jdbc的ResultSet接口 |
2.1.1 使用Map接口传递多个参数
在开发中,查询SQL语句经常需要传递多个参数。在mybatis中运行Map接口通过键值对传递多个参数。
在mybatis(一)MyBatis与Spring的整合 的基础上进行添加
- 首先在UserMapper.xml映射文件中添加多条件查询语句
<!--多条件查询-->
<select id="selectByMap" parameterType="map" resultType="User">
select * from user where id = #{id} and name = #{name}
</select>
- 在接口UserDao中添加接口
/**
* @param param
* @return
* 多条件查询
*/
public List<User> selectByMap(Map<String,Override> param);
- 在UserController的test方法中添加
//多条件查询
Map<String,Object> param = new HashMap<>();
param.put("id", 1);
param.put("name", "张三");
userDao.selectByMap(param);
- 在TsetController中进行测试
可以看出多条件查询成功。
还有一种传递多个参数的方法是:
使用JavaBean传递多个参数
修改UserMapper.xml映射文件 parameterType = “User” ,在UserController的test方法中使用User的set方法进行设定查询条件,然后进行传参即可。
<!--多条件查询JavaBean,实际可以重新创个parameterType的类-->
<select id="selectByUser" parameterType="User" resultType="User">
select * from user where id = #{id} and name = #{name}
</select>
// User为新建的javabean
// JavaBean传递参数
User param = new User();
param.setId(1);
param.setName("张三");
userDao.selectByUser(param);
2.2 <insert>元素-----insert
<insert>元素用于映射插入语句,mybatis执行完一条插入语句将返回一个整数表示其影响的行数。它的属性与 <select>元素的属性大部分相同,但也有几个特有属性:
- keyProperty:该属性的作用是将插入或更新操作时的返回值赋给PO类的某个属性,通常会设置为主键对应的属性。如果是联合主键,可以将多个值用逗号隔开。
- keyColumn:该主键用于设置第几列是主键,当主键列表不是表中的第1列时需要设置。如果是联合主键,可以将多个值用逗号隔开。
- useGeneratedKeys:该属性将使mybatis使用jdbc的getGeneratedKeys()方法获取由数据库内部产生的主键,例如MySQL、SQL Server 等自动递增的字段,其默认值为false。
2.2.1 主键(自动递增)回填
MySQL、SQL Server 等数据库的表格可以采用自动递增的字段作为主键,有时可能需要使用这个刚产生的主键,用于关联其他业务。
- 首先在UserMapper.xml映射文件中修改<insert>元素中的内容
<!--添加一个用户,开启获取主键值,并将插入后自动递增的主键值返回给id属性-->
<insert id="insertOneUser" parameterType="User" keyProperty="id" useGeneratedKeys="true">
insert into user values(null,#{name},#{sex})
</insert>
- 在UserController的test方法中修改
//增加一个用户并返回主键值
User addUser = new User();
addUser.setName("老王");
addUser.setSex("女");
userDao.insertOneUser(addUser);
System.out.println("插入后的主键值为:" + addUser.getId());
- 结果显示
2.2.2 自定义主键
在实际项目中,有的数据库不支持自动递增或者没有设置自动递增,可以使用mybatis的<selectKey>元素来自定义生成主键。
<!--自定义主键-->
<insert id="" parameterType="">
<!--先使用selectKey元素定义主键,然后再定义SQL语句-->
<selectKey keyProperty="" resultType="" order="">
select decode(max(id),null,1,max(id)+1) as newId from user
</selectKey>
insert into user values (null,#{name},#{sex})
</insert>
- keyProperty元素指定哪个字段为主键,order可以取值before 或者after 意思是在插入语句之前或者之后执行selectKey中的语句
2.3 <update> 和<delete>元素----update–delete
<update> 和<delete>元素中的属性和<select>元素中的相似。用法就像之前一样。
2.4 <sql>元素----sql
<sql>元素元素的作用在于定义SQL语句的一部分,以方便后面的SQL语句引用它,例如反复使用的列名。
- 首先在UserMapper.xml映射文件中修改<select>元素中的内容
<!--重复的列名-->
<sql id="columns"> id,name,sex</sql>
<!--根据id查询user信息-->
<select id="selectByID" parameterType="Integer" resultType="User">
select <include refid="columns"> from user where id = #{id}
</select>
- include 元素的refid属性引用自定义的代码片段
2. 5 <resultMap>元素----resultMap
<resultMap>元素表示结果映射集,是mybatis中最重要也是最强大的元素,主要用来定义映射规则、级联的更新以及定义类型转化器等。
2.5.1 <resultMap>元素的结构----resultMap
<resultMap id="" type="">
<constructor><!-- 类再实例化时用来注入结果到构造方法 -->
<idArg/><!-- ID参数,结果为ID -->
<arg/><!-- 注入到构造方法的一个普通结果 -->
</constructor>
<id/><!-- 用于表示哪个列是主键 -->
<result/><!-- 注入到字段或JavaBean属性的普通结果 -->
<association property=""/><!-- 用于一对一关联 -->
<collection property=""/><!-- 用于一对多、多对多关联 -->
<discriminator javaType=""><!-- 使用结果值来决定使用哪个结果映射 -->
<case value=""/><!-- 基于某些值的结果映射 -->
</discriminator>
</resultMap>
- <resultMap> 元素的 type 属性表示需要的 POJO,id 属性是 resultMap 的唯一标识。
- 子元素<constructor> 用于配置构造方法(当 POJO 未定义无参数的构造方法时使用)。
- 子元素 <id> 用于表示哪个列是主键。
- 子元素 <result> 用于表示POJO和数据表普通列的映射关系。
- 子元素 <association>、<collection> 和 <discriminator> 用在级联的情况下。
一条查询 SQL 语句执行后将返回结果,而结果可以使用 Map 存储,也可以使用 POJO 存储。
2.5.2 使用Map存储结果集
- 在UserMapper.xml中添加映射语句
<!--使用map存储结果集-->
<select id="selectAllMapResult" resultType="map">
select * from user ;
</select>
- 在UserDao中添加接口映射函数
/**
* @return
* 使用map存储结果集
*/
public List<Map<String,Object>> selectAllMapResult();
- 在UserController中test方法中添加逻辑代码
//使用map存储结果集
List<Map<String, Object>> users = userDao.selectAllMapResult();
for (Map<String, Object> user : users) {
System.out.println(user);
}
其中,Map中的key值是select语句中的字段名。value是对应字段的值。
- 在TestController中测试
结果如下
2.5.3 使用POJO存储结果集
- 在UserMapper.xml中添加映射语句
<!--使用自定义结果集类型-->
<resultMap id="userResult" type="User">
<!--property是User类中的属性-->
<!--column是查询结果的列名,可来自不同的表-->
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
</resultMap>
<!--使用POJO存储结果集-->
<select id="selectAllUserResult" resultMap="userResult">
select * from user ;
</select>
- 在UserDao中添加接口映射函数
/**
* @return
* 使用POJO类型存储结果集
* User为新建的POJO类
*/
public List<User> selectAllUserResult();
- 在UserController中test方法中添加逻辑代码
//使用POJO存储结果集
List<User> users1 = userDao.selectAllUserResult();
for (User user : users1) {
System.out.println(user);
}
- 测试与结果
结果与上面一致
2.6 级联查询
级联关系是一个数据库实体的概念,有三种级联关系,分别是一对一级联、一对多级联、多对多级联。
级联查询通俗的说就是利用一个表中的外键查询与之相关联的另一个表(外键对应这个表的主键)中数据。
2.6.1 一对一级联查询(多对一)
在mybatis中,通过<resultMap>元素的子元素<association>处理这种一对一级联关系。<association>元素通常使用以下属性:
- property :指定映射到实体类的对象属性
- column:指定表中对应的字段(查询返回的列名)
- javaType:指定映射到实体对象属性的类型
- select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询。
以一个User对应一个idcard为例:
目录结构,src下面还有一个mybatis-config.xml,详细配置参考MyBatis与Spring的整合
- 首先,创建idcard数据表和实体类
public class IdCard {
private Integer id;
private Integer id_card;
private String id_place;
//省略gitter和setter等
}
User类中添加IdCard属性,并在表中设置外键card_id
public class User {
//属性名与数据表字段名一一对应
private Integer id;
private String name;
private String sex;
//与身份证关联,card_id字段为user表外键
private IdCard idCard;
//省略gitter和setter等
}
创建一个pojo类UserAndCard,存储查询后的数据
public class UserAndCard {
private Integer id;
private String name;
private String sex;
private Integer card_no;
private String card_place;
//省略
}
- 在mapper目录下新建IdCard.xml SQL映射文件,并根据id查询所有
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="main.java.mybatis.dao.IdCardDao">
<select id="selectById" parameterType="Integer" resultType="IdCard">
select * from idcard where id = #{id}
</select>
</mapper>
- 在dao目录下创建IdCardDao接口,并编写查询接口方法
@Repository
@Mapper
public interface IdCardDao {
/**
* @param id
* @return
* 通过id查询IdCard
*/
public IdCard selectById(Integer id);
}
- 在mapper目录下编写UserMapper.xml
<!--一对一级联 根据id查询个人信息:级联查询的第一种方法(嵌套查询,执行两个SQL语句)-->
<resultMap id="UserToCard1" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<!--一对一级联查询 property指定映射到idCard对象,column指查询card_id字段返回数据,javaType指定映射到实体类的类型,select指定嵌套的子SQL语句-->
<association property="idCard" column="card_id" javaType="IdCard" select="main.java.mybatis.dao.IdCardDao.selectById"/>
</resultMap>
<select id="selectUserAndCard1" parameterType="Integer" resultMap="UserToCard1" >
select * from user where id = #{id}
</select>
<!--一对一 根据id查询个人信息:级联查询的第二种方法(嵌套结果,执行一个SQL语句)-->
<resultMap id="UserToCard2" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<!--一对一级联查询 property指定映射到idCard对象,column指查询card_id字段返回数据,javaType指定映射到实体类的类型,select指定嵌套的子SQL语句-->
<association property="idCard" javaType="IdCard">
<id property="id" column="card_id"/>
<result property="card_no" column="card_no"/>
<result property="card_place" column="card_place"/>
</association>
</resultMap>
<select id="selectUserAndCard2" parameterType="Integer" resultMap="UserToCard2" >
select a.*,b.card_no,b.card_place from user a , idcard b where a.id = #{id} and a.card_id = b.id
</select>
<!--一对一 根据id查询个人信息:级联查询的第三种方法(pojo存储结果)-->
<select id="selectUserAndCard3" parameterType="Integer" resultType="UserAndCard" >
select a.*,b.card_no,b.card_place from user a , idcard b where a.id = #{id} and a.card_id = b.id
</select>
- 在mybatis-config.xml配置映射文件
<!--映射文件位置-->
<mappers>
<mapper resource="main/java/mybatis/mapper/UserMapper.xml"/>
<mapper resource="main/java/mybatis/mapper/IdCardMapper.xml"/>
</mappers>
- 在 UserController中编写逻辑代码,调用接口
System.out.println("-----------第一种方法----------");
User useToCard1 = userDao.selectUserAndCard1(1);
System.out.println(useToCard1);
System.out.println("-----------第二种方法----------");
User useToCard2 = userDao.selectUserAndCard2(1);
System.out.println(useToCard2);
System.out.println("-----------第三种方法----------");
UserAndCard useToCard3 = userDao.selectUserAndCard3(1);
System.out.println(useToCard3);
- TestController进行测试
public class TestController {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/main/java/mybatis/applicationContext.xml");
UserController userController = (UserController)applicationContext.getBean("userController");
userController.test();
}
}
三种方法结果一样。一对一,同时也可用作多对一,其中第二种方法更为实用。
2.6.2 一对多
一对多使用<resultMap>元素的子元素<collection property="" ofType="" column = “” select =“”>。也是三种方法,一方面使用List接收多方面,同理一对一。
以一个用户有多个购物订单Orders为例:
- 首先,创建Orders数据表和实体类
/**
* @author xry
* 订单
*/
public class Orders {
private Integer id;
private Integer user_id; //作为外键连接user表的id
private Integer order_no;
//省略gitter和setter等
}
User类中添加orders属性
public class User {
//属性名与数据表字段名一一对应
private Integer id;
private String name;
private String sex;
//与身份证关联,card_id字段为user表外键
private IdCard idCard;
//关联订单
private List<Orders> orders;
//省略gitter和setter等
}
创建一个pojo类UserAndOrders,作为第三种方法使用
public class UserAndCard {
private Integer id;
private String name;
private String sex;
private Integer oid; //区分id
private Integer order_no;
//省略
}
- 在mapper目录下新建OrdersMapper.xml SQL映射文件,并根据id查询所有
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="main.java.mybatis.dao.OrdersDao">
<select id="selectOrdersById" parameterType="Integer" resultType="Orders">
select * from orders where user_id = #{user_id}
</select>
</mapper>
- 在dao目录下创建OrdersDao 接口,作为第一种方法使用,并编写查询接口方法
@Repository
@Mapper
public interface OrdersDao {
/**
* @param id
* @return
* 通过id查询orders
*/
public List<Orders> selectOrdersById(Integer user_id);
}
- 在mapper目录下编写UserMapper.xml
<!--一对多级联查询 第一种方法(嵌套查询)-->
<resultMap id="UserAndOrders1" type="User" >
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<!--ofType表示集合类型,column表示将id值传递给select的值-->
<collection property="orders" ofType="Orders" column="id" select="main.java.mybatis.dao.OrdersDao.selectOrdersById"/>
</resultMap>
<select id="selectUserAndOrders1" parameterType="Integer" resultMap="UserAndOrders1">
select * from user where id = #{id}
</select>
<!--一对多级联查询 第二种方法(一个查询语句)-->
<resultMap id="UserAndOrders2" type="User" >
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<collection property="orders" ofType="Orders">
<!--column为查询语句返回数据的字段名,重复的以别名区分-->
<id property="id" column="bid"/>
<result property="user_id" column="user_id"/>
<result property="order_no" column="order_no"/>
</collection>
</resultMap>
<select id="selectUserAndOrders2" parameterType="Integer" resultMap="UserAndOrders2">
select a.*,b.id 'bid',b.order_no from user a, orders b where a.id = #{id} and a.id = b.user_id
</select>
<!--一对多级联查询 第三种方法(pojo储存结果集)-->
<select id="selectUserAndOrders3" parameterType="Integer" resultType="UserAndOrders">
select a.*,b.id 'oid',b.order_no from user a, orders b where a.id = #{id} and a.id = b.user_id
</select>
将Mapper.xml注册到mybatis核心配置文件
<mapper resource="main/java/mybatis/mapper/OrdersMapper.xml"/>
- 在 UserController中编写逻辑代码,调用接口
//一对多级联查询
System.out.println("-----------一对多,嵌套查询----------");
User userToOrders1 = userDao.selectUserAndOrders1(1);
System.out.println(userToOrders1);
//一对多级联查询
System.out.println("-----------一对多,一条查询语句----------");
User userToOrders2 = userDao.selectUserAndOrders2(1);
System.out.println(userToOrders2);
//一对多级联查询
System.out.println("-----------一对多,pojo----------");
List<User> userToOrders3 = userDao.selectUserAndOrders3(1);
System.out.println(userToOrders3);
- TestController进行测试
public class TestController {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/main/java/mybatis/applicationContext.xml");
UserController userController = (UserController)applicationContext.getBean("userController");
userController.test();
}
}
2.6.3 多对多
多对多使用<resultMap>元素的子元素<collection property="" ofType="" >,同理一对多的第二种方法进行多对多级联。
mybatis没有多对多级联,而是通过中间表将两个一对多的关系进行级联,比如一个订单有多个产品,一个产品有多个订单,产品与订单形成了多对多的关系,通过一个订单记录表,订单记录表记录订单和产品的id信息,形成多对多关系。
- 实体类和关系表创建
orders_detail中间表
Product 类以及表结构
public class Product {
private Integer id;
private String name;
private Double price;
//一个产品中多个订单
private List<Orders> orders;
//省略
}
Orders 表以及结构
**
* @author xry
* 订单
*/
public class Orders {
private Integer id;
private Integer user_id;
private Integer order_no;
//一个订单中有多个产品
private List<Product> products;
//省略
}
- 在OrdesMapper.xml中添加多对多映射语句
<!--一对多级联-->
<resultMap id="OrdersAndProducts" type="Orders">
<id property="id" column="id"/>
<result property="user_id" column="user_id"/>
<result property="order_no" column="order_no"/>
<collection property="products" ofType="Product">
<id property="id" column="pid"/>
<result property="name" column="name"/>
<result property="price" column="price"/>
</collection>
</resultMap>
<!--多对多查询-->
<select id="selectOrdersAndProducts" resultMap="OrdersAndProducts">
select o.*,p.*,p.id 'pid' from orders o , orders_detail od,product p where o.id = od.orders_id and p.id = od.product_id
</select>
- 在OrdersDao中添加接口映射方法
/**
* @return
* 多对多级联查询
*/
public List<Orders> selectOrdersAndProducts();
- 在 UserController中编写逻辑代码,调用接口
//多对多级联查询
System.out.println("--------------多对多-----------------");
List<Orders> ordersAndProducts = ordersDao.selectOrdersAndProducts();
for (Orders result:ordersAndProducts){
System.out.println(result);
}
- . TestController进行测试以及结果
三、动态SQL
动态SQL主要有:
- <if>元素
- <choose> 、<when> 、<otherwise>元素
- <trim> 、<where>、<set>元素
- <bind>元素
3.1 if元素
<if>元素用在SQL语句where的一部分,if条件成立则根据name进行模糊查询,否则查询所有(单个if 不输入参数也可以查询所有,多个if则会报错)
<!--<if>元素-->
<select id="selectUserByIf" resultType="User" parameterType="String">
select * from user where 1=1
<if test="name !=null and name !=''">
and name like concat('%',#{name},'%')
</if>
</select>
3.2 choose元素
<choose>元素下有<when> 和<otherwise>元素,选择性的条件语句。
<!--<choose> <when> <otherwise> 元素-->
<select id="selectUserByChoose" resultType="User">
select * from user where 1=1
<choose>
<when test="name !=null and name !=''">
and name like concat('%',#{name},'%')
</when>
<otherwise>
and id > 10
</otherwise>
</choose>
</select>
3.3 trim元素
<trim>元素主要功能是在自己包含的内容前加上某些前缀。
- prefix添加前缀 ,
- prefixOverrides 首部内容覆盖,eg:and被覆盖
- suffix 添加后缀
- suffixOverrides 覆盖尾部内容
<!--<trim>元素-->
<select id="selectUserByTrim" resultType="User" parameterType="String">
select * from user
/*prefix添加前缀 , prefixOverrides 首部内容覆盖,eg:and覆盖为空,suffix="" suffixOverrides="" 后置。。*/
<trim prefix="where" prefixOverrides="and" suffix="" suffixOverrides="">
and name like concat('%',#{name},'%')
</trim>
</select>
3.4 where元素
<where>元素,不考虑条件的输出是什么样,所有条件都不满足则会查询所有记录,查询参数无论有无都能查询。自动忽略第一个条件语句中开头的 and 或者 or ,
<!--<where>元素-->
<select id="selectUserByWhere" parameterType="String" resultType="User">
select * from user
<where>
<if test="name !=null and name !=''">
and name like concat('%',#{name},'%')
</if>
</where>
</select>
3.5 set元素
<set>元素用于动态更新列。
<!--<set>元素 动态修改-->
<update id="updateUserBySet" parameterType="map">
update user
<set>
name = #{name}
</set>
where id = #{id}
</update>
3.6 foreach元素
<foreach>元素主要用于sql语句in后面,可以在SQL中迭代一个集合。
- item元素表示每一个元素进行迭代时的别名
- index元素表示指定一个名字,用于表示迭代过程中每次迭代到的位置
- open元素表示该语句以什么开始
- separator元素表示用什么符号作为分隔符
- close元素表示以什么结束
- collection元素,当入参为单个类型为List或者array,collection属性值为list或者array,当入参为多个且封装在map中,collection属性值为key
<!--<foreach>-->
<select id="selectUserByForeach" parameterType="List" resultType="User">
select * from user where id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
3.7 bind 元素
<bind >元素将模糊查询条件独立处理使用,好处是防止传统SQL的${}拼接字符串造成的SQL注入;或者是不同数据库之前拼接字符串的方法不同MySQL是concat函数,oracle连接符号"||"。
<!--使用bind元素进行模糊查询-->
<select id="selectUserByBind" resultType="User" parameterType="String">
<bind name="bind_name" value="'%'+ name + '%'"/>
select * from user where name like #{bind_name}
</select>