s2dao是基于seasar2的orm框架,使用簡(jiǎn)單且功能比較強(qiáng)大。官方網(wǎng)站為http://s2dao.seasar.org/,中英日文檔皆有。
如果對(duì)hibernate望而生畏,而只是尋找一個(gè)替代jdbc的工具的話,s2dao算是一個(gè)不錯(cuò)的選擇。某種程度上來(lái)講,s2dao可能會(huì)比較像ibatis(筆者沒(méi)有使用過(guò)ibatis)。
具體編碼來(lái)說(shuō),基本上是一個(gè)interface(相當(dāng)于DAO)對(duì)應(yīng)一個(gè)javabean。這里的javabean不是pojo,不具備持久性,只是作為dao方法返回值的容器,所以可以很方便的實(shí)現(xiàn)復(fù)雜的多表檢索。
interface的具體方法體不用自己手寫(xiě),通過(guò)系統(tǒng)的interceptor可自動(dòng)填充并實(shí)現(xiàn)。
下面對(duì)使用做具體介紹。本文使用的s2dao版本為1.0.49。
DB中有三個(gè)表:

1.單表
Example.java為Example表的容器類(s2dao習(xí)慣稱之為DTO,雖然這個(gè)稱呼不是很恰當(dāng))
※注:當(dāng)進(jìn)行多表檢索時(shí),@Bean指定其中的一個(gè)table即可。
接下來(lái)是DAO,代碼大體比較易懂。
從幾個(gè)檢索函數(shù)可以看出,s2dao基本能實(shí)現(xiàn)所有種類的檢索。
SingletonS2ContainerFactory.init();
執(zhí)行結(jié)果當(dāng)然是OK,控制臺(tái)LOG就不貼了,貼一下生成的DB LOG,按測(cè)試代碼中調(diào)用dao函數(shù)的順序一一對(duì)應(yīng):
2.多表
看到這你可能會(huì)很奇怪,為什么要存在fId字段?不是有Father類了么?遺憾的是,目前s2dao不支持級(jí)聯(lián)的插入更新刪除(CUD),只支持級(jí)聯(lián)檢索。fId是為了CUD而存在的。
實(shí)現(xiàn)級(jí)聯(lián)檢索的是Child.java中的getFather方法,@Relation指明了其關(guān)系。relationNo為是第幾個(gè)外鍵關(guān)聯(lián)的序號(hào),relationKey為主外鍵名稱聲明。
測(cè)試程序:
執(zhí)行結(jié)果DB LOG:
除以上功能,s2dao還可以調(diào)用存儲(chǔ)過(guò)程,這里就不再介紹了。
如果對(duì)hibernate望而生畏,而只是尋找一個(gè)替代jdbc的工具的話,s2dao算是一個(gè)不錯(cuò)的選擇。某種程度上來(lái)講,s2dao可能會(huì)比較像ibatis(筆者沒(méi)有使用過(guò)ibatis)。
具體編碼來(lái)說(shuō),基本上是一個(gè)interface(相當(dāng)于DAO)對(duì)應(yīng)一個(gè)javabean。這里的javabean不是pojo,不具備持久性,只是作為dao方法返回值的容器,所以可以很方便的實(shí)現(xiàn)復(fù)雜的多表檢索。
interface的具體方法體不用自己手寫(xiě),通過(guò)系統(tǒng)的interceptor可自動(dòng)填充并實(shí)現(xiàn)。
下面對(duì)使用做具體介紹。本文使用的s2dao版本為1.0.49。
DB中有三個(gè)表:

