转载 Seasar2框架功能参考

此内容转载自大唐云动力产品开发知识库

http://oa.icloudpower.com/seasar2/live/SAStruts.html

Seasar2

Seasar2的核心特色,即Super Agile Struts(超级敏捷开发框架,此后简称SAStruts),Seasar2实际上就是能够将传统基于Struts的系统开发过程大幅敏捷化的(Super Agile)的技术开发框架。

开发环境:JDK1.6,Eclipse(Version: 3.5以上)和Tomcat6.0

示例应用1-index

让我们来看看工程目录webapp下保存的文件,是不是有缺省显示的index.jsp(index.html)文件

在Seasar2框架中,当浏览器访问Web应用的根目录时,如果存在 RootPackage.action.IndexAction 的类,系统将自动定位到此Action。

IndexAction.java源代码:

package tutorial.action;

import org.seasar.struts.annotation.Execute;

public class IndexAction {

  @Execute(validator = false)
  public String index() {
    return "index.jsp";
  }
}

在这个action中,带有@Execute注解的方法,将被系统调用。一个action中可以定义复数个带@Execute注解的执行方法。

在本例中,action中只定义了有一个缺省的index()方法。它将被无条件调用。

方法的返回值,即为action需要跳转的页面,上述例子执行后,页面将跳转到index.jsp。

打开配置文件web.xml,其中VIEW_PREFIX定义的值为/WEB-INF/view,所以跳转的页面就是/WEB-INF/view/index.jsp。

好了。在第一个示例的说明结束之前,我们在顺便看一下webapp/WEB-INF/struts- config.xml这个配置文件。

你是否发现,这个配置文件中根本就没有有关Action及ActionForm的定义。

Seasar2是通过对url 来分析,根据一定的命名规则,准确定位到对应的Action类并执行调用。从而完全省略了对struts-config.xml文件的修改和维护。

同样,细心的你是否发现,工程里找不到webapp/WEB-INF/validation.xml文件。

Seasar2开发框架中,通过在ActionForm类中增加注解的方式,替代了传统Status通过配置文件(validation.xml)定义输 入验证的套路。

示例应用2-加法运算

AddAction.java 源代码:
package tutorial.action;

import org.seasar.struts.annotation.Execute;
import org.seasar.struts.annotation.IntegerType;
import org.seasar.struts.annotation.Required;

public class AddAction {

@Required
@IntegerType
public String arg1;

@Required
@IntegerType
public String arg2;

public Integer result;

@Execute(validator = false)
public String index() {
return "index.jsp";
}

@Execute(input = "index.jsp")
public String submit() {
result = Integer.valueOf(arg1) + Integer.valueOf(arg2);
return "index.jsp";
}
}

Seasar2中定义的action类,就是一个最普通的POJO类(没有继承任何Class的简单类文 件)。

来自页面的各种请求都集中在这个类中处理。每一个请求对应一个执行函数。函数定义时,需要在前面附加@Execute注解。而函数的返回值,就是请求处理结束后,将要跳转到的页面。

下述2个url请求,都对应着Action中的同一个执行函数 :AddAction#index()

http://localhost:8080/seasar2-tutorial/add/index

http://localhost:8080/seasar2-tutorial/add/   *url中没有指明执行函数时,Seasar2将默认调用缺省的index()函数。

有关Form中的submit按钮:

<input type="submit" name="submit" value="计算"/>

Seasar2自动匹配提交按钮的name属性,所以,AddAction#submit()函数将负责处理此提交请求。

Form提交时,一般都会涉及对输入数据的验证。Seasar2是通过在输入变量上标记注解的方式来实现验证。

在@Execute中,常用的属性是validator和input。

valiator=ture时,当系统验证输入数据不合法时,页面将跳转到input属性所指定的页面。

 /add/index.jsp 源代码

<html>
<head>
<title>Add</title>
</head>
<body>
<html:errors/>
<s:form>
<html:text property="arg1"/> + <html:text property="arg2"/>
= ${f:h(result)}<br />
<input type="submit" name="submit" value="计算"/>
</s:form>
</body>
</html>

对于一般JSP页面经常使用到的taglib,可以在webapp/WEB-INF/view/common/common.jsp做定义说明。

系统对输入数据验证发现错误时,需要提示验证信息,html:errors 标签显示这些信息。

定义JSP页面的Form,请使用s:form标签,标签的action属性,会由框架自动生成。一般情况下无需特别定义。

