5.执行非查询语句


1. 更新数据的基本方法


1.1 用于非查询SQL语句的SqlMap API

insert 方法:


Object insert(String id, Object parameterObject)
throws SQLException;

返回Object对象

update方法


int update(String id, Object parameterObject)
throws SQLException;

返回受影响记录数


delete 方法

int delete(String id, Object parameterObject)
throws SQLException;

返回删除记录数


1.2 非查询已映射语句

下表为表4-3 一部分





2.1 使用内联参数映射


</pre><pre name="code" class="html"><insert id="insertWithInlineInfo">
insert into account (
accountId,
username, password,
memberSince,
firstName, lastName,
address1, address2,
city, state, postalCode,
country, version
) values (
#accountId:NUMBER#,
#username:VARCHAR#, #password:VARCHAR#,
#memberSince:TIMESTAMP#,
#firstName:VARCHAR#, #lastName:VARCHAR#,
#address1:VARCHAR#, #address2:VARCHAR#,
#city:VARCHAR#, #state:VARCHAR#, #postalCode:VARCHAR#,
#country:VARCHAR#, #version:NUMBER#
)
</insert>

执行
Account account = new Account();
account.setAccountId(new Integer(9999));
account.setUsername("inlineins");
account.setPassword("poohbear");
account.setFirstName("Inline");
account.setLastName("Example");
sqlMapClient.insert("Account.insertWithInlineInfo", account);

2.2 使用外部参数映射

<parameterMap id="fullParameterMapExample" class="Account">
<parameter property="accountId" jdbcType="NUMBER" />
<parameter property="username" jdbcType="VARCHAR" />
<parameter property="password" jdbcType="VARCHAR" />
<parameter property="memberSince" jdbcType="TIMESTAMP" />
<parameter property="firstName" jdbcType="VARCHAR" />
<parameter property="lastName" jdbcType="VARCHAR" />
<parameter property="address1" jdbcType="VARCHAR" />
<parameter property="address2" jdbcType="VARCHAR" />
<parameter property="city" jdbcType="VARCHAR" />
<parameter property="state" jdbcType="VARCHAR" />
<parameter property="postalCode" jdbcType="VARCHAR" />
<parameter property="country" jdbcType="VARCHAR" />
<parameter property="version" jdbcType="NUMBER" />
</parameterMap>

<insert id="insertWithExternalInfo"
parameterMap="fullParameterMapExample">
insert into account (
accountId,
username, password,
memberSince
firstName, lastName,
address1, address2,
city, state, postalCode,
country, version
) values (
?,?,?,?,?,?,?,?,?,?,?,?,?
)
</insert>


2.3 自动生成的键

如果将数据库设计为使用自动生成的主键,就可以使用ibatis的<selectKey>元素(<insert>元素一个专用子元素)来获取这些自动生成的主键的值并将其保存在对象中


方式1:把记录插入到数据库中并且数据库为该记录自动生成主键之后,就立刻抓取该键值。
必须确保数据库驱动确实能返回你执行上一条insert语句所得到的键值。

方式2: 在插入记录之前就获取键值。

对此两种方式,ibatis都可以帮助轻松的完成任务。<selectKey>元素使得这个任务对应用程序完全透明。


insert 方法返回一个Object对象的原因:使你能够得到所生成的键值。


