• S2dao 简单Demo(转)


    s2dao是基于seasar2的orm框架,使用简单且功能比较强大。官方网站为http://s2dao.seasar.org/,中英日文档皆有。
    如果对hibernate望而生畏,而只是寻找一个替代jdbc的工具的话,s2dao算是一个不错的选择。某种程度上来讲,s2dao可能会比较像ibatis(笔者没有使用过ibatis)。

    具体编码来说,基本上是一个interface(相当于DAO)对应一个javabean。这里的javabean不是pojo,不具备持久性,只是作为dao方法返回值的容器,所以可以很方便的实现复杂的多表检索。
    interface的具体方法体不用自己手写,通过系统的interceptor可自动填充并实现。

    下面对使用做具体介绍。本文使用的s2dao版本为1.0.49。
    DB中有三个表:


    1.单表

    Example.java为Example表的容器类(s2dao习惯称之为DTO,虽然这个称呼不是很恰当)
    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所对应的DB表名,剩下的就是字段和getter、setter了。
    ※注:当进行多表检索时,@Bean指定其中的一个table即可。

    接下来是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指明了检索对应的数据承接类。
    从几个检索函数可以看出,s2dao基本能实现所有种类的检索。
    @Query为条件注释(如findAllByIdAndName),相当于where后面的。
    当检索条件的参数需要反复使用或颠倒顺序等的时候(如findAllById),需要添加@Arguments注释。
    @Sql则为原生态无污染的SQL代码注释(如findIDMax)。
    可以对输入参数进行条件控制(如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 }※注:在执行测试前,需要进行框架的初始化,其实就是一行:
    SingletonS2ContainerFactory.init();

    执行结果当然是OK,控制台LOG就不贴了,贴一下生成的DB LOG,按测试代码中调用dao函数的顺序一一对应:
    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.多表

    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 }
    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存在一对多/一对一关联,Child中维持着与Father的关系。
    看到这你可能会很奇怪,为什么要存在fId字段?不是有Father类了么?遗憾的是,目前s2dao不支持级联的插入更新删除(CUD),只支持级联检索。fId是为了CUD而存在的。
    实现级联检索的是Child.java中的getFather方法,@Relation指明了其关系。relationNo为是第几个外键关联的序号,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 }
    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 }
    测试程序:
    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 }
    执行结果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'

  • 相关阅读:
    分享一个关于Cookie做的实验结果
    使用jest进行单元测试
    【转载】为什么单反镜头做不小,镜头越好越重呢?
    【转载】解读手机摄像头
    【转载】2019中国机器视觉产业全景图谱
    【行业】视觉传感器
    图像质量测评
    COM口了解下
    dbus-python的API及示例
    QtDbus的API及示例
  • 原文地址:https://www.cnblogs.com/likwo/p/1762769.html
Copyright © 2020-2023  润新知