Form中的输入项目,如文本框,下拉框等,通用 html:text 等标准html标签库。 property属性即对应ActionForm类或Action类中定义的属性名称。

Form提交时,因submit的标签将name属性设置为 "submit", 所以,AddAction类中需要有对应的submit()函数,处理此按钮的处理请求。

上例中,我们对输入的2个参数作了输入验证。分别是必录项验证和整数验证。请看arg1和arg2定义上方的注解。

当验证发现输入不合法是,页面将跳转到input属性定义的index.jsp页面。验证输入合法时,submit()函数将被调用执行。

submit()函数的返回值是index.jsp。所以页面提交后,页面会跳转到index.jsp。

action类中,定义有result。jsp页面可以使用${f:h(result)}显示ActionForm或者action类中的属性值。

f:h标签,可以将变量中的特殊html字符做转换。保证正确的显示结果。

示例应用3-文件上传

UploadAction.java 源代码
package tutorial.action;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.upload.FormFile;
import org.seasar.framework.container.annotation.tiger.Binding;
import org.seasar.framework.container.annotation.tiger.BindingType;
import org.seasar.framework.exception.IORuntimeException;
import org.seasar.struts.annotation.Execute;
import org.seasar.struts.annotation.Required;
import org.seasar.struts.upload.S2MultipartRequestHandler;
import org.seasar.struts.util.ActionMessagesUtil;

public class UploadAction {

    @Required
    @Binding(bindingType = BindingType.NONE)
    public FormFile formFile;

    @Binding(bindingType = BindingType.NONE)
    public FormFile[] formFiles;

    public HttpServletRequest request;

    public ServletContext application;

    @Execute(validator = false)
    public String index() {
        SizeLimitExceededException e = (SizeLimitExceededException) request
            .getAttribute(S2MultipartRequestHandler.SIZE_EXCEPTION_KEY);
        if (e != null) {
            ActionMessages errors = new ActionMessages();
            errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
                "errors.upload.size",
                new Object[] { e.getPermittedSize(), e.getActualSize() }));
            ActionMessagesUtil.addErrors(request, errors);
        }
        return "index.jsp";
    }

    @Execute(input = "index.jsp")
    public String upload() {
        ActionMessages messages = new ActionMessages();
        upload(formFile, messages);
        for (FormFile file : formFiles) {
            upload(file, messages);
        }
        ActionMessagesUtil.addMessages(request, messages);
        return "index.jsp";
    }

    protected void upload(FormFile file, ActionMessages messages) {
        if (file.getFileSize() == 0) {
            return;
        }
        String path = application.getRealPath("/WEB-INF/work/"
            + file.getFileName());
        try {
            OutputStream out = new BufferedOutputStream(new FileOutputStream(
                path));
            try {
                out.write(file.getFileData(), 0, file.getFileSize());
            } finally {
                out.close();
            }
        } catch (IOException e) {
            throw new IORuntimeException(e);
        }
        messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
            "messages.upload.complete",
            new Object[] { path }));
    }
}

Seasar2框架提供有方便的文件上传类,开发带有文件上传的应用,开发者只需在Action或ActionForm中,定义FormFile类型的变量就可以了。

我们可以将存放UpladFile的变量定义为数组,如FormFile[],便可以从提交的Form中获取多个上传文件对象。

当FormFile定义为数组时,无法通过加注验证注解方式验证上传文件。此时如需要验证上传是否成功,需要通过FormFile#getFileSize()是否为0来判断。

我们可以在配置文件里限制上传文件的大小。(struts-config.xml中controller节点的maxFileSize属性值),如果接受到的文件超过了配置文件设定的上限。框架将抛出SizeLimitExceededException异常。

上述示例中,有异常发生时,处理将跳转到index函数,所以在index函数中,通过判断否存在SizeLimitExceededException来确定上传文件大小是否超过上限。

/upload/index.jsp源代码

<html>
<head>
<title>Upload</title>
</head>
<body>
<html:errors/>
<html:messages id="m" message="true">
${f:h(m)}<br />
</html:messages>

<s:form action="/upload" enctype="multipart/form-data">
<input type="file" name="formFile" /><br />
<c:forEach varStatus="s" begin="0" end="1">
<input type="file" name="formFiles[${s.index}]" /><br />
</c:forEach>

<input type="submit" name="upload" value="上传"/>
</s:form>
</body>
</html>

带有文件上传的页面,注意form的enctype属性要设置为"multipart/form- data"。上 传标签(<input type="file" ... />)的name属性要与Action或者ActionForm内的属性变量名称相。

