5.执行非查询语句

来源:互联网 发布:比较好的网络穿越小说 编辑:程序博客网 时间:2024/05/21 15:39


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,memberSincefirstName, 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"><selectKeykeyProperty="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#)<selectKeykeyProperty="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$BEGINif (a > b) thenreturn a;elsereturn 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 functionMap 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) astemp integer;begintemp := 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 functionMap 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) asbeginif (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 functionMap 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
原创粉丝点击