1.單表
Example.java為Example表的容器類(s2dao習(xí)慣稱之為DTO,雖然這個(gè)稱呼不是很恰當(dāng))
1 package com.hg.s2dao.dto;
2
3 import org.seasar.dao.annotation.tiger.Bean;
4
5 @Bean(table = "EXAMPLE")
6 public class Example {
7
8 private String id;
9 private String name;
10
11 public String getId() {
12 return id;
13 }
14
15 public void setId(String id) {
16 this.id = id;
17 }
18
19 public String getName() {
20 return name;
21 }
22
23 public void setName(String name) {
24 this.name = name;
25 }
26
27 public String toString() {
28 return "id: " + id + " name: " + name;
29 }
30
31 }
使用@Bean注釋表明此DTO所對(duì)應(yīng)的DB表名,剩下的就是字段和getter、setter了。2
3 import org.seasar.dao.annotation.tiger.Bean;
4
5 @Bean(table = "EXAMPLE")
6 public class Example {
7
8 private String id;
9 private String name;
10
11 public String getId() {
12 return id;
13 }
14
15 public void setId(String id) {
16 this.id = id;
17 }
18
19 public String getName() {
20 return name;
21 }
22
23 public void setName(String name) {
24 this.name = name;
25 }
26
27 public String toString() {
28 return "id: " + id + " name: " + name;
29 }
30
31 }
※注:當(dāng)進(jìn)行多表檢索時(shí),@Bean指定其中的一個(gè)table即可。
接下來(lái)是DAO,代碼大體比較易懂。
1 package com.hg.s2dao.dao;
2
3 import java.util.List;
4
5 import org.seasar.dao.annotation.tiger.Arguments;
6 import org.seasar.dao.annotation.tiger.Query;
7 import org.seasar.dao.annotation.tiger.S2Dao;
8 import org.seasar.dao.annotation.tiger.Sql;
9
10 import com.hg.s2dao.dto.Example;
11
12 @S2Dao(bean = Example.class)
13 public interface ExampleDao {
14
15 // C////////////////////////////////////
16 /** insert multi */
17 int insertExamples(java.util.List<Example> exps);
18
19 /** insert single */
20 int insertExample(Example exp);
21
22 // R////////////////////////////////////
23 /** search all */
24 List<Example> findAll();
25
26 /** sql command */
27 @Sql("SELECT MAX(E.ID) FROM EXAMPLE E ")
28 String findIDMax();
29
30 /** contains condition */
31 @Query("ID = ? AND NAME = ?")
32 Example findAllByIdAndName(String id, String name);
33
34 /** when multi use or self-define order */
35 @Arguments( { "id1", "id2" })
36 @Query("ID = /*id2*/ OR ID = /*id1*/ ")
37 List<Example> findAllById(String id1, String id2);
38
39 /** list param */
40 @Arguments( { "ids" })
41 @Query("ID IN /*ids*/('') ")
42 List<Example> findAllByIdList(List<String> ids);
43
44 /** param condition */
45 @Arguments( { "ids" })
46 @Query("1 != 0 " //
47 + "/*IF ids != null && ids.size() > 0*/" //
48 + "AND ID IN /*ids*/('') " //
49 + "/*END*/")
50 List<Example> findAllByIdListAdv(List<String> ids);
51
52 // U////////////////////////////////////
53 /** update */
54 int updateExample(Example exp);
55
56 /** object param */
57 @Sql("UPDATE EXAMPLE SET NAME = /*exp.name*/ ")
58 int updateExampleName(Example exp);
59
60 // D////////////////////////////////////
61 /** delete */
62 int deleteExample(Example exp);
63
64 /** delete by param */
65 @Query("ID = ?")
66 int deleteExampleById(String id);
67 }
@S2Dao指明了檢索對(duì)應(yīng)的數(shù)據(jù)承接類。2
3 import java.util.List;
4
5 import org.seasar.dao.annotation.tiger.Arguments;
6 import org.seasar.dao.annotation.tiger.Query;
7 import org.seasar.dao.annotation.tiger.S2Dao;
8 import org.seasar.dao.annotation.tiger.Sql;
9
10 import com.hg.s2dao.dto.Example;
11
12 @S2Dao(bean = Example.class)
13 public interface ExampleDao {
14
15 // C////////////////////////////////////
16 /** insert multi */
17 int insertExamples(java.util.List<Example> exps);
18
19 /** insert single */
20 int insertExample(Example exp);
21
22 // R////////////////////////////////////
23 /** search all */
24 List<Example> findAll();
25
26 /** sql command */
27 @Sql("SELECT MAX(E.ID) FROM EXAMPLE E ")
28 String findIDMax();
29
30 /** contains condition */
31 @Query("ID = ? AND NAME = ?")
32 Example findAllByIdAndName(String id, String name);
33
34 /** when multi use or self-define order */
35 @Arguments( { "id1", "id2" })
36 @Query("ID = /*id2*/ OR ID = /*id1*/ ")
37 List<Example> findAllById(String id1, String id2);
38
39 /** list param */
40 @Arguments( { "ids" })
41 @Query("ID IN /*ids*/('') ")
42 List<Example> findAllByIdList(List<String> ids);
43
44 /** param condition */
45 @Arguments( { "ids" })
46 @Query("1 != 0 " //
47 + "/*IF ids != null && ids.size() > 0*/" //
48 + "AND ID IN /*ids*/('') " //
49 + "/*END*/")
50 List<Example> findAllByIdListAdv(List<String> ids);
51
52 // U////////////////////////////////////
53 /** update */
54 int updateExample(Example exp);
55
56 /** object param */
57 @Sql("UPDATE EXAMPLE SET NAME = /*exp.name*/ ")
58 int updateExampleName(Example exp);
59
60 // D////////////////////////////////////
61 /** delete */
62 int deleteExample(Example exp);
63
64 /** delete by param */
65 @Query("ID = ?")
66 int deleteExampleById(String id);
67 }
從幾個(gè)檢索函數(shù)可以看出,s2dao基本能實(shí)現(xiàn)所有種類的檢索。
- @Query為條件注釋(如findAllByIdAndName),相當(dāng)于where后面的。
- 當(dāng)檢索條件的參數(shù)需要反復(fù)使用或顛倒順序等的時(shí)候(如findAllById),需要添加@Arguments注釋。
- @Sql則為原生態(tài)無(wú)污染的SQL代碼注釋(如findIDMax)。
- 可以對(duì)輸入?yún)?shù)進(jìn)行條件控制(如findAllByIdListAdv)。
1 private static void testBase() {
2
3 ExampleDao dao = getComponent(ExampleDao.class);
4
5 // C///////////////////////////////
6 Example exp = new Example();
7 exp.setId("1");
8 exp.setName("a");
9 System.out.println(dao.insertExample(exp));
10 exp = new Example();
11 exp.setId("2");
12 exp.setName("b");
13 System.out.println(dao.insertExample(exp));
14
15 // R///////////////////////////////
16 System.out.println(dao.findAll());
17 System.out.println(dao.findAllByIdAndName("1", "a"));
18 System.out.println(dao.findAllById("1", "2"));
19 System.out.println(dao.findIDMax());
20
21 List<String> ids = new ArrayList<String>();
22 ids.add("1");
23 ids.add("2");
24 System.out.println(dao.findAllByIdList(ids));
25 System.out.println(dao.findAllByIdListAdv(null));
26 System.out.println(dao.findAllByIdListAdv(ids));
27
28 // U///////////////////////////////
29 exp = new Example();
30 exp.setId("1");
31 exp.setName("c");
32 System.out.println(dao.updateExample(exp));
33 exp = new Example();
34 exp.setName("haha");
35 System.out.println(dao.updateExampleName(exp));
36
37 // D///////////////////////////////
38 exp = new Example();
39 exp.setId("1");
40 exp.setName("a");
41 System.out.println(dao.deleteExample(exp));
42 exp = new Example();
43 exp.setId("2");
44 System.out.println(dao.deleteExample(exp));
45 }
46
47 public static <T> T getComponent(final Class<T> clazz) {
48 final S2Container container = SingletonS2ContainerFactory.getContainer();
49 final Object o = container.getComponent(clazz);
50 final T bean = clazz.cast(o);
51 return bean;
52 }
※注:在執(zhí)行測(cè)試前,需要進(jìn)行框架的初始化,其實(shí)就是一行:2
3 ExampleDao dao = getComponent(ExampleDao.class);
4
5 // C///////////////////////////////
6 Example exp = new Example();
7 exp.setId("1");
8 exp.setName("a");
9 System.out.println(dao.insertExample(exp));
10 exp = new Example();
11 exp.setId("2");
12 exp.setName("b");
13 System.out.println(dao.insertExample(exp));
14
15 // R///////////////////////////////
16 System.out.println(dao.findAll());
17 System.out.println(dao.findAllByIdAndName("1", "a"));
18 System.out.println(dao.findAllById("1", "2"));
19 System.out.println(dao.findIDMax());
20
21 List<String> ids = new ArrayList<String>();
22 ids.add("1");
23 ids.add("2");
24 System.out.println(dao.findAllByIdList(ids));
25 System.out.println(dao.findAllByIdListAdv(null));
26 System.out.println(dao.findAllByIdListAdv(ids));
27
28 // U///////////////////////////////
29 exp = new Example();
30 exp.setId("1");
31 exp.setName("c");
32 System.out.println(dao.updateExample(exp));
33 exp = new Example();
34 exp.setName("haha");
35 System.out.println(dao.updateExampleName(exp));
36
37 // D///////////////////////////////
38 exp = new Example();
39 exp.setId("1");
40 exp.setName("a");
41 System.out.println(dao.deleteExample(exp));
42 exp = new Example();
43 exp.setId("2");
44 System.out.println(dao.deleteExample(exp));
45 }
46
47 public static <T> T getComponent(final Class<T> clazz) {
48 final S2Container container = SingletonS2ContainerFactory.getContainer();
49 final Object o = container.getComponent(clazz);
50 final T bean = clazz.cast(o);
51 return bean;
52 }
SingletonS2ContainerFactory.init();
執(zhí)行結(jié)果當(dāng)然是OK,控制臺(tái)LOG就不貼了,貼一下生成的DB LOG,按測(cè)試代碼中調(diào)用dao函數(shù)的順序一一對(duì)應(yīng):
1 INSERT INTO EXAMPLE (id, name) VALUES ('1', 'a')
2 INSERT INTO EXAMPLE (id, name) VALUES ('2', 'b')
3 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE
4 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE WHERE ID = '1' AND NAME = 'a'
5 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE WHERE ID = '2' OR ID = '1'
6 SELECT MAX(E.ID) FROM EXAMPLE E
7 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE WHERE ID IN ('1', '2')
8 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE WHERE 1 != 0
9 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE WHERE 1 != 0 AND ID IN ('1', '2')
10 UPDATE EXAMPLE SET name = 'c' WHERE id = '1'
11 UPDATE EXAMPLE SET NAME = 'haha'
12 DELETE FROM EXAMPLE WHERE id = '1'
13 DELETE FROM EXAMPLE WHERE id = '2'
2 INSERT INTO EXAMPLE (id, name) VALUES ('2', 'b')
3 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE
4 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE WHERE ID = '1' AND NAME = 'a'
5 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE WHERE ID = '2' OR ID = '1'
6 SELECT MAX(E.ID) FROM EXAMPLE E
7 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE WHERE ID IN ('1', '2')
8 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE WHERE 1 != 0
9 SELECT EXAMPLE.id, EXAMPLE.name FROM EXAMPLE WHERE 1 != 0 AND ID IN ('1', '2')
10 UPDATE EXAMPLE SET name = 'c' WHERE id = '1'
11 UPDATE EXAMPLE SET NAME = 'haha'
12 DELETE FROM EXAMPLE WHERE id = '1'
13 DELETE FROM EXAMPLE WHERE id = '2'
2.多表
1 package com.hg.s2dao.dto;
2
3 import org.seasar.dao.annotation.tiger.Bean;
4
5 @Bean(table = "FATHER")
6 public class Father {
7
8 private String id;
9 private String name;
10
11 public String getId() {
12 return id;
13 }
14
15 public void setId(String id) {
16 this.id = id;
17 }
18
19 public String getName() {
20 return name;
21 }
22
23 public void setName(String name) {
24 this.name = name;
25 }
26
27 }
2
3 import org.seasar.dao.annotation.tiger.Bean;
4
5 @Bean(table = "FATHER")
6 public class Father {
7
8 private String id;
9 private String name;
10
11 public String getId() {
12 return id;
13 }
14
15 public void setId(String id) {
16 this.id = id;
17 }
18
19 public String getName() {
20 return name;
21 }
22
23 public void setName(String name) {
24 this.name = name;
25 }
26
27 }
1 package com.hg.s2dao.dto;
2
3 import org.seasar.dao.annotation.tiger.Bean;
4 import org.seasar.dao.annotation.tiger.Relation;
5
6 @Bean(table = "CHILD")
7 public class Child {
8
9 private String id;
10 private String name;
11 private Father father;
12 /* s2dao do not support cascade CUD but only R,so need field 'fId' */
13 private String fId;
14
15 public String getId() {
16 return id;
17 }
18
19 public void setId(String id) {
20 this.id = id;
21 }
22
23 public String getName() {
24 return name;
25 }
26
27 public void setName(String name) {
28 this.name = name;
29 }
30
31 public String getFId() {
32 return fId;
33 }
34
35 public void setFId(String id) {
36 fId = id;
37 }
38
39 @Relation(relationNo = 0, relationKey = "F_ID:ID")
40 public Father getFather() {
41 return father;
42 }
43
44 /* cannot del this method */
45 public void setFather(Father father) {
46 this.father = father;
47 }
48
49 }
Father和Child存在一對(duì)多/一對(duì)一關(guān)聯(lián),Child中維持著與Father的關(guān)系。2
3 import org.seasar.dao.annotation.tiger.Bean;
4 import org.seasar.dao.annotation.tiger.Relation;
5
6 @Bean(table = "CHILD")
7 public class Child {
8
9 private String id;
10 private String name;
11 private Father father;
12 /* s2dao do not support cascade CUD but only R,so need field 'fId' */
13 private String fId;
14
15 public String getId() {
16 return id;
17 }
18
19 public void setId(String id) {
20 this.id = id;
21 }
22
23 public String getName() {
24 return name;
25 }
26
27 public void setName(String name) {
28 this.name = name;
29 }
30
31 public String getFId() {
32 return fId;
33 }
34
35 public void setFId(String id) {
36 fId = id;
37 }
38
39 @Relation(relationNo = 0, relationKey = "F_ID:ID")
40 public Father getFather() {
41 return father;
42 }
43
44 /* cannot del this method */
45 public void setFather(Father father) {
46 this.father = father;
47 }
48
49 }
看到這你可能會(huì)很奇怪,為什么要存在fId字段?不是有Father類了么?遺憾的是,目前s2dao不支持級(jí)聯(lián)的插入更新刪除(CUD),只支持級(jí)聯(lián)檢索。fId是為了CUD而存在的。
實(shí)現(xiàn)級(jí)聯(lián)檢索的是Child.java中的getFather方法,@Relation指明了其關(guān)系。relationNo為是第幾個(gè)外鍵關(guān)聯(lián)的序號(hào),relationKey為主外鍵名稱聲明。
1 package com.hg.s2dao.dao;
2
3 import org.seasar.dao.annotation.tiger.S2Dao;
4
5 import com.hg.s2dao.dto.Father;
6
7 @S2Dao(bean = Father.class)
8 public interface FatherDao {
9
10 /** insert single */
11 int insert(Father f);
12
13 /** delete */
14 int delete(Father c);
15 }
2
3 import org.seasar.dao.annotation.tiger.S2Dao;
4
5 import com.hg.s2dao.dto.Father;
6
7 @S2Dao(bean = Father.class)
8 public interface FatherDao {
9
10 /** insert single */
11 int insert(Father f);
12
13 /** delete */
14 int delete(Father c);
15 }
1 package com.hg.s2dao.dao;
2
3 import org.seasar.dao.annotation.tiger.Query;
4 import org.seasar.dao.annotation.tiger.S2Dao;
5
6 import com.hg.s2dao.dto.Child;
7
8 @S2Dao(bean = Child.class)
9 public interface ChildDao {
10
11 /** insert single */
12 int insert(Child c);
13
14 /** contains condition */
15 // cannnot only write: @Query("ID = ?")
16 @Query("CHILD.ID = ?")
17 Child findAllById(String id);
18
19 /** update */
20 int update(Child c);
21
22 /** delete */
23 int delete(Child c);
24
25 }
2
3 import org.seasar.dao.annotation.tiger.Query;
4 import org.seasar.dao.annotation.tiger.S2Dao;
5
6 import com.hg.s2dao.dto.Child;
7
8 @S2Dao(bean = Child.class)
9 public interface ChildDao {
10
11 /** insert single */
12 int insert(Child c);
13
14 /** contains condition */
15 // cannnot only write: @Query("ID = ?")
16 @Query("CHILD.ID = ?")
17 Child findAllById(String id);
18
19 /** update */
20 int update(Child c);
21
22 /** delete */
23 int delete(Child c);
24
25 }
測(cè)試程序:
1 private static void testRelation() {
2
3 FatherDao daoF = getComponent(FatherDao.class);
4 ChildDao daoC = getComponent(ChildDao.class);
5
6 // C///////////////////////////////
7 Father popeye = new Father();
8 popeye.setId("1");
9 popeye.setName("Popeye");
10 System.out.println(daoF.insert(popeye));
11
12 Child pipeye = new Child();
13 pipeye.setId("1");
14 pipeye.setName("Pipeye");
15 pipeye.setFId(popeye.getId());
16 System.out.println(daoC.insert(pipeye));
17
18 Child pupeye = new Child();
19 pupeye.setId("2");
20 pupeye.setName("Pupeye");
21 pupeye.setFId(popeye.getId());
22 System.out.println(daoC.insert(pupeye));
23
24 // R///////////////////////////////
25 // pipeye.getFather() is null,so need search again
26 Child pipeyeNew = daoC.findAllById(pipeye.getId());
27 System.out.println(pipeyeNew.getFather());
28
29 // U///////////////////////////////
30 pipeyeNew.setName("pipeyeNew");
31 System.out.println(daoC.update(pipeyeNew));
32
33 // D///////////////////////////////
34 System.out.println(daoC.delete(pipeye));
35 System.out.println(daoC.delete(pupeye));
36 System.out.println(daoF.delete(popeye));
37 }
2
3 FatherDao daoF = getComponent(FatherDao.class);
4 ChildDao daoC = getComponent(ChildDao.class);
5
6 // C///////////////////////////////
7 Father popeye = new Father();
8 popeye.setId("1");
9 popeye.setName("Popeye");
10 System.out.println(daoF.insert(popeye));
11
12 Child pipeye = new Child();
13 pipeye.setId("1");
14 pipeye.setName("Pipeye");
15 pipeye.setFId(popeye.getId());
16 System.out.println(daoC.insert(pipeye));
17
18 Child pupeye = new Child();
19 pupeye.setId("2");
20 pupeye.setName("Pupeye");
21 pupeye.setFId(popeye.getId());
22 System.out.println(daoC.insert(pupeye));
23
24 // R///////////////////////////////
25 // pipeye.getFather() is null,so need search again
26 Child pipeyeNew = daoC.findAllById(pipeye.getId());
27 System.out.println(pipeyeNew.getFather());
28
29 // U///////////////////////////////
30 pipeyeNew.setName("pipeyeNew");
31 System.out.println(daoC.update(pipeyeNew));
32
33 // D///////////////////////////////
34 System.out.println(daoC.delete(pipeye));
35 System.out.println(daoC.delete(pupeye));
36 System.out.println(daoF.delete(popeye));
37 }
執(zhí)行結(jié)果DB LOG:
1 INSERT INTO FATHER (id, name) VALUES ('1', 'Popeye')
2 INSERT INTO CHILD (id, f_id, name) VALUES ('1', '1', 'Pipeye')
3 INSERT INTO CHILD (id, f_id, name) VALUES ('2', '1', 'Pupeye')
4 SELECT CHILD.id, CHILD.f_id, CHILD.name, father.id AS id_0, father.name AS name_0 FROM CHILD, FATHER father WHERE CHILD.F_ID = father.ID(+) AND CHILD.ID = '1'
5 UPDATE CHILD SET f_id = '1', name = 'pipeyeNew' WHERE id = '1'
6 DELETE FROM CHILD WHERE id = '1'
7 DELETE FROM CHILD WHERE id = '2'
8 DELETE FROM FATHER WHERE id = '1'
2 INSERT INTO CHILD (id, f_id, name) VALUES ('1', '1', 'Pipeye')
3 INSERT INTO CHILD (id, f_id, name) VALUES ('2', '1', 'Pupeye')
4 SELECT CHILD.id, CHILD.f_id, CHILD.name, father.id AS id_0, father.name AS name_0 FROM CHILD, FATHER father WHERE CHILD.F_ID = father.ID(+) AND CHILD.ID = '1'
5 UPDATE CHILD SET f_id = '1', name = 'pipeyeNew' WHERE id = '1'
6 DELETE FROM CHILD WHERE id = '1'
7 DELETE FROM CHILD WHERE id = '2'
8 DELETE FROM FATHER WHERE id = '1'
除以上功能,s2dao還可以調(diào)用存儲(chǔ)過(guò)程,這里就不再介紹了。