MySql如何实现批量操作

导读:本篇文章讲解 MySql如何实现批量操作,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

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

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!