Mybatis的foreach,遍历参数列表执行相应的操作
一. 配置
首先,mysql需要数据库连接配置&allowMultiQueries=true
jdbc.url=jdbc:mysql://mbp-mysql-xm01:5002/xmppsc?autoReconnect=true&useUnicode=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
二. foreach
foreach的主要作用是在构建in条件中,它可以在SQL语句中进行迭代一个集合。
foreach元素的属性主要有:collection,index,item,open,separator和close,意义如下:
在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有一下3种情况:
- 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
- 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
- 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在breast里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
三. 批量操作
1)批量插入
int insertObjects(Integer roleId,Integer[] menuIds);
<insert id="insertObjects">
insert into sys_role_menus
(role_id,menu_id)
values <!-- (1,2),(1,3),(1,4) -->
<foreach collection="menuIds" separator="," item="menuId">
(#{roleId},#{menuId})
</foreach>
</insert>
若传参为String,可以通过.split(‘,’)
<foreach collection="tags.split(',')" item="tag" open="(" separator="," close=")">
#{tag}
</foreach>
2)批量更新
@Update("update msg_inbox set latest=0 where (pub_uid,user_uid) in " +
"<foreach collection='items' index='index' item='item' open='((' separator='),(' close='))'>" +
"#{item.pub_uid},#{item.user_uid}" +
"</foreach> and latest=1")
void clearSessions(@Param("items")List<MsgInbox> items);
3)批量删除
int deleteObjects(Integer...ids);
<delete id="deleteObjects">
delete from sys_logs
<where>
<choose>
<when test="ids!=null and ids.length>0">
id in
<foreach collection="ids" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</when>
<otherwise>
or 1=2
</otherwise>
</choose>
</where>
</delete>
4)批量查询
List<SysUserMenu> findUserMenus(List<Integer> menuIds);
基于菜单id获取一级菜单和二级菜单
resultMap
<resultMap id="sysUserMenu" type="com.cy.pj.sys.pojo.SysUserMenu">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="url" column="url"/>
<collection property="childs"
ofType="com.cy.pj.sys.pojo.SysUserMenu">
<id property="id" column="cid"/>
<result property="name" column="cname"/>
<result property="url" column="curl"/>
</collection>
</resultMap>
<!-- 基于菜单id获取一级菜单和二级菜单 -->
<select id="findUserMenus" resultMap="sysUserMenu">
select p.id,p.name,p.url,c.id cid,c.name cname,c.url curl
from sys_menus p left join sys_menus c
on c.parentId=p.id
where p.parentId is null and c.id in
<foreach collection="menuIds" open="(" close=")"
separator="," item="menuId">
#{menuId}
</foreach>
</select>
工具类
数据库的原生操作会封装成一个工具类,SQLServer中有SQLHelper,
Mysql中也有MySQLHelper,批量操作也可以放到MySQLHelper中,实现效果一样。
/// <summary>
///大批量数据插入,返回成功插入行数
/// </summary>
/// <param name="connectionString">数据库连接字符串</param>
/// <param name="table">数据表</param>
/// <returns>返回成功插入行数</returns>
public static int BulkInsert(string connectionString, DataTable table)
{
if (string.IsNullOrEmpty(table.TableName)) throw new Exception("请给DataTable的TableName属性附上表名称");
if (table.Rows.Count == 0) return 0;
int insertCount = 0;
string tmpPath = Path.GetTempFileName();
string csv = DataTableToCsv(table);
File.WriteAllText(tmpPath, csv);
using (MySqlConnection conn = new MySqlConnection(connectionString))
{
MySqlTransaction tran = null;
try
{
conn.Open();
tran = conn.BeginTransaction();
MySqlBulkLoader bulk = new MySqlBulkLoader(conn)
{
FieldTerminator = ",",
FieldQuotationCharacter = '"',
EscapeCharacter = '"',
LineTerminator = "\r\n",
FileName = tmpPath,
NumberOfLinesToSkip = 0,
TableName = table.TableName,
};
bulk.Columns.AddRange(table.Columns.Cast<DataColumn>().Select(colum => colum.ColumnName).ToList());
insertCount = bulk.Load();
tran.Commit();
}
catch (MySqlException ex)
{
if (tran != null) tran.Rollback();
throw ex;
}
}
File.Delete(tmpPath);
return insertCount;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/106538.html