Ibatis怎么做ibatis 批量更新 list

ibatis之批量操作实例
public void batchUpdateExec(String sqlId, List&Object& param) throws DaoException {
if (sqlId != null && sqlId.length() & 0) {
if (param != null && param.size() & 0) {
this.getSqlMapClient().startBatch();
for (int i = 0; i & param.size(); i++) {
this.getSqlMapClient().update(sqlId, param.get(i));
this.getSqlMapClient().executeBatch();
} catch (SQLException e) {
throw new DaoException(e);Ibatis怎么做批量更新?????_百度知道
Ibatis怎么做批量更新?????
提问者采纳
这些明白; 执行批处理 /div class=& /);quote_div&key3'&#47.insert(&startBatch() 开始批处理 &#47.)PS;
} /public void create(List&amp,这样的好处能说下吗,差别就是加了startBatch() &code&quot, &#47.startBatch();quote_title& /span style=&quot:
&#47.executeBatch();首先不加这两个;startBatch() 开始批处理 /比如;
sqlMapC &#47.printStackTrace(); /makemyownlife 写道&div /value' /div class=& 执行批处理sqlMapC
} catch (Exception e) { / sqlMapClient, reply):
&#47,少量数据可以用循环来执行; &#47.executeBatch();Reply& / /key2' replyList) { &#47,在ibatis中是怎么优化的;,红色部分也可以正常执行批量插入?问题补充;R 开始批处理sqlMapC public void create(List& class=& /) ;
&#47.executeBatch();}}&VALUES (&#39:只是单独的ibatis项目; /iBatis2通过SqlMapClient提供了一组方法用于批处理实现.create&;/INSERT INTO t (t;&#47.printStackTrace();e;
e上面的解析成sql就是update Question? where questionId in(1;/div&&#47,5,放到同一个session中吗;; &#47:&lt,真正是否能够一次性批量操作;div /
&div class=&&#47,4; } &#47: replyList) {/ &#47.;div &#47,不和spring集成;key1' 插入操作 /quote_title&
try { /pre name=&quot?, reply). /
/,'xecuteBatch() 执行批处理 / 插入操作sqlMapClt, (' replyList) {try {&#47??问题补充..startBatch();key1'value2'span /
sqlMapCquote_div&quot,&lt,要看你的数据库类型;/
}&&#47:&lt?问题补充;rensanning 写道&&#47? set status = &quot?; 一次插入多条数据; 开始批处理 &#47: /pre&quote_div&quot: replyList) { /&lt.; &#47.c)
&#47.create& &#47,'ibatis只是对JDBC的封装;div class=&for (R/ /&quote_title&java&quot.: /div&div class=&div&xecuteBatch() 执行批处理 / /
&#47.b;;OK&&#47,如果是大量数据;; &#47,&#39: red&}/
sqlMapC&lt,2?:&lt?;Reply.a;lt,&#39,;makemyownlife 写道&for (Reply reply,3;iBatis2通过SqlMapClient提供了一组方法用于批处理实现;/div class=&/.insert(&Reply&&#47! &#47
采纳率100%
上面的解析成sql就是
update Question
其他类似问题
为您推荐:
ibatis的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁23:32 提问
sql 批量更新
一个(还有多个选项的)字段
一个学生表,一个状态表
学生表里面有个字段是学生奖项(1,2,3) 对应的奖项名称是状态表里面的内容。
主要内容:
是通过学生的id(批量)修改奖项(awards)这个字段,每个青年的奖项可能不同(如:A学生有:2,3。B学生有:3,4)。奖项也是含有多个值的(如1,2,3,4,5。。)
现在要去掉其中一个奖项,或者增加一个奖项。
sql语句要如何写?用ibatis如何操作。
按赞数排序
下面是对SQL Server的,如果是其他数据库,可以使用MID函数替换SUBSTRING函数。
如果你需要关联其他的表,在语句中加入FROM来设置关联关系。
如果你不需要限制学生ID,可以在WHERE里面移除
更新和删除语句都会先判断是否有需要更新和删除的奖项
添加语句会先判断是否已经包含了需要添加的奖项
更新奖项如下
DECLARE @P NVARCHAR(50)
DECLARE @P1 NVARCHAR(50)
DECLARE @ID INT
SET @P = '1'
SET @P1 = '90'
SET @ID = 1
UPDATE 学生表 T
SET T.[awards] = SUBSTRING(REPLACE(',' + T.[awards] + ',', ',' + @P + ',', ',' + @P1 + ','), 2, LEN(T.[awards]) - LEN(@P) + LEN(@P1))
WHERE ',' + T.[awards] + ',' LIKE
'%,' + @P + ',%'
AND T.[id] = @ID
添加奖项如下
DECLARE @P NVARCHAR(50)
DECLARE @ID INT
SET @P = '90'
SET @ID = 1
UPDATE 学生表 T
SET T.[awards] = T.[awards] + ',' + @P
WHERE ',' + T.[awards] + ',' NOT LIKE
'%,' + @P + ',%'
AND T.[id] = @ID
DECLARE @P NVARCHAR(50)
DECLARE @ID INT
SET @P = '2'
SET @ID = 1
SET T.[awards] = SUBSTRING(REPLACE(',' + T.[awards] + ',', ',' + @P + ',', ','), 2, LEN(T.[awards]) - LEN(@P) - CASE WHEN T.[awards] = @P THEN 0 ELSE 1 END)
WHERE ',' + T.[awards] + ',' LIKE
'%,' + @P + ',%'
AND T.[id] = @ID
可以使用事务实现批量处理,自己google下
什么数据库,一般数据库有replace,可以用replace进行字符串替换。
添加直接用拼接函数就行,拼接上新增的奖项,如果是删除那就直接用替换函数替换掉删除的奖项,删除注意下,号的处理就行了吧
其他相似问题iBatis执行非查询语句(CRUD,函数和过程) - Stop here ! - ITeye技术网站
博客分类:
&&& CRUD操作中除了查询操作,其他都统一称为更新操作,因为增删改都是更新数据库表的,SqlMap API中对应的方法就是insert,update和delete,我们逐一来看。
&&& insert方法的方法签名为:Object insert(String id, String parameterObject) throws SQLException。那么我们需要传递的参数就是XML文件中的映射语句名称和执行插入操作所需要的参数。返回值为Object类型,也就是说它可以返回一个对象。我们想想通过插入语句我们希望得到什么呢?没错,就是插入这条记录的主键。
&&& 这里还不得不多说一下主键的问题。虽然每种数据库都有自己主键的生成方式,但对于这种将数据插入到数据库后立即要知道主键的情况,就会产生问题。iBatis中的insert元素的一个子元素selectKey可以帮助我们获取自动生成的主键并保存在返回对象中,它有两种调用方式:
&&& 第一就是数据插入到数据库中之后立即抓取这条记录的主键的值,但此时要注意抓取的值确实是刚插入的记录的,也就是说数据库的驱动支持这么操作。如果有两个线程同时执行insert操作,其可能的顺序为insert #1,insert #2,selectKey #1,selectKey #2,那么在执行selectKey #1时得到的就是第二个记录的主键值了,这显然对程序产生了影响。
&&& 第二种方式就是在插入记录之前就获取键,然后连同这个键一同插入到数据库中,这样就不存在第一种情况的风险,是安全的操作。这种方式更倾向于支持序列的数据库。
&&& 在MySQL数据库中没有序列的支持,那么可以使用LAST_INSERT_ID()函数来获取自动生成的主键,我们来一段代码:
&insert id="addUser" parameterClass="parameterMap" &
insert into users(USERNAME,PASSWORD,AGE,MOBILE,EMAIL)
values(#userName:VARCHAR#,#password:VARCHAR#,#age:INT#,#mobile:VARCHAR#,#email:VARCHAR#)
&selectKey keyProperty="userId" resultClass="int"&
select LAST_INSERT_ID()
&/selectKey&
&&& 向数据库中插入一条记录同时获取了其生成的主键值,主键字段是userId,类型是int这都很好理解。而在程序中,我们只需这么来操作:
ParameterMap parameterMap = new ParameterMap("userName", "sarin",
"password", "123", "age", "23", "mobile", "1", "email", "@");
Object obj = sqlMap.insert("User.addUser", parameterMap);
System.out.println(obj);
&&& 打印出的就是主键的值了,这个示例不但演示了iBatis的插入操作,也演示了插入操作同时获取主键值的方法,当然在Oracle中使用序列就行了,SQL Server是使用SCOPE_IDENTITY()函数,这参考一下数据库文档即可。
&&& 上面我们在执行更新操作时传递的参数是我们写好的ParameterMap类型,即:
package ibatis.
import java.util.HashM
public class ParameterMap extends HashMap&Object, Object& {
private static final long serialVersionUID = 1L;
public ParameterMap(Object... parameters) {
for (int i = 0; i & parameters.length - 1; i += 2) {
super.put(parameters[i], parameters[i + 1]);
&&& 这是内联参数映射的一种,当然我们也可以使用Javabean作为参数传递的对象,来看一个示例:
User user = new User(null, "sarin", "123", "", "@", 23);
Object obj = sqlMap.insert("User.addUser", user);
System.out.println(obj);
&&& 这样使用的前提是在User类中重载一个构造方法来传递属性的值,当然默认的构造方法也要有(当你调用了queryForObject()方法时)。另外一种是外部参数映射,我们定义一个parameterMap来测试这种情况:
&parameterMap class="ibatis.util.User" id="userPramaterMap"&
&parameter property="userName" jdbcType="VARCHAR" /&
&parameter property="password" jdbcType="VARCHAR" /&
&parameter property="age" jdbcType="INT" /&
&parameter property="mobile" jdbcType="VARCHAR" /&
&parameter property="email" jdbcType="VARCHAR" /&
&/parameterMap&
&&& 自动生成的主键userId这里我们就不用写了,然后定义插入语句的映射:
&insert id="addUserUseParameterMap" parameterMap="userPramaterMap"&
insert into
users(USERNAME,PASSWORD,AGE,MOBILE,EMAIL)
values(?,?,?,?,?)
&selectKey keyProperty="userId" resultClass="int"&
select LAST_INSERT_ID()
&/selectKey&
&&& 最后在程序中,则和上面内联参数没有什么不同,除了映射的语句名称:
User user = new User(null, "sarin", "123", "", "@", 23);
Object obj = sqlMap.insert("User.addUserUseParameterMap", user);
System.out.println(obj);
&&& 更新操作的第二种是update,SqlMap API中更新操作的方法签名是int update(String id, Object parameterObject) throws SQLException,参数的含义都已经非常清楚了,就是映射的语句名称和参数,而返回值是int型的。在JDBC规范中我们知道更新操作返回的是影响的结果行数,其实insert也是,只不过SqlMap给我们了新的选择。
&&& 要注意的一点是iBatis允许在一条SQL语句中更新一条或多条记录,而其他面向对象的工具是只允许修改一条记录(比如Hibernate),但Hibernate针对批量操作也做了处理。
&&& 说到批量操作,就会有并发的问题,那么事务机制很自然就要想到了,这里简单介绍一下iBatis处理批量操作的方法,后面会有详细介绍iBatis的事务。这里给出一个处理并发的小技巧,就是在高并发的数据表中加一个时间戳字段或者是版本字段控制,每次更新操作都修改这个字段,就能一定程度上控制数据完整性。
&&& 由于iBatis是SQL映射工具,那么就不需要像使用Hibernate那样考虑对象间的关系,在程序中做好处理就行了。先看下面这个示例:购物车订单,这是很经典的示例,我们需要建立两个类(订单和订单项),两个SQL映射文件和一个测试类。数据库表结构如下:
&&& 这是订单表,简单做示例,就订单名称和生成订单的时间两项即可。
&&& 这是订单项表,字段见名知意,这里就不多解释了。下面来看看实体类的设计:
package ibatis.
import java.util.D
import java.util.L
public class Order implements java.io.Serializable {
private Integer orderId;
private String orderN
private java.util.Date generateT
private List&OrderItem& orderI
public Order() {
public Order(Integer orderId, String orderName, Date generateTime,
List&OrderItem& orderItems) {
this.orderId = orderId;
this.orderName = orderN
this.generateTime = generateT
this.orderItems = orderI
// 省略getter和setter方法
public String toString() {
return "Order [generateTime=" + generateTime + ", orderId=" + orderId+ ", orderItems=" + orderItems + ", orderName=" + orderName+ "]";
&&& 下面是订单项的实体类,也很简单:
package ibatis.
public class OrderItem implements java.io.Serializable {
private Integer oderItemId;
private String itemN
private Integer orderId;
public OrderItem() {
public OrderItem(Integer oderItemId, String itemName, int quantity,
float price, Integer orderId) {
this.oderItemId = oderItemId;
this.itemName = itemN
this.quantity =
this.price =
this.orderId = orderId;
// 省略getter和setter方法
public String toString() {
return "OrderItem [itemName=" + itemName + ", oderItemId=" + oderItemId+ ", orderId=" + orderId + ", price=" + price + ", quantity="
+ quantity + "]";
&&& 虽然iBatis是SQL映射,但是实体类中我们使用对象类型而不是基本数据类型还是有很多好处的,比如直接和null判断。下面我们来看SQL映射文件,其中使用了简单的动态SQL,这个后面会详细来说明。
&sqlMap namespace="Order"&
&typeAlias alias="Order" type="ibatis.model.Order" /&
&insert id="insert" parameterClass="Order"&
insert into
orders(orderName,generateTime)
(#orderName:VARCHAR#,now())
&selectKey keyProperty="orderId" resultClass="int"&
select LAST_INSERT_ID()
&/selectKey&
&update id="update" parameterClass="Order"&
&isNotEmpty property="orderName"&
orderName=#orderName:VARCHAR#
&/isNotEmpty&
&/dynamic&
orderId=#orderId:INT#
&delete id="deleteDetails" parameterClass="Order"&
delete from
orderitems
orderId=#orderId:INT#
&&& 分析一下这个配置,首先定义了Order类型,在文件中可以直接使用。然后就是SQL语句了,有添加,更新和删除操作,其中删除是删除所有的订单项,插入操作后返回自动生成的主键,这个在前面已经说明了,很好理解。那么订单项的配置文件就更简单了:
&sqlMap namespace="OrderItem"&
&typeAlias alias="OrderItem" type="ibatis.model.OrderItem" /&
&insert id="insert" parameterClass="OrderItem"&
insert into
orderitems(itemName,quantity,price,orderId)
(#itemName:VARCHAR#,#quantity:INT#,#price:FLOAT#,#orderId:INT#)
&&& 只有一个添加语句做示例。最后不要忘了在SqlMapConfig中引入这两个配置文件,下面来看看测试类:
// 省略包引入语句
public class OrderDemo {
private static String config = "ibatis/SqlMapConfig.xml";
private static R
private static SqlMapClient sqlM
reader = Resources.getResourceAsReader(config);
} catch (IOException e) {
e.printStackTrace();
sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
public static void main(String[] args) throws SQLException{
OrderItem item1 = new OrderItem(null, "IBM THINKPAD T410", 1, 10000, null);
OrderItem item2 = new OrderItem(null, "HP 6930P", 1, 7000, null);
OrderItem item3 = new OrderItem(null, "APPLE MC024", 1, 16000, null);
// 创建OrderItem对象集合,放入三个购物项
List&OrderItem& orderItems = new ArrayList&OrderItem&();
orderItems.add(item1);
orderItems.add(item2);
orderItems.add(item3);
Order order = new Order(null, "Sarin's Order", null, orderItems);
saveOrder(sqlMap, order);
public static void saveOrder(SqlMapClient sqlMap, Order order)
throws SQLException {
// 判断是插入订单还是更新
if (null == order.getOrderId()) {
sqlMap.insert("Order.insert", order);
sqlMap.update("Order.update", order);
// 清除订单原有信息
sqlMap.delete("Order.deleteDetails", order);
// 插入订单项目
for (int i = 0; i & order.getOrderItems().size(); i++) {
OrderItem oi = order.getOrderItems().get(i);
oi.setOrderId(order.getOrderId());
sqlMap.insert("OrderItem.insert", oi);
&&& 代码能为我们完成任务,但是可以看出,这里没有任何的事务隔离,如果循环插入时发生了异常,那么数据完整性将遭到破坏。这是因为此时的事务是在每条语句执行时提交的,这也会影响程序的执行性能。做如下测试,修改main函数为:
public static void main(String[] args) throws SQLException {
long start = System.currentTimeMillis();
// 中间执行代码
long end = System.currentTimeMillis();
System.out.println(end - start);
&&& 一次测试时间是494,而如果:
public static void main(String[] args) throws SQLException,IOException {
long start = System.currentTimeMillis();
String config = "ibatis/SqlMapConfig.xml";
Reader reader= Resources.getResourceAsReader(config);
SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
// 中间执行代码
long end = System.currentTimeMillis();
System.out.println(end - start);
&&& 执行时间可达到874,所以性能是很低的。下面我们来看看批量更新操作,将saveOrder()方法做如下修改:
public static void saveOrder(SqlMapClient sqlMap, Order order)
throws SQLException {
// 开启事务
sqlMap.startTransaction();
// 判断是插入订单还是更新
if (null == order.getOrderId()) {
sqlMap.insert("Order.insert", order);
sqlMap.update("Order.update", order);
// 开始批量操作
sqlMap.startBatch();
// 清除订单原有信息
sqlMap.delete("Order.deleteDetails", order);
// 插入订单项目
for (int i = 0; i & order.getOrderItems().size(); i++) {
OrderItem oi = order.getOrderItems().get(i);
oi.setOrderId(order.getOrderId());
sqlMap.insert("OrderItem.insert", oi);
sqlMap.executeBatch();
mitTransaction();
} finally {
sqlMap.endTransaction();
&&& 测试出的运行时间是432,确实效率提高了,因为数据量小,不是很明显。这里要注意批量操作的开始地方,因为后面的OrderItem使用到了Order的主键,而这个主键是数据库自动生成的,那么我们必须获取到这个主键才能执行批量那个操作。而在executeBatch()执行时才会执行SQL操作,如果开始批量的位置不对,则不能获取到创建的主键的值,那么后面的操作也不能被执行了。
&&& 最后就是存储过程了,这里给出一个简单的示例:在存储过程中删除订单详细项,一个比较奇怪的地方就是iBatis调用mysql的存储过程要使用insert()方法,这里并不知道其原因。首先我们定义一个存储过程:
&&& 在SQL配置中,我们定义一个存储过程和映射参数类型:
&parameterMap class="java.util.Map" id="pm_delOiByOId"&
&parameter property="orderId"/&
&/parameterMap&
&procedure id="deleteOrderitemsByOrderId" parameterMap="pm_delOiByOId" resultClass="int"&
call delete_orderitems_by_orderid(?)
&/procedure&
&&& 程序中,使用insert()方法调用存储过程,比如:
Map m = new HashMap();
m.put("orderId", 3);
sqlMap.queryForObject("Order.deleteOrderitemsByOrderId", m);
&&& 除了存储过程,还有函数,我们也来看个示例:
CREATE DEFINER = `root`@`localhost` FUNCTION `max_in_example`(`a` int,`b` int)
RETURNS int(10)
if(a & b) then
&&& 这是MySQL的一个函数定义,在SQL映射文件中,必须使用select来标记,而不是procedure,这个要记住。
&parameterMap class="java.util.Map" id="pm_in_example"&
&parameter property="a"/&
&parameter property="b"/&
&/parameterMap&
&select id="in_example" parameterMap="pm_in_example" resultClass="int"&
select max_in_example(?,?)
&&& 程序中,这样写就行了:
Map m = new HashMap(2);
m.put("a", new Integer(7));
m.put("b", new Integer(5));
Integer val = (Integer) sqlMap.queryForObject("User.in_example", m);
System.out.println(val);
&&& 打印的结果就是7。至此iBatis的非查询语句就介绍完了。
下载次数: 70
关于ibats更新update的书写方式,个人愚见:为什么非得要“&isNotEmpty&”才能更新字段呢?有这样一种情况,用户之前在备注字段写了一些信息,现在想把备注字段清空,那就没法实现了。那是动态SQL的一部分,用于判断字段逻辑而进行最终SQL的动态拼装
浏览: 1274615 次
来自: 大连
浏览量:116826
浏览量:279018
浏览量:128171
浏览量:56683
可以参考最新的文档:如何在eclipse jee中检出项目并转 ...
spring mvc demo教程源代码下载,地址:http: ...
看帖回复是美德,楼主讲的很清晰明了,看了豁然开朗.
&div class=&quote_title ...
不错,不错}

我要回帖

更多关于 ibatis 批量删除 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信