MySql如何实现批量操作

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种情况:

  1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
  2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
  3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个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>

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;
}

版权声明:本文为weixin_48052161原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。