struct2hibernate3spring3CRUD程序开发指南.docx

上传人:b****8 文档编号:23706572 上传时间:2023-05-20 格式:DOCX 页数:29 大小:41.47KB
下载 相关 举报
struct2hibernate3spring3CRUD程序开发指南.docx_第1页
第1页 / 共29页
struct2hibernate3spring3CRUD程序开发指南.docx_第2页
第2页 / 共29页
struct2hibernate3spring3CRUD程序开发指南.docx_第3页
第3页 / 共29页
struct2hibernate3spring3CRUD程序开发指南.docx_第4页
第4页 / 共29页
struct2hibernate3spring3CRUD程序开发指南.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

struct2hibernate3spring3CRUD程序开发指南.docx

《struct2hibernate3spring3CRUD程序开发指南.docx》由会员分享,可在线阅读,更多相关《struct2hibernate3spring3CRUD程序开发指南.docx(29页珍藏版)》请在冰豆网上搜索。

struct2hibernate3spring3CRUD程序开发指南.docx

struct2hibernate3spring3CRUD程序开发指南

CRUD程序开发指南

1.代码

1.1数据库设计

  先设计性能优良的数据库结构,再用JPAAnnoation进行映射.

  Column命名尽量考虑可直接作为对象的属性名,如列User_Name将被映射为属性userName.

1.2entity对象

  手工编写代码和必要的JPAAnnoatation(如一对多关系,非持久化等),也可以使用Hibernatetools的从数据库逆向初步生成后再进行修改。

@Entity

@Table(name="SS_USER")

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

publicclassUserextendsIdEntity{

privateStringemail; 

publicStringgetEmail(){

returnemail;

}

publicvoidsetEmail(Stringemail){

this.email=email;

}

}

1.3dao对象

  继承于HibernateDAO,一般不需要进一步编码,同样可以在Hibernatetools逆向时生成。

@Repository

publicclassUserDaoextendsHibernateDao{

}

1.4manager对象

  一个Manager对象管理多个紧密关联的entity对象,可按需手工编写CRUD函数,也同样可以使用Hibernatetools生成.

http:

//anonsvn.jboss.org/repos/hibernate/trunk/HibernateExt/tools/src/

@Component

@Transactional

publicclassSecurityEntityManager{

@Autowired

privateUserDaouserDao;

@Transactional(readOnly=true)

publicUsergetUser(Longid){

returnuserDao.get(id);

}

publicvoidsaveUser(Userentity){

userDao.save(entity);

}

}

1.5action对象

   继承于项目内定的CRUDActionSupport类,实现基类规定的ModelDriven与Preparable函数,CRUD操作和页面属性的访问函数.

    使用@NameSpace定义URL映射,如@Namespace("/security")publicclassUserAction指向/security/user.action.

   使用@Results定义特别的返回,如需要redirect的Result.

1.6jsp

  实现对象列表页与表单页,按convention规则的目录存放,如1.5示例的中jsp文件为weapp/WEB-INF/content/security/user.jsp与user-input.jsp。

1.7测试

  dao类需编写集成测试用例进行CRUD测试保证ORM配置正确,对特殊的查询函数也需要进行测试。

  manager类则主要对其中的业务逻辑部分进行测试,尽量用EasyMock实现单元测试用例。

  如果有必要,比如特别要测试的JS效果,GUI已稳定的非常重要的功能,还需要用Selenium编写一个功能测试。

2.配置

 所谓零配置,指的是每增加一个实体的CRUD不需要修改一次公共配置文件,下面简单解释下原来XML的去向。

1.hibernate相关

  1.model对象中的JPAannotation代替了原来的*.hbm.xml.

  2.在applicationContext.xml里定义sessionFactory时,使用packagesToScan属性批量定义了sessionFactory加载的实体对象。

2.spring相关

  1.service/dao对象中, 可用@Component标明是Spring的Bean,Autowired或Resouce标明了注入关系。

  代替了在applicationContext-*.xml中的定义,但需要先在applicationContext.xml中定义

  

component-scanbase-package="org.springside.examples.miniweb"/>

  2.在Servicebean中用@Transcational定义事务。

3.struts2相关

 使用conventionplugin,通过在struts.xml中定义扫描web包,搜索所有*..web..*包中的类作为action.

 action对象和jsp全部按照默认的目录结构和命名规则进行对应,可以在action对象中通过conventionannotation重新特殊配置。

SpringSide3.0的Java编码规范

明:

本规范分为不同的级别,默认级别为必须遵循级别,而(II)为建议级别,非强制执行。

1.格式与命名规范(FormatingandNamingConventions)

1.最重要:

不用死记硬背,直接使用Eclipse的自动格式化功能。

2.换行:

每行120字符以上--因为现在屏幕已大为宽广。

3.括号:

if,for,while语句全部使用括号包围。

4.命名规则:

不允许使用汉语拼音命名

避免使用下划线(静态变量除外)

 接口尽量采用"able","ible",or"er",如Runnable命名,尽量不采用首字母为I或加上IF后缀的命名方式,如IBookDao,BookDaoIF。

(II)

2.注释规范(DocumentConvertions)

2.1注释类型

1.JAVADOC注释

/***....**/

2.失效代码注释

由/**...**/界定,标准的C-Style的注释。

专用于注释已失效的代码。

3.代码细节注释

由//界定,专用于注释代码细节。

注意:

即使有多行注释也仍然使用//,以便与用/**/注释的失效代码分开。

2.2注释的格式

1.注释中的第一个句子要以(英文)句号、问号或者感叹号结束。

Javadoc生成工具会将注释中的第一个句子放在方法汇总表和索引中。

2.为了在JavaDoc和IDE中能快速链接跳转到相关联的类与方法,尽量多的使用@seexxx.MyClass,@seexx.MyClass#find(String)。

3.Class必须以@author声明作者,体现代码责任。

但不需要声明@version与@date,由版本管理系统保留此信息。

(II)

4.标识(javakeyword,class/method/field/argument名,Constants)在注释中第一次出现时以{@linkxxx.Myclass}注解以便JavaDoc与IDE中可以链接。

(II)

2.3注释的内容

1.可精简的注释内容

注释中的每一个单词都要有其不可缺少的意义,注释里不写"@paramname-名字"这样的废话。

如果该注释是废话,连同标签删掉它,而不是自动生成一堆空的标签,如空的@paramname,空的@return。

2.推荐的注释内容

对于调用复杂的API尽量提供代码示例。

(II)

对于已知的Bug需要声明,//TODO或//FIXME声明:

未做/有Bug的代码。

(II)

Null规约:

  如果方法允许Null作为参数,或者允许返回值为Null,必须在JavaDoc中说明。

否则方法的调用者不允许使用Null作为参数,并认为返回值是NullSafe(不会返回NULL)。

3.编程规范(ProgrammingConventions)

3.1基本规范

1.当API会面对不可知的调用者时,方法需要对输入参数进行校验,如不符合则抛出IllegalArgumentException,建议使用Spring的Assert系列函数。

2.因为System.out.println(),e.printStackTrace()仅把信息显示在控制台,因此不允许使用,必须使用logger打印并记录信息。

3.在数组中的元素(如String[1]),如果不再使用需要设为NULL,否则会内存泄漏。

因此直接用Collections类而不要使用数组。

4.在不需要封闭修改的时候,尽量使用protected而不是private,方便子类重载。

5.变量,参数和返回值定义尽量基于接口而不是具体实现类,如Mapmap=newHashMap();

6.用double而不是Float,因为float会容易出现小数点后N位的误差。

3.2异常处理

1.重新抛出的异常必须保留原来的异常,即thrownewNewException("message",e);而不能写成thrownewNewException("message")。

2.在所有异常被捕获且没有重新抛出的地方必须写日志。

--TODO

3.如果属于正常异常的空异常处理块必须注释说明原因,否则不允许空的catch块。

3.3JDK5.0规范

1.重载方法必须使用@Override,可避免父类方法改变时导致重载函数失效。

2.不需要关心的warning信息用@SuppressWarnings("unused"),@SuppressWarnings("unchecked"),@SuppressWarnings("serial")注释。

技术参考手册

1.总述

∙架构风格简述

∙目录结构描述

2. 基础框架

∙Spring:

SpringFramework

∙Database:

ORM-Hibernate,Jdbc-SpringJdbcTemplate,  数据库-H2、MySQL、Oracle,数据库连接池-DBCP

∙Web:

MVC-Struts2,View-JSP2、Taglib、UrlRewrite,Javascript-JQuery、DojoBase,CSS-YUICSSFramework

∙基础类库:

日志-Slf4j,Log4j,Utils工具类

3 企业服务

∙Web服务:

WebService-JAX-WS2、CXF,REST-JAX-RS、Jersey,HttpClient

∙安全:

SpringSecurity,验证码-JCaptcha,Utils-散列、签名、加密

∙缓存:

Cache总述,Memcached,EhCache

∙定时任务:

Quartz,JDKScheduledThreadPoolExecutor

∙JMS:

ActiveMQ+SpringJMS

∙JMX:

SpringJMX

∙Email:

SpringEmail

∙报表:

FlashChart-AmCharts,Excel-POI

∙数据格式:

XML-JAXB2,Dom4j,JSON-Jackson

∙应用服务器:

应用服务器总述,Jetty,JSW+Jetty运行环境

4.架构质量

∙架构质量:

GracefulShutdown

∙管理工具:

Monitor-HypericHQ

∙性能调优:

Web2.0页面优化,  Profile工具-VisualVM、Yorkit,SQL监控工具-P6Spy

Test

1.资料与概述

∙Java测试资料(江南白衣博物馆)

∙Spring2.5集成测试资料(江南白衣博物馆)

测试用例分三类:

   一类是单元测试,测试每一个Class的功能,尽量使用EasyMock/JMockit,Mock掉所有依赖类,隔绝其他类对本类的影响(除了DAO层)。

  二类是功能测试,测试子系统对用户故事的实现,为保证测试速度,一般使用Jetty,H2数据库这些嵌入式的底层,GUI部分一般使用Selenium,对依赖的外系统一般也会采用Dummy/Stub/嵌入式版本等形式。

  三类是集成测试,测试各子系统集成的效果,一般是最基本最基本的少量用例的自动化测试,配合手工测试进行。

2.选型

2.1JUnit3.8vsJUnit4.5

    Spring3.0已经取消JUnit3支持,@Before式的标签使得继承重载关系可以更加的灵活。

2.2EasyMock vsJMockitvsJMock&Others

    比较过EasyMock和JMock觉得还是EasyMock要好用一些,但是EasyMock对静态方法没办法,这时候要JMockit出场,另外写Stub而不是Mock的时候,也是JMockit好用。

2.3Selenium

      Web集成工具中,Selenium是最好用的了,特别是最新版Selenium2.0,将传统的FireFox/IEDriver与运行速度超快的HtmlUnit,统一在WebDriver的API下可随意切换非常好用。

但Anyway,维护GUI测试用例的成本还是很高的,最好还是配合手工测试,不要想着什么都自动化测试。

2.4Spring的测试框架

    像DAO层测试这种需要连接实际数据库及其他需要建立ApplicationContext的情况,Spring提供了较方便的初始化并缓存ApplicationContext,注入以及测试事务自动回滚的功能。

2.5其他

∙测试代码覆盖率工具,Sonar里用C字头的,而开发人员自己用Emma,因为它有Eclipse的插件EclEmma

∙DBUnit:

测试数据的初始化与清理。

Unittest

3.1单元测试概况

   JUnit4中@BeforeClass是只执行一次的静态函数,@Before是每个测试方法都执行一次的函数(小心测试父类与子类的准备函数名不要都叫before,setup,一不小心就互相覆盖了)

   @Ignore("xxx")可以暂时不执行类/方法并说明原因(Sonar会对@Ignore的用例进行监控,所以暂时Skip用例时尽量使用@Ignore,以便日后恢复)。

  可以继承Assert,免得那堆静态导入那堆校验函数。

  对待测对象的私有变量,私有函数可以用ReflectionUtils的反射函数直接调用,如ReflectionUtils.setFieldValue(userManager,"userDao",mockUserDao);

  另外,Spring还为Web相关的测试提供了MockHttpRequest等一大堆stub类,SpringSide也提供了一个可能会用到的WebTestUtils,SpringWebApplicationContext初始化到ServletContext,将MockRequest/Response放入Struts2的ServletActionContext.

3.2Mock

  Mock对单元测试是如此重要,EasyMock们也不再要求基于接口编程了.

  另外,虽然EasyMock提供了createNiceMock()这样的简便方法,但尽量还是不要用,太不可控了.

  在必要情况下可以在设定函数参数时用上isA()这样的功能,如果函数有多个参数,需要都使用匹配。

比如userDao.save(Longid,Useruser);如果想灵活第2个参数,可以写成:

  mockUserDao.save(EasyMock.eq(1L),EasyMock.isA(User.class));

3.3使用ApplicationContext的测试

      严格说使用ApplicationContext的测试不是完全的单元测试,按Spring的说法是集成测试。

    Spring2.5的依赖测试用例支持ApplicationContext依赖注入,事务自动回滚等功能(也可设置不回滚),详见Spring2.5集成测试资料。

    因为Spring的类名一贯清晰但超长,而且不继承于Assert,因此基于它的代码作了小小的改造:

∙SpringContextTestCase:

等于AbstractJUnit4SpringContextTests加上Assert函数。

∙SpringTxTestCase:

在SpringContextTest的基础上,支持事务回滚,支持基于jdbcTemplate的数据库操作常用函数,和Assert函数。

     注意测试时要使用dao的flush()函数,因为Hibernate只有事务提交时才会执行SQL,为了验证你的ORM正确性,必须常常执行flush强制hibernate执行SQL。

不过只要不执行提交,sql执行的结果不会影响测试数据库的实际数据。

    可在applicationContext-test.properties定义与applicationContext.properties不一样的测试环境参数。

    注意Spring对于相同applicationContext-*xml数组配置的applicationContext,默认是会被cache起来,在所有TestCase中使用的。

这造成了太多的混乱,在SpringContextTestCase使用使用@DirtiesContext强迫放弃Cache功能。

3.4Assert方法

   Junit4下不再有继承TestCase基类后,那些assert方法如果要staticimport会变得麻烦,还是继承一下Assert类算了。

3.5测试数据

FunctionalTest

3.1概述

   功能测试以用户故事为线索编写,描述子系统的功能,与单元测试针对类的覆盖率而编写明显不同。

   多变的GUI的测试编写与维护都有一定成本,慎重决定手工还是自动,特别是一些不那么重要的用例。

但非GUI的部分如WebService,就可以尽量的多写了。

3.2Jetty+H2的嵌入式功能测试环境

  如果要启动半天的应用服务器和数据库,显然不适合,而嵌入式的Jetty与H2启动飞快且想关就关,是功能测试的必须。

  如果你坚持用"真正"的应用服务器与数据库,我可以打赌按着这个风格,你的功能测试很快就会突破15分钟的总运行时间,然后总是有用例失败没人修复,然后成为一个摆设。

  SpringSide提供了JettyUtils可以很方便的启动Jetty服务器。

用一个测试用的web.xml指向测试用的applicationContext-test.xml再指向测试用的Mock和Embed们。

  H2服务用一个嵌入式的JDBCURL即可,注意DB_CLOSE_DELAY=-1,另外需要编写一个ant命令,将mysql/oracle的真正sql粗转为H2的SQL,在applicationContext-test.xml中运行初始化。

3.3Selenium功能测试

    Selenium是我在公司实际项目中坚持下来的Web自动测试工具。

    Selenium2.0很好的同时支持了速度飞快的HtmlUnit与实际的IE/Firefox,如果持续集成用的服务器不方便启动浏览器,还有一个RemoteDriver远程连到一台Windows的服务器上面跑,SpringSide提供了SeleniumUtil封装了分析属性文件切换这几种Driver的能力。

    但Selenium2.0目前的API反倒不如1.0丰富,所以SeleniumUtils对最缺失的最常用函数进行了重新封装。

    Selenium用例的维护成本非常高,因此相比其他的测试用例,需要把测试代码写的更加漂亮,需要有良好的封装重用,良好的可读性,稳健的不受其他用例执行结果影响的用例设计,最后页面代码本身也要有可测试性,添加适当的ID方便selenium定位元素,而这一切的反面教材,就是用例中充满了靠SeleniumIDE记录的XPath路径(/tr[3]/td[1]),难读,且脆弱。

   Selenium2.0的资料:

∙官方UserGuide

∙官方博客

,每周收集很多文章。

 

3.4 分组执行测试

  TestNG的Groups效果,可以控制只运行某些Group的用例,比如有些用例执行起来很慢,而且重要程度不高,可以放到晚上的nightly-build再去执行,使用方法如下:

  1.在测试用例的方法上定义Groups,如@Groups("nightly"),

  2.为TestCase设置@RunWith(GroupsTestRunner.class)

  3.用-Dtest.groups=daily,nightly定义会执行的group.

  4.如果方法上没有定义Groups,则全部执行。

如果-D没有定义test.groups,也是全部执行。

  5.如果类的所有方法均不执行,则类的@BeforeClass标注的方法也不执行。

    详见GroupsTestRunnerTest

3.5DBUnit,数据准备类与测试用例间数据解耦

   当测试用例多起来以后,如果防止用例间执行结果的互相影响(这个用例跑完之后会影响另一个用例的结果值),降低用例对基础数据的依赖非常重要(增加或修改基础数据不会造成一大堆用例跑不过)。

  因为使用H2嵌入式数据库,表结构的初始化sql在applicationContext-test.xml中定义,这是Spring3.0新提供的功能。

   测试数据尽量在用例中创建,使用相应的数据准备类如UserData.java,使用了SpringSide提供了DataUtils工具方法尽量随机的产生数据,比如随机生成数字,随机从备选List出取出若干个元素等。

   有些基本数据也可以用DBUnit来载入,预先定义在src/test/resources/*-data.xml.可以定义多套数据.

   另外平时开发调试时,也可以用Ant来调用DBUnit(Maven的DBUnit插件不支持调用多个xml文件)来记录和载入基础数据,详见用bin的db-init.bat与db-export.bat。

  JUnit执行用例的顺序不可控,因此规定,

∙纯单元测试不访问数据库

∙访问数据库的集成测试用Spring的事务测试基类强制Rollback

∙使用DBUnit的

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1