页面的FormFile如果是要处理数组形式的文件上传,上传标签的name属性値需要写成 属性名[数组下标] 的形式。

功能参考

本章介绍Seasar2框架的主要功能及配置规则。完成本章的学习,在回过头结合上一章节的示例后,你也可以轻松自如的开发构建属于自己的应用工程了。

Project构成

Seasar2构建的工程的src目录中,需要有一个RootPackage包,RootPackage包的名字可以自定义,以示例工程seasar2-tutorial为例,工程中指定的RootPackage包名称为tutorial。

在包名确定后,需要确定配置文件convention.dicon中的配置是否与这个包名一致。

convention.dicon 内容

<components>
    <component
        class="org.seasar.framework.convention.impl.NamingConventionImpl">
        <initMethod name="addRootPackageName">
            <arg>"tutorial"</arg>
        </initMethod>
    </component>
    <component
        class="org.seasar.framework.convention.impl.PersistenceConventionImpl"/>
</components>


在RootPackage下一般会有下面几个典型的java包

Action

系统中所有Action处理,都在RootPackage.Action下做定义,比如

与http://hostname/projectname/xxx/ 这样的URL相对应的Action类,就是XxxAction.java (注意大小写)

ActionForm

Action中对应的ActionForm,都在RootPackage.Form下做定义,比如,XxxAction中对应的ActionForm,其名称就对应为XxxForm。(注意大小写)

ActionForm的作用就是接受来自页面提交的输入/输出参数。(虽然这些参数都可以在action中定义,但从维护,可读的角度来要求,我们规定,对于Action处理中需要处理的页面输入输出参数,都要在ActionForm类中相应的变量定义)

Entity

系统中所有Entity类,都在RootPackage.Entity下做定义。Entity是用户储存数据库持久层的数据实体类。对于Entity的命名没有特别的规定。一般情况下可沿用数据库表的名称。

Service

对Entity操作的类,这里我们称为Service。系统中所有Entity类,都在 RootPackage.Service下做定义。

Serivce的类名称形如 XxxService, 因为一个Service通常与一个Entity对应, 所以Xxx部分原则上使用与之对应的Entity名称。(*关于数据持久层的说明,请参考S2JDBC进阶章节)

Util

工程项目中会经常调用到的自定义的工具类,可都存放在在RootPackage.Util下,没有特别的命名要求。


应用程序体系结构

Seasar2框架从根本上来说,也是基于MVC(Model View Controller)体系结构衍生而成的, Model对应Entity、View对应JSP、Controller对应Action。 

一个Action中,可以包含多个执行方法(函数)。通常,一个UseCase映射一个Action。

在B/S系统中也可以认为,业务由多个页面构成,页面是构成UseCase的基本单位。而数据如何在页面中显示的逻辑,则在Action中做编码定义。

业务逻辑处理一般定义在Service中。也有一种设计观点认为。通过Dao(Data Access Object),可以进一步把数据访问从业务逻辑中抽出,以应对开发过程中发生的数据访问层框架的变更。

但这种情况基本上不会发生,故在Seasar2框 架中,数据访问处理可以直接写在业务逻辑中。

Action

服务器端用以响应处理浏览器请求(Request)的类,这里称之为Action。 在Struts里,URL和Action的对应关系,需要在struts-config.xml中定义,在Seasar2框架中,这个对应关系通过下述约 定的命名规则由框架自动确定,不需要再对struts-config.xml做任何编辑修改。

举例来说 http://localhost:8080/seasar2-tutorial/login/ 

首先,seasar2-tutorial 是应用名称。

再往后,Seasar2将根据下述规则,将URL转换定位到对应的Action。
    * Web应用名之后的是请求的路径,/login/ , 将路径最后的/去掉,并加上Action后缀, 变成 loginAction
    * 将首字母转换为大写字母 loginAction  --〉LoginAction
    * 前置 RootPackage.action.
    * 通过上面3步的转换,Seasar2最终将、/login/ 这个URL映射到 tutorial.action.LoginAction 这个类。

如果请求URL中没有ActionPATH,框架会查找是否存在有 RootPackage.action.IndexAction这个类,并加载执行。

http://localhost:8080/seasra2- tutorial/ 对应的Action就是 tutorial.action.IndexAction。

补充,如果想让系统缺省调用IndexAction,要注意Web的根目录下不要存放有 index.jsp。其执行的优先度高于IndexAction。

