• Mybatis 针对ORACLE和MYSQL的批量插入与多参数批量删除


      今天利用Mybatis的<for each>标签做oracle的批量插入数据时,发现和MySQL数据库有区别。在此记录下,以防之后再踩坑。

    一、批量插入:

    1.controller:

    /**
         * batchSaveAccountRole 批量给角色添加用户
         *
         * @param role
         * @return R返回类型
         */
        @RequestMapping(value = "/batchSaveAccountRole", method = RequestMethod.PUT)
        @ResponseBody
        public R batchSaveAccountRole(@RequestBody List<RoleAccount> roleAccountList) {
            R r = R.ok();
            if (roleAccountList != null) {
                int row = roleService.batchSaveAccountRole(roleAccountList);
                r = R.ok(row + "");
            }
            return r;
        }
    

    2.service:

    public int batchSaveAccountRole(List<RoleAccount> roleAccountList) {
    		return roleDao.batchSaveAccount2Role(roleAccountList);
    }
    

    3.dao:

    int batchSaveAccount2Role(List<RoleAccount> roleAccountList);
    

    4.mapper(Oracle):

    <insert id="batchSaveAccount2Role" parameterType="java.util.List">
         	INSERT INTO SYSTEM_ACCOUNT_ROLES (role_id, account_id)
         	<foreach close=")" collection="list" item="item" open="(" separator="union all">
    			select
    			#{item.roleId},#{item.accountId}
    			from dual
    	</foreach> 
    </insert>
    

      在Oracle的版本中,有几点需要注意的:

      1.SQL中没有VALUES;

     

      2.<foreach>标签中的(selece ..... from dual);

     

      3.<foreach>标签中的separator的属性为"UNION ALL",将查询合并结果集。

     

    5.mapper(MySQL):

    <insert id="batchSaveAccount2Role" parameterType="java.util.List">
         	INSERT INTO SYSTEM_ACCOUNT_ROLES (role_id, account_id) values
         	<foreach collection="list" item="item" separator=",">
    		(#{item.roleId},#{item.accountId})
    	</foreach> 
    </insert>
    

    二、批量删除:

    1.controller:

     /**
         * 根据角色批量删除用户
         *
         * @param ids 唯一ID列表
         * @return R 返回类型
         */
        @RequestMapping(value = "/batchDeleteAccount2Role", method = RequestMethod.PUT)
        @ResponseBody
        @GeckoAuthority(codes = {"GECKO_SYSTEM_ROLES_DELETE"})
        public R batchDeleteAccount2Role(@RequestBody List<RoleAccount> roleAccountList) {
        	 R r = R.ok();
             if (roleAccountList != null) {
                 int row = roleService.batchDeleteAccount2Role(roleAccountList);
                 r = R.ok(row + "");
             }
             return r;
        }
    

    2.service:

    public int batchDeleteAccount2Role(List<RoleAccount> roleAccountList) {
    		String roleId = roleAccountList.get(0).getRoleId();
    		return roleDao.batchDeleteAccount2Role(roleId,roleAccountList);
    }
    

    3.dao:

    int batchDeleteAccount2Role(@Param("roleId")String roleId, @Param("list")List<RoleAccount> roleAccountList);
    

    4.mapper:

    <delete id="batchDeleteAccount2Role">
         	delete from SYSTEM_ACCOUNT_ROLES where role_id =  #{roleId} and account_id IN
            <foreach collection="list" item="item" open="(" close=")" separator=",">
                #{item.accountId}
            </foreach> 
    </delete>
    

    三、总结:

     1.<for each> 标签的属性:

    属性 描述
    item 循环体中的具体对象。支持属性的点路径访问,如item.age,item.info.details。
    具体说明:在list和数组中是其中的对象,在map中是value。
    该参数为必选。
    collection

    要做foreach的对象,作为入参时,List<?>对象默认用list代替作为键,数组对象有array代替作为键,Map对象没有默认的键。
    当然在作为入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:
    如果User有属性List ids。入参是User对象,那么这个collection = "ids"
    如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = "ids.id"
    上面只是举例,具体collection等于什么,就看你想对那个元素做循环。
    该参数为必选。

    separator 元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
    open foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选。
    close foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
    index 在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。

    2.Oracle dual表的使用:

    dual表是一个虚拟表,用来和select语句一起使用。
    1、查看当前用户
    select  user from dual
    2、用来调用系统函数
    select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual ----得到当前系统时间

    select SYS_CONTEXT('USERENV','TERMINAL') from dual;--获得主机名

    select SYS_CONTEXT('USERENV','language') from dual;--获得当前locale

    select dbms_random.random from dual;--获得一个随机数

    3、得到序列的下一个值或当前值,用下面语句

    select your_sequence.nextval from dual;--获得序列your_sequence的下一个值

    select your_sequence.currval from dual;--获得序列your_sequence的当前值

    4、可以用做计算器

    select 7*9 from dual;

    5、查空值
    select  null extattrid,null extattrname from dual union all select  extattrid,extattrname from VExtAttrDetail where extattrsn in (22)

     详见:http://www.cnblogs.com/qiangqiang/archive/2010/10/15/1852229.html
     
    
    
    
    
    
  • 相关阅读:
    Debian下修改/etc/fstab出错致系统无法启动修正
    三种管理方法[书摘]
    Windows Phone & Windows 8 Push Notification from Windows Azure
    Windows Phone 8 如何在内存与硬件受限的设备上开发
    Windows Phone 8 获取与监听网络连接状态
    Windows Phone 处理 MessageBox导致的应用异常退出以及使用代码方式退出应用
    Windows store 应用调用 SharePoint Service
    嵌入式成长轨迹61 【智能家居项目】【ARM 飞凌ok6410】【在虚拟机Ubuntu下NFS网络文件系统建立】
    嵌入式成长轨迹65 【智能家居项目】【ARM 飞凌ok6410】【飞凌开发板——SD卡一键烧写】
    嵌入式成长轨迹63 【智能家居项目】【ARM 飞凌ok6410】【ARM QT 移植环境搭建问题集锦】
  • 原文地址:https://www.cnblogs.com/liuyk-code/p/7874497.html
Copyright © 2020-2023  润新知