<insert id="insert">
<selectKey
keyProperty="accountId"
resultClass="int">
SELECT nextVal('account_accountid_seq')
</selectKey>
INSERT INTO Account (
accountId, username, password
) VALUES(
#accountId#, #username#, #password#)
</insert>

Integer returnValue = (Integer) sqlMap.insert(
"Account.insert", account);

<selectKey>元素其实也定义一个已映射语句,并且该已映射语句可以访问的参数映射与包含该已映射语句的insert语句相同。
<insert id="insertSequence">
<selectKey keyProperty="accountId" resultClass="int">
SELECT nextVal(#sequence#)
</selectKey>
INSERT INTO Account (
accountId, username, password
) VALUES(
#accountId#, #username#, #password#)
</insert>

如果使用Microsoft SQL Server

<insert id="insert">
INSERT INTO Account (
username, password
) VALUES(
#username#, #password#)
<selectKey
keyProperty="accountId"
resultClass="int">
SELECT SCOPE_IDENTITY()
</selectKey>
</insert>

3. 更新和删除数据


3.1 处理并发更新


ibatis没有实现的功能:为记录提供某种形式的锁。

可是使用若干技术来处理并发更新:时间戳或者为数据库表中的每条记录加一个版本号。

CREATE TABLE account (
accountid serial NOT NULL,
username varchar(10),
passwd varchar(10),
firstname varchar(30),
lastname varchar(30),
address1 varchar(30),
address2 varchar(30),
city varchar(30),
state varchar(5),
postalcode varchar(10),
country varchar(5),
version int8,
CONSTRAINT account_pkey PRIMARY KEY (accountid)
)

同时使用accountId字段和version字段。 根据返回值判断

3.2 更新或删除子记录

在应用程序的数据层处理对象关系

	public void saveOrder(SqlMapClient sqlMapClient, Order order) throws SQLException {
		if (null == order.getOrderId()) {
			sqlMapClient.insert("Order.insert", order);
		} else {
			sqlMapClient.update("Order.update", order);
		}
		sqlMapClient.delete("Order.deleteDetails", order);
		for (int i = 0; i < order.getOrderItems().size(); i++) {
			OrderItem oi = (OrderItem) order.getOrderItems().get(i);
			oi.setOrderId(order.getOrderId());
			sqlMapClient.insert("OrderItem.insert", oi);
		}
	}

没有提供任何形式的事务隔离。


4. 运行批量更新


	public void saveOrder(SqlMapClient sqlMapClient, Order order) throws SQLException {
		sqlMapClient.startTransaction();<span style="white-space:pre">					</span>//打包为事务
		try {
			if (null == order.getOrderId()) {
				sqlMapClient.insert("Order.insert", order);
			} else {
				sqlMapClient.update("Order.update", order);
			}
			sqlMapClient.startBatch();<span style="white-space:pre">					</span>///批处理
			sqlMapClient.delete("Order.deleteDetails", order);
			for (int i = 0; i < order.getOrderItems().size(); i++) {
				OrderItem oi = (OrderItem) order.getOrderItems().get(i);
				oi.setOrderId(order.getOrderId());
				sqlMapClient.insert("OrderItem.insert", oi);
			}
			sqlMapClient.executeBatch();<span style="white-space:pre">					</span>///
			sqlMapClient.commitTransaction();<span style="white-space:pre">				</span>//
		} finally {
			sqlMapClient.endTransaction();
		}
	}


如果使用selectKey语句来更新所插入对象的系统生成键, 那么他们将为所生成的键返回空值

5. 使用存储过程


5.1 优缺点分析


1.千万不要走极端

2.使用恰当的工具来工作


5.2 IN、OUT和INOUT参数

CREATE OR REPLACE FUNCTION max_in_example
(a float4, b float4)
RETURNS float4 AS
$BODY$
BEGIN
if (a > b) then
return a;
else
return b;
end if;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;


以下是使用这个存储过程的参数映射、已映射语句及Java代码
<parameterMap id="pm_in_example" class="java.util.Map">
<parameter property="a" />
<parameter property="b" />
</parameterMap>

<procedure id="in_example" parameterMap="pm_in_example"
resultClass="int" >
{ call max_in_example(?, ?) }
</procedure>
// Call a max function
Map m = new HashMap(2);
m.put("a", new Integer(7));
m.put("b", new Integer(5));
Integer val =
(Integer)sqlMap.queryForObject("Account.in_example", m);


in out
 
create procedure swap(a in out integer, b in out integer) as
temp integer;
begin
temp := a;
a := b;
b := temp;
end;
以下是使用这个存储过程的参数映射、已映射语句及Java代码

<parameterMap id="swapProcedureMap" class="java.util.Map">
<parameter property="a" mode="INOUT" />
<parameter property="b" mode="INOUT" />
</parameterMap>
<procedure id="swapProcedure" parameterMap="swapProcedureMap">
{ call swap(?, ?) }
</procedure>

// Call swap function
Map m = new HashMap(2);
m.put("a", new Integer(7));
m.put("b", new Integer(5));
Integer val =
(Integer) sqlMap.queryForObject("Account.in_example", m);

out(Oracle PL/SQ L)

create or replace procedure maximum
(a in integer, b in integer, c out integer) as
begin
if (a > b) then c := a; end if;
if (b >= a) then c := b; end if;
end;
以下是使用这个存储过程的参数映射、已映射语句及Java代码
<parameterMap id="maxOutProcedureMap" class="java.util.Map">
<parameter property="a" mode="IN" />
<parameter property="b" mode="IN" />
<parameter property="c" mode="OUT" />
</parameterMap>
<procedure id="maxOutProcedure"
parameterMap="maxOutProcedureMap">
{ call maximum (?, ?, ?) }
</procedure>
// Call maximum function
Map m = new HashMap(2);
m.put("a", new Integer(7));
m.put("b", new Integer(5));
sqlMap.queryForObject("Account.maxOutProcedure", m);
// m.get("c") should be 7 now.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值