ActionPath可以进一步分割子集,如/aaa/bbb/这样的请求url的ActionPath,对应执行RootPackage.action.aaa.BbbAction类。
Seasar2中的Action类,是POJO(最普通的Java类)。 不需要继承Strtus的Action。
在Action中通常会要使用到ActionForm,引用ActionForm时,请附加@ActionFormと@Resource注解,引用的ActionForm的实体变量名,固定定义为ActionForm类名的(首字母需转为小写)

ActionForm 引用示例

@ActionForm
@Resource
protected AddForm addForm;

向JSP页面输出的值以及而来自JSP页面提交的数据,既可以在Action类中作为属性定义,也可以将其定义在ActionForm中。但原则上请定义都在ActionForm中。

当有些信息(如Login用户名)需要在Session中管理保存时,将其放入RootPackage.dto.XxxDto。并通过注解@Component声明他将在Session中管理。

@Component(instance = InstanceType.SESSION)
public class UserDto implements Serializable {

    private static final long serialVersionUID = 1L;
    
    public String userName;
    ...
}

在Action中使用上述UserDto时、需要做如下变量定义, 前置注解@Resource,变量名为类名称,首字母替换为小写。

@Resource
protected UserDto userDto;

相似的,我们编写的业务逻辑代码,都汇集到RootPackage.service包下,命名为XxxService。

public class XxxService {
...
}

在Action中,需要调用Service时, 按相同的命名规范定义实体,如下:

@Resource

protected XxxService xxxService;

同理,对于HttpServletRequest、HttpServletResponse等Servlet API相关的对象,也可通过前置@Resource注解的方式建立引用。

示例代码:

public class MyAction {


@Resource

protected HttpServletRequest request;


@Resource

protected HttpServletResponse response;

 

@Resource

protected HttpSession session;

 

@Resource

protected ServletContext application;

...

}

执行方法(函数)

Action类中的,对应于Request请求的处理函数,称为执行方法(函数),

方法名(函数名)任意,前置@Execute注解。方法的返回值是String,方法不带任何参数。

@Execute
public String xxx() {
    ...
    return ...;
}

执行方法的返回值,就是处理完成后页面跳转的地址,

如返回值不是以/开头的,系统将以Action所在Path作为相对路径的起始点。

例如,/add/的Action的返回值为index.jsp时,跳转的页面即为/add/index.jsp。

在web.xml中有一个VIEW_PREFIX参数,用以确定该jsp文件在工程中的位置。

在seasar2-tutorial工程里,VIEW_PREFIX的值为/WEB-INF/view,所以跳转页面所在的位置就在/WEB-INF/view/add/index.jsp。

如返回值是以/开头的,系统则认为是Web应用的根地址为相对路径的起始点。

例如,返回值是/select/时,跳转的页面就是 http://localhost:8080/seasar2-tutorial/select/ 。

页面的跳转方法,缺省为FORWARD,当需要使用重定向方式是,需要在返回路径的后面追加redirect=true的参数。形如,

    ...

    return "xxx.jsp?redirect=true";
    ...

    return "xxx.jsp?key=value&redirect=true";

跨域跳转

...
return "https://hostname/appname/path/?redirect=true";

也有些情况,如文件下载等请求处理,只通过Response直接输出而没有跳转时,执行方法的返回值设为null。

一个Action类中,可以定义多个执行方法。具体到哪一个方法被调用,则是由请求URL,JSP页面提交按钮的Name属性值来确定。

如下的例子、AddAction#index()将被调用执行。

http://localhost:8080/sa-struts-tutorial/add/index

http://localhost:8080/sa-struts-tutorial/add/   (url中没有执行方法名时,index()方法将被缺省调用)

故上述2个URL等效。

再看一个页面提交的例子

JSP页面的按钮定义为

<input type="submit" name="confirm" value="确认提交"/>

此提交按钮标签的name属性值是comfirm。Action类中的conFirm()方法负责处理通过此按钮提交后的一系列工作。

如希望窗体提交前做必要的输入数据验证,Seaser2提供了比较简易的方法。 将@Execute注解的validator参数置为true。缺省为true。

当验证出错后,页面将跳转到input参数指定的页面。

@Execute(validator = true, input = "edit.jsp")

ActionForm

ActionForm,主要用于管理Request中的输入输出参数,是一个普通的POJO。

输入输出参数的名字对应ActionForm内定义各属性变量。

Seasar2中,Action的生存期缺省为Request周期,如要提升为Session生存周期,需要增加一行注解的描述。

@Component(instance = InstanceType.SESSION)

public class XxxForm implements Serializable {


    private static final long serialVersionUID = 1L;

    ...

}

需要注意的一点,需要归入Session生存周期管理的组件,必须implements Serializable。

进一步,使用对输入对象做数据验证,也是在ActionForm中通过对属性变量前置注解来实现。

@Required

public String arg1;

* 对arg1做必须输入的验证

Ajax

Seasar2支持Ajax调用。最常见的是通过jquery调用。

Ajax调用时,Action的执行方法内,直接使用ResponseUtil.write("字符串"),输出字符文本。也没有页面迁移,所以方法的返回值是null。

@Execute(validator = false)
public String hello() {
    ResponseUtil.write("Hello Ajax");
    return null;
}

在jsp文件中,使用到jquery,需要包含jquery库。

<script src="${f:url('/js/jquery.js')}"></script>
...
<span id="message"></span><br />
<input type="button" value="hello"
    onclick="$('#message').load('hello');"/>

上例中,在jsp页面中,通过$('TAGid').load('执行方法名');的写法,可以将Ajax调用的输出结果赋回页面的指定元素(TAGID)。

有关Seasar2框架的基础知识就是这些。掌握的这些基础知识,你已经可以自己开发一些简单的Web应用了!细心的读者可能发现,这里还没有详细设计到对数据库,事务的介绍。这将在下一篇,Seasea2进阶章节做进一步介绍。

Seasar2 使用进阶 (数据库访问及有关配置文件)

本章节结合示例代码重点介绍如何利用Seaser2附带的S2JDBC持久层框架,快速实现对数据库数据的增删查改和事务控制。

前面的章节提到过,对数据库操作的业务逻辑,可以放在Service层中实现。

Seasar2框架中缺省包含有S2JDBC持久层框架,实现对各类数据库的通用支持,与数据库连接有关的配置信息,都通过配置文件jdbc.dicon统一管理。

S2JDBC支持多种市面常见的数据库,这些信息定义在配置文件s2jdbc.dicon中,根据项目实际情况进行修改。

在实际代码中,我们通过JdbcManager实例与持久层框架S2JDBC交互。

Service或者Action中,引用JdbcManager的方法如下:

@Resource

protected JdbcManager jdbcManager;

 

自动事务

在Action或Service中,如需要打开或关闭例外,异常发生后的事务自动回滚,请修改配置文件cutomizer.dicon。

<component name="actionCustomizer"
  class="org.seasar.framework.container.customizer.CustomizerChain">
  <initMethod name="addCustomizer">
    <arg>
      <component
        class="org.seasar.framework.container.customizer.TxAttributeCustomizer"/>
    </arg>
  </initMethod>
  ...
</component>
   
<component name="serviceCustomizer"
  class="org.seasar.framework.container.customizer.CustomizerChain">
  <initMethod name="addCustomizer">
    <arg>
      <component
        class="org.seasar.framework.container.customizer.TxAttributeCustomizer"/>
    </arg>
  </initMethod>
  ...

S2JDBC示例汇编

下面的例子,演示了如何通过jdbcmanager,完成对数据库表的CRUD操作。

  • SELECT

/*多条结果*/

List<Employee> results = jdbcManager.from(Employee.class)
                             .join("department")
                             .where("id in (? , ?)", 11, 22)
                             .orderBy("name")
                             .getResultList();

/*单条结果*/

Employee result =
    jdbcManager
        .from(Employee.class)
        .where("id = ?", 1)
        .getSingleResult();
System.out.println(result.name);

* Employee是一个Entity,其属性一般都对应于数据库表的定义,其中没有业务逻辑,可以通过工具自动生成,提高编码效率。

/**

* Employee 实体类

*

*/

@Entity

public class Employee {

 

/** id字段属性 */

@Id

@Column

public Integer id;

 

/** name 字段 属性 */

@Column

public String name;

 

/** jobType 字段 属性 */

@Column

public Integer jobType;

 

/** salary 字段 属性 */

@Column

public Integer salary;

 

/** departmentId 字段 属性 */

@Column(nullable = true, unique = false)

public Integer departmentId;

 

/** addressId 字段 属性 */

@Column(nullable = true, unique = true)

public Integer addressId;

}

  • Select (结果分页)

    List < Employee > results =
        jdbcManager
           
    . from ( Employee . class )
           
    . orderBy ( "id" )
           
    . limit ( 5 )
           
    . offset ( 4 )
           
    . getResultList ();
    for ( Employee e : results ) {
       
    System . out . println ( e . id );
    }

  • Insert

    public void testInsertTx () throws Exception {
       
    Employee emp = new Employee ();
        emp
    . name = "test" ;
        emp
    . jobType = JobType . ANALYST ;
        emp
    . salary = 300 ;
        jdbcManager
    . insert ( emp ). execute ();
    }

  • Update

    mployee emp =
        jdbcManager
           
    . from ( Employee . class )
           
    . where ( "id = ?" , 1 )
           
    . getSingleResult ();
    emp
    . name = "hoge" ;
    jdbcManager
    . update ( emp ). execute ();

  • Delete

Employee emp =
    jdbcManager
        .from(Employee.class)
        .where("id = ?", 1)
        .getSingleResult();
jdbcManager.delete(emp).execute();

emp =
    jdbcManager
        .from(Employee.class)
        .where("id = ?", 1)
        .getSingleResult();

对于单表的简单数据表操作,可以通过以上的方式完成。对于多表结合等复杂SQL的操作,JdbaManager提供另外一种直接执行SQL或SQL文件的方法。

  • 代码内SQL定义

private static final String SELECT_SQL =
   
"select e.*, d.name as department_name"
       
+ " from employee e left outer join department d"
       
+ " on e.department_id = d.id"
       
+ " where d.id = ?" ;
...
List < EmployeeDto > results =
    jdbcManager
       
. selectBySql ( EmployeeDto . class , SELECT_SQL , 1 )
       
. getResultList ();
for ( EmployeeDto e : results ) {
   
System . out . println ( e . name + " " + e . departmentName );
}

  • 执行外部SQL文件定义

    SelectParam param = new SelectParam ();
    param
    . salaryMin = new BigDecimal ( 1200 );
    param
    . salaryMax = new BigDecimal ( 1800 );
    List < EmployeeDto > results =
        jdbcManager
           
    . selectBySqlFile (
               
    EmployeeDto . class ,
               
    "examples/sql/employee/selectAll.sql" ,
                param
    )
           
    . getResultList ();

看一下sql文件是如何定义的examples/sql/employee/selectAll.sql:( SQL定义文件必须保存为UTF-8编码)。

select * from employee where
salary
<= /*salaryMin*/ 1000
and
salary >= /*salaryMax*/ 2000

SQL中的查询参数,可以是Map,也可以是一个POJO,只要KEY或者属性名和sql文件中定义的参数名称一致即可。

SelectParam .java:

package examples . entity . Employee ;

 

public class SelectAllParam {

    public BigDecimal salaryMin ;

    public BigDecimal salaryMax ;

}

  • 复杂SQL的分页,注意,实现分页的SQL定义中,一定要有order by。

jdbcManager
    .selectBySql(
        EmployeeDto.class,
        "select id, name from employee order by name")
    .limit(100)
    .offset(10)
    .getResultList();

  • 通过SQL实现,insert/update/delete

    jdbcManager
        .updateBySql(
            "update employee set salary = ? where id = ?",
            BigDecimal.class,
            Integer.class)
        .params(null, 1)
        .execute();

到此,有关Seasar2快速开发框架的基本使用就介绍完了。更多的使用技巧,需要你在实际的项目中不断 积累和摸索。

多读读别人写的程序。对自己也是很好的提高。

常见问题(Question And Answer)

Question 1:Web.xml中是否可以定义自己的Servlet?

Answer:可以。Seasar框架本身支持开发者自己编写的Servlet。 但主要注意的是。当在Servlet中需要用到Seasar2提供的组件时,

请务必通过SingletonS2ContainerFactory(单例容器工厂)对象建立引用。

例:在servlet中使用jdbcmanager.

       final String PATH = "s2jdbc_cloud.dicon";

        SingletonS2ContainerFactory.setConfigPath(PATH);
        SingletonS2ContainerFactory.init();
        S2Container s2Container = SingletonS2ContainerFactory.getContainer();
        jdbcmanager = (JdbcManager) s2Container.getComponent("jdbcManager_cloud");

Question 2:s2jdbc是否支持oracle的BLOB字段类型?

Answer:支持。entity类中定义的字段项加注 @Lob 注解即可

例:

@Lob
@Column(name = "IMAGEDATA")
public byte [] imagedata ;

 

posted @ 2013-09-25 09:03  博到用时方恨少  阅读(3301)  评论(1)    收藏  举报