- 浏览: 1079224 次
文章分类
最新评论
-
shunyang218:
图刷不出来 ,有点可惜了。
android facebook twitter开发 与 OAUTH -
whoshaofeng:
eval('('+str+')') 为什么加 '('
JSON那些事 -
ileson:
可否把代码贴出来、研究一下。
分享几个超级震憾的图片特效
在 SCA Module 中使用 Hibernate 框架实现数据持久层
SCA(Service Component Architecture)作为服务组件体系结构,将所有的集成构件都描述为具有定义明确的接口的服务组件。SCA 还引入了模块的概念,它将服务组件集中到一起,并提供服务的进一步说明和封装。这意味着只要模块的接口保持不变,就可以在不影响整个解决方案中的任何其他模块的情况下更改模块内的服务组件。服务组件的实现可以是Java 对象(例如POJO或者SLSB), BPEL,Human task,业务状态机以及业务规则集合等。
服务数据对象(Service Data Objects,SDO)是SOA体系结构中的一个用来简化和统一数据应用的开发框架,也是SCA Module的基本组成部分。SDO支持与XML的集成并且适用于J2EE模式和最佳实践。与其他的数据集成模型不同,SDO不仅仅是数据的抽象,SDO框架也是一个断开连接的编程模型,即可以在不连接任何数据源的情况下进行编程。
Hibernate是一种Java语言下的对象关系映射解决方案,Hibernate不仅负责从Java类到数据库表的映射,还包括从Java数据类型到SQL数据类型的映射,并且还提供了面向对象的数据查询检索机制,从而极大地缩短的手动处理SQL和JDBC上的开发时间。
本文主要由两部分内容组成:
1. 讨论如何以Model Driven的方式,构建SCA模块以及生成实现。
2. 讨论如何引入Hibernate实现SCA Module的持久层,并结合示例讨论如何针对类与类之间的各种映射关系定义 Hibernate映射文件,以及如何调用Hibernate API操作JavaBean来实现对数据库对象的访问。
文中涉及到的建模和代码实现都是在WebSphere Integration Developer v6.0开发并基于 WebSphere Process Server v6.0上测试完成的,使用的数据库是DB2 v8.2。
开始之前,希望读者对如下知识有一定了解:
- SOA:Service Oriented Architecture 面向服务的体系结构
- SCA:Service Component Architecture 服务组件体系结构
- SDO:Service Data Object 服务数据对象
- Hibernate:一种Java语言下的对象关系映射解决方案
我们引入一个证券业的简单实例来说明整个过程。
如果您想从事证券投资,就需要去证券公司开立一个交易账户。开户时,证券公司需要把您的个人信息注册到股东表中,并且对您购买的股票进行记录以进行后续的证券买卖结算。基于这个场景, 我们将基于SCA把建立个人证券账户相关的业务功能构建为服务组件,在实现服务组件时采用Hibernate来快速完成数据对象与SDO之间的映射工作。
我们用以下的用例图来描述这个场景:
根据这个场景,我们需要为股东,证券,证券类别,股东证券账户等实体创建相应的Java对象,用下面的类图来描述这些 Java对象以及它们之间的关系:
在创建图-2所示的类图时,我们同时也创建了对应的Java类。这种Model-Drive的开发方式,省却了再次手动创建Java类的繁琐,并且可以实现类图和代码上对Java类进行同步更改。
根据上面的背景介绍,为了构建一个服务组件来提供与建立个人证券账户相关的业务功能的服务,我们将构建一个名为 StockService的组件,该组件实现以下业务功能:
新增一个证券 |
新增一个证券类别 |
新增一条证券账户信息 |
新增一个股东 |
获得某个股东的所有证券信息列表 |
根据证券代码获得具有该证券的股东账户列表 |
获得所有的证券类别列表 |
为此,我们按照以下步骤创建Module项目以及相关的SDO和Interface。
我们为StockService服务组件示例创建一个新的workspace,例如,本文所用示例的workspace路径为: d:/workspace/soa。然后,切换到Business Integration视图下。
选择菜单File->New->Others打开新建项目窗口,选择Business Integration菜单中的Module,如下图所示:
将新建的Module命名为:StockModule,如下图所示:
作为构建StockService的基础,我们须根据类图定义模块所需的SDOs:
id | string | 证券类别代码 |
stkTypeName | string | 证券类别名称 |
stockTypes[] | StockType | 证券类别列表 |
id | string | 证券代码 |
stkName | string | 证券名称 |
stkType | StockType | 证券类别 |
stocks[] | Stock | 证券列表 |
stock | Stock | 证券 |
currentPrice | double | 当前价格 |
highestPrice | double | 最高价 |
lowestPrice | double | 最低价 |
id | string | 股东代码 |
name | string | 股东姓名 |
gender | string | 性别 |
idCardNum | string | 身份证号码 |
string | 电子邮箱 | |
address | string | 地址 |
stockHolder | StockHolder | 股东信息 |
stock | Stock | 股东所拥有的证券信息 |
balance | int | 当前余额 |
profit | double | 盈余 |
stockMemo | StockMemo | 证券价格信息 |
比较复杂的是StockAccount,下图反映了StockAccount与StockHolder,Stock,StockMemo之间的引用关系:
该接口将定义清单-1中所列的业务功能,我们将该接口命名为:StockServiceInterface,创建完毕的接口如下图所示:
StockModule项目在Business Integration视图下犹如下图所示:
双击图-7中的红色部分,打开StockModule的Assembly Diagram,右键单击StockService,在弹出菜单中选择Add->Interface,将StockServiceInterface加入到StockService组件中。
图-8:StockModule的Assembly Diagram:
在图-8所示的Assembly Diagram中,在StockService组件上点右键弹出的菜单中,选择export分别为该组件导出Web service绑定,命名为StockServiceExport,然后为StockService增加一个Stand-alone References,以使得StockService 组件具有为本地客户端提供服务的能力。
图-8:为StockService导出的Web service绑定
在图-8所示的Assembly Diagram所示的StockService组件上点右键弹出的菜单中,选择Generate Implementation (如果已经生成过Java实现,则为Regenerate Implementation)来自动生成Java实现代码。
在弹出的窗口中,为生成的代码选择所在的package。图-11中所示,请选择module.stock.implementation:
生成以后的Assembly Diagram有一些变化,在StockService组件的图示上会增加一个J的标志,表示是Java implementation, 如图-12所示:
图-12: 生成Java实现后的Assembly Diagram
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以使用面向对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序实用,也可以在Servlet/JSP的Web应用中使用。本文讨论的在对SCA模块的实现时,我们使用Hibernate实现SCA的持久层。
使用Hibernate之后,StockService模块,SDO,Java Bean, DB之间的关系可以总结为以下图示:
您可以到http://www.hibernate.org网站上下载Hibernate。本文的示例使用的是3.2.0版本,您可以到下列地址下载hibernate-3.2.0.ga.zip:
http://prdownloads.sourceforge.net/hibernate/hibernate-3.2.0.ga.zip?download 下载后解压到本地磁盘。
2.在StockModule项目中配置Hibernate运行环境
在第一部分,我们已经为StockService模块生成实现代码,我们需要将其中的每个方法予以实现。实现类名为: module.stock.implementation.StockServiceImpl,我们将把相关的Java对象和Hibernate对象放到同一级路经下,即:module.stock.implementation,这个包所在的文件夹路径为:
StockModule/gen/src/module/stock/implementation
将运行Hibernate所需要的jar添加到Java Build Path中
在StockModule项目文件夹中新建一个lib目录,将以下jar包从hibernate解压之后的目录拷贝到StockModule/lib目录下:
- antlr-2.7.6.jar
- asm.jar
- cglib-2.1.3.jar
- commons-collections-2.1.1.jar
- commons-logging-1.0.4.jar
- dom4j-1.6.1.jar
- hibernate3.jar
- jta.jar
- log4j-1.2.11.jar
然后,在StockModule项目的Properties中,点击”Add JARs”按钮,将这些包添加到StockModule项目的Java Build Path中,添加以后如图-14所示:
图-14:将Hibernate所需的Jar包添加到Java Build Path中
配置数据库连接信息
将StockModule发布到WID中的Websphere Process Server v6.0,然后在管理控制台增加名称为jdbc/localdb的JNDI配置,并保证测试连接成功:
Step1: 设置DB2_JDBC_DRIVER_PATH,指定DB2 JDBC驱动的位置
例如:C:/Program Files/IBM/SQLLIB/java
Step2: 新建J2C认证信息
在Security -> Global security -> JAAS Configuration -> J2C Authentication data中,新增J2C认证信息,这里的用户名和密码是为登录数据用的。
Step3: 新增JDBC Providers:DB2 Legacy CLI-based Type 2 JDBC Driver
选择Resources -> JDBC Providers 菜单,点击New按钮:
保存之后,在其Data Sources属性中,新增jndi_localdb的JNDI配置:
在module.stock.implementation目录中创建hibernate.cfg.xml并进行配置
主要配置以下几项:
hibernate.connection.datasource:jdbc/localdb(JNDI名称)
connection.pool_size:1
dialect:org.hibernate.dialect.DB2Dialect
show_sql:true(将Hibernate生成的SQL语句以SystemOut的方式输出到日志中)
mapping resource:引入Hibernate映射文件
配置完毕的hibernate.cfg.xml文件如下表:
- <?xmlversion='1.0'encoding='utf-8'?>
- <!DOCTYPEhibernate-configurationPUBLIC
- "-//Hibernate/HibernateConfigurationDTD3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
- <hibernate-configuration>
- <session-factory>
- <!--Databaseconnectionsettings,weusejndihere-->
- <propertyname="hibernate.connection.datasource">
- jdbc/localdb</property>
- <propertyname="connection.pool_size">1</property>
- <!--SQLdialect-->
- <propertyname="dialect">
- org.hibernate.dialect.DB2Dialect</property>
- <!--EnableHibernate'sautomaticsessioncontextmanagement-->
- <propertyname="current_session_context_class">
- thread</property>
- <!--Disablethesecond-levelcache-->
- <propertyname="cache.provider_class">
- org.hibernate.cache.NoCacheProvider</property>
- <!--EchoallexecutedSQLtostdout-->
- <propertyname="show_sql">true</property>
- <mappingresource=
- "/gen/src/module/stock/implementation/Stock.hbm.xml"/>
- <mappingresource=
- "/gen/src/module/stock/implementation/StockType.hbm.xml"/>
- <mappingresource=
- "/gen/src/module/stock/implementation/StockAccount.hbm.xml"/>
- <mappingresource=
- "/gen/src/module/stock/implementation/StockHolder.hbm.xml"/>
- <mappingresource=
- "/gen/src/module/stock/implementation/StockMemo.hbm.xml"/>
- </session-factory>
- </hibernate-configuration>
该文件将在实例化SessionFactory的时候被引用,Hibernate将根据此文件创建数据库连接池,并根据其中的mapping 定义建立*.hbm.xml与JavaBean之间的映射关系。有关SessionFactory,请参考实现StockService模块一节的内容。
在本文所附的StockModule.rar中,在StockModule/gen/src/module/stock/implementation路径下包含一个名为 create_db_objects.sql的文件,运行db2cmd并连接到sample数据库上,
db2 connect to sample
然后使用下列命令提交create_db_objects.sql文件来创建所需的表:
db2 –td; -f create_db_objects.sql
项目中还有一个init_db_objects.sql文件来向所创建的表中插入一些测试数据,请执行下列命令:
db2 –td; -f init_db_objects.sql
在创建图-2所示的类图的同时,我们已经创建了下列JavaBean:
- module.stock.implementation.StockType
- module.stock.implementation.StockMemo
- module.stock.implementation.StockHolder
- module.stock.implementation.StockAccount
- module.stock.implementation.Stock
使用WebSphere Integration Developer,程序员能够以模型驱动的方式在建模的过程中创建类图和对应的Java类。
Hibernate映射文件定义的是数据库表的字段和JavaBean的属性之间的映射关系,这种映射关系除了一般字段与字段的直接对应关系外,还包括表与表之间的多对一,一对多,多队多的对应关系。Hibernate将根据这些映射文件,自动生成SQL语句,并把从数据库中取得的对象填充到JavaBean的简单属性或复杂属性中。
这一节中,我们将介绍如何为本例中的各个JavaBean构造Hibernate映射文件,并将揭示以下技巧:
- 如何映射id主键以及id值的生成方法
- 如何使用数据库提供的sequence对象生成id
- 如何映射多对一关系
- 如何定义组合主键映射
创建StockType.hbm.xml – 最一般的情形
StockType是最简单的JavaBean,没有复杂的映射关系,StockType.hbm.xml定义StockType这个JavaBean和数据库表StockType之间的映射关系:
CREATE TABLE stockType( id VARCHAR(10) NOT NULL, typeName VARCHAR(20), CONSTRAINT pk_stockType PRIMARY KEY(id) ); |
package module.stock.implementation; import java.io.Serializable; public class StockType implements Serializable { private String id; private String typeName; //Getters and setters… … … } |
- <?xmlversion="1.0"?>
- <!DOCTYPEhibernate-mappingPUBLIC
- "-//Hibernate/HibernateMappingDTD3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mappingpackage="module.stock.implementation">
- <classname="StockType"table="StockType"
- lazy="true">
- <comment>StockTypetable</comment>
- <idname="id">
- <generatorclass="assigned"/>
- </id>
- <propertyname="typeName"/>
- </class>
- </hibernate-mapping>
- package: 指明 class name=”StockType”所代表的JavaBean的package路径。
- table: 指明与StockType JavaBean建立映射关系的表名。
- comment: 对此映射文件的注释
- id: 主健定义,必须唯一,如果StockType表中的字段名不是id,则需要用column=”idName”来说明,例如:<id name="id" column="idName">
- generator: 指定主键值的产生算法,assigned为用户指定。可供选择的还有: sequence(使用数据库提供的sequence对象,Oracle, DB2等数据库支持,本例将用到sequence), increment, identity, hilo, seqhilo, uuid, guid, native,select foreign等,关于这些id生成算法的具体情况,请参考Hibernate reference documentation。
- property:指定JavaBean属性与数据表字段之间的映射,如果列名与JavaBean属性名不相同,则需要增加column=”” 来说明。如<property name="typeName" column="name"/>。
创建Stock.hbm.xml – 定义多对一关系
Stock(证券)类有一个stkType属性,类型为StockType(证券类别),一个证券类别可以有多个证券,多个证券可能属于同一个证券类别,所以它们之间的关系是多(Stock)对一(StockType)的关系,我们使用many-to-one来定义这种关系。其他字段直接映射即可。
CREATE TABLE stock( id VARCHAR(10) NOT NULL, stkName VARCHAR(40), stkTypeId VARCHAR(10), CONSTRAINT pk_stock PRIMARY KEY (id) ); |
清单-8:Stock类定义-6:StockType.hbm.xml定义
package module.stock.implementation; import java.io.Serializable; public class Stock implements Serializable { private String id; private String stkName; private String stkTypeId; private StockType stkType; //Getters and setters …… } |
清单-9:Stock.hbm.xml定义
- <?xmlversion="1.0"?>
- <!DOCTYPEhibernate-mappingPUBLIC
- "-//Hibernate/HibernateMappingDTD3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mappingpackage="module.stock.implementation">
- <classname="Stock"table="Stock"lazy="true">
- <comment>Stocktable</comment>
- <idname="id">
- <generatorclass="assigned"/>
- </id>
- <propertyname="stkName"/>
- <propertyname="stkTypeId"/>
- <many-to-onename="stkType"class="StockType"
- insert="false"update="false">
- <columnname="stkTypeId"/>
- </many-to-one>
- </class>
- </hibernate-mapping>
-many-to-one:定义stkType属性与StockType类之间的多对一关系。Name为Stock类的stkType属性,class指定该属性的类型, <column>指定在Stock表中与StockType进行连接的属性名,在本例中为stkTypeId。
创建StockHolder.hbm.xml – 使用数据库的sequence
StockHolder存放股东信息,该表中的主键id的值由一个用户定义的sequence产生,为了让Hibernate能够自动调用这个sequence的 nextval获取下一个值,我们必须指定id元素的generator的class为sequence,并且在param中指定sequence的名称,如清单-10所示:
- CREATETABLEStockHolder(
- idINTEGERNOTNULL,
- nameVARCHAR(40),
- genderCHAR(2),
- idCardNumVARCHAR(18),
- emailVARCHAR(50),
- addressVARCHAR(100),
- CONSTRAINTpk_stockHolderPRIMARYKEY(id)
- );
- CREATESEQUENCEstockHolder_seq
- STARTWITH1005
- INCREMENTBY1
- NOMAXVALUE
- NOCYCLE
- CACHE24;
public class StockHolder implements Serializable { private String id; private String name; private String gender; private String idCardNum; private String email; private String address; //Getters and setters …… } |
清单-12:StockHolder.hbm.xml定义
- <?xmlversion="1.0"?>
- <!DOCTYPEhibernate-mappingPUBLIC
- "-//Hibernate/HibernateMappingDTD3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mappingpackage="module.stock.implementation">
- <classname="StockHolder"table="StockHolder"
- lazy="true">
- <comment>StockHoldertable</comment>
- <idname="id">
- <generatorclass="sequence">
- <paramname="sequence">stockHolder_seq</param>
- </generator>
- </id>
- <propertyname="name"/>
- <propertyname="gender"/>
- <propertyname="idCardNum"/>
- <propertyname="email"/>
- <propertyname="address"/>
- </class>
- </hibernate-mapping>
StockMemo.hbm.xml – 使用identity
StockMemo表存放每个交易日的证券价格信息,StockMemo表的主键id在数据库中是一个identity的自增字段类型,因此在做Hibernate映射时,必须使用<generator class="native" />来对id的generator算法进行定义, native将使得Hibernate在插入数据时,使用数据库内置的identity属性来生成唯一的id值。
- CREATETABLEstockMemo(
- idINTEGERNOTNULL
- GENERATEDALWAYSASIDENTITY(STARTWITH1INCREMENTBY1),
- stockIdVARCHAR(10)NOTNULL,
- currentPriceDECIMAL(17,3),
- highestPriceDECIMAL(17,3),
- lowestPriceDECIMAL(17,3),
- tradeDateVARCHAR(10)defaultchar(currentdate),
- FOREIGNKEYfk_stockMemeo(stockId)
- REFERENCESStockONDELETENOACTION
- );
- publicclassStockMemoimplementsSerializable{
- privateStringid;
- privateStringstockId;
- privateStringcurrentPrice;
- privateStringhighestPrice;
- privateStringtradeDate;
- privateStockstock;
- //Gettersandsetters
- ……
- }
StockMemo类还有一个stock属性,类型为Stock,很明显对应于stockId,StockMemo与Stock之间是多对一的关系,因此,我们使用 many-to-one元素来定义stock属性。如清单-13所示:
- <?xmlversion="1.0"?>
- <!DOCTYPEhibernate-mappingPUBLIC
- "-//Hibernate/HibernateMappingDTD3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mappingpackage="module.stock.implementation">
- <classname="StockMemo"table="StockMemo"
- lazy="true">
- <comment>Stockmemotable</comment>
- <idname="id">
- <generatorclass="native"/>
- </id>
- <propertyname="stockId"/>
- <propertyname="currentPrice"/>
- <propertyname="highestPrice"/>
- <propertyname="lowestPrice"/>
- <propertyname="tradeDate"/>
- <many-to-onename="stock"class="Stock"
- insert="false"update="false">
- <columnname="stockId"/>
- </many-to-one>
- </class>
- </hibernate-mapping>
StockAccount.hbm.xml – 使用compose-id和多个many-to-one映射
StockAccount类比较复杂,对应的Accout表存放的是股东拥有证券的情况,除了要对stockHolderId, stockId, balance, profit等四个一般属性进行映射外,还必须为三个复杂数据类型的属性进行映射。
在定义映射关系之前,需要明确StockAccount与StockHolder,Stock以及StockMemo之间的对应关系:
- 一个股东可以买卖多个证券,因此StockAccount与StockHolder之间是多对一关系
- 一个证券可以被多个股东所买卖,因此StockAccount与Stock之间是多对一关系
- 一个证券在不同的交易日有不同的价格,因此StockMemo与Stock之间是多对一关系
- 值得注意的是通过StockAccount,我们实际上定义了StockHolder与Stock之间的多对多关系。
清单-16:Account表定义
- CREATETABLEaccount(
- stockHolderIdINTEGERNOTNULL,
- stockIdVARCHAR(10)NOTNULL,
- balanceINT,
- profitDECIMAL(17,3),
- FOREIGNKEYfk_account1(stockHolderId)
- REFERENCESStockHolderONDELETENOACTION,
- FOREIGNKEYfk_account2(stockId)
- REFERENCESstockONDELETENOACTION
- );
对于Account表,stockHolderId和stockId组合可以被视为该表的主键,这一点将使用composite-id元素在Hibernate映射文件中进行表达。
清单-17:StockAccount类定义
- publicclassStockAccountimplementsSerializable{
- privateStringstockHolderId;
- privateStringstockId;
- privateintbalance;
- privatefloatprofit;
- privateStockHolderstockHolder;
- privateStockstock;
- privateStockMemostockMemo;
- //Gettersandsetters
- ......
- publicbooleanequals(StockAccountsa){
- booleanisEquals=false;
- if(sa!=null){
- if(stockHolder.getId().equals(sa.getStockHolder().getId())&
- stockHolder.getIdCardNum().equals(
- sa.getStockHolder().getIdCardNum())&
- stock.getId().equals(sa.getStock().getId())&
- stock.getStkName().equals(sa.getStock().getStkName())
- )
- isEquals=true;
- }
- returnisEquals;
- }
- publicinthashCode(){
- inth=0;
- h=stockHolder.hashCode()+19*stock.hashCode();
- returnh;
- }
- }
- <aname="<?xmlversion="1.0"?>
- <!DOCTYPEhibernate-mappingPUBLIC
- "-//Hibernate/HibernateMappingDTD3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mappingpackage="module.stock.implementation">
- <classname="StockAccount"table="Account"lazy="true">
- <comment>StockAccounttable</comment>
- <composite-id>
- <key-propertyname="stockHolderId"/>
- <key-propertyname="stockId"/>
- </composite-id>
- <many-to-onename="stockHolder"class="StockHolder"
- insert="false"update="false">
- <columnname="stockHolderId"/>
- </many-to-one>
- <many-to-onename="stock"class="Stock"
- insert="false"update="false">
- <columnname="stockId"/>
- </many-to-one>
- <many-to-onename="stockMemo"class="StockMemo"
- insert="false"update="false">
- <columnname="stockId"/>
- </many-to-one>
- <propertyname="balance"/>
- <propertyname="profit"/>
- </class>
- </hibernate-mapping>
- "></a>
-composite-id定义了一个由stockHolderId和stockId组成的组合主键。和一般id不同,在包含composite-id的持久类中,必须重载equals()和hashCode()这两个方法。如上面的清单-15所示。
-三个many-to-one元素,把stockHolder, stock和stockMemo分别映射到StockHolder类,Stock类和StockMemo类上。
StockServiceImp是StockService模块的实现类,我们使用Hibernate充当数据访问服务层,通过JavaBean可以很方便的实现底层数据与SDO之间的交换。
图-18 SDO,JavaBean与数据库的交互过程
首先,我们需要创建一个叫做HibernateUtil的类,如清单-17所示,它以Singleton的模式实例化一个SessionFactory,为Hibernate API调用提供基础。在实例化SessionFactory时,指定hibernate.xfg.xml配置文件(见清单-3)。
清单-19: HibernateUtil.java
- publicclassHibernateUtil{
- privatestaticfinalSessionFactorysessionFactory;
- static{
- try{
- //CreatetheSessionFactoryfromhibernate.cfg.xml
- sessionFactory=newConfiguration()
- .configure("/gen/src/module/stock/implementation/hibernate.cfg.xml")
- .buildSessionFactory();
- }catch(Throwableex){
- System.err.println("InitialSessionFactorycreationfailed."+ex);
- thrownewExceptionInInitializerError(ex);
- }
- }
- publicstaticSessionFactorygetSessionFactory(){
- returnsessionFactory;
- }
- }
然后,实现addStock, addStockType,getStockTypeList等一系列方法。限于篇幅,本文只介绍两个典型的方法 addStockAccount和getStockList的实现,这两个方法的实现包括了实现其他几个方法会涉及到的问题。
1) addStockAccount方法:
该方法的功能是:将StockHolder SDO和Stock SDO以及stock的数量qty等数据存储到account表中,业务上表现为股东StockHolder买进数量为qty的Stock类证券。
输入参数有三个:
- DataObject stockHolder, 股东信息
- DataObject stock,证券信息
- Integer qty,买入的证券数量
我们的方法是把DataObject中的数据转换到JavaBean中,然后再利用Hibernate,把数据持久化到DB中,代码如清单-18所示:
清单-20:addStockAccount的实现代码
- publicStringaddStockAccount(DataObjectstockHolder,DataObjectstock,Integerqty){
- Stringmessage=null;
- if(stockHolder!=null&&stock!=null){
- try{//得到SessionFactory的实例
- Sessionsession=HibernateUtil.getSessionFactory().getCurrentSession();
- //这一句是必需的,表明Transaction的开始
- session.beginTransaction();
- //将输入参数DataObject分别转换为JavaBean
- StockHoldersh=convertToStockHolder(stockHolder);
- Stockst=convertToStock(stock);
- //新建一个StockAccountBean对象
- StockAccountsa=newStockAccount();
- //把入参都set进去
- sa.setStock(st);
- sa.setStockHolder(sh);
- sa.setStockHolderId(sh.getId());
- sa.setStockId(st.getId());
- sa.setBalance(qty.intValue());
- sa.setProfit(0);//初始化为0
- //调用session.persist()方法,指定StockAccount将被持久化
- session.persist("StockAccount",sa);
- //调用session.flush()方法将memory中的数据保存到数据库中
- session.flush();
- //关闭session
- session.close();
- message="StockAccountsavedsuccessfully!";
- }catch(Exceptione){
- e.printStackTrace();
- message="FailetosaveStockAccounttodatabase:"+e.getMessage();
- }
- }
- returnmessage;
- }
下面对上述代码进行简要说明:
- 首先,我们把输入参数中的两个DataObject转换为JavaBean:sh(StockHolder)和st(Stock)
对于StockHolder,我们定义以下方法来完成DataObject向JavaBean转化:
清单-21:convertToStockHolder(DataObject stockHolderBO)方法
- privateStockHolderconvertToStockHolder(DataObjectstockHolderBO){
- StockHolderstockHolder=null;
- if(stockHolderBO!=null){
- try{
- stockHolder=newStockHolder();
- stockHolder.setId(stockHolderBO.getString("id"));
- stockHolder.setName(stockHolderBO.getString("name"));
- stockHolder.setGender(stockHolderBO.getString("gender"));
- stockHolder.setIdCardNum(stockHolderBO.getString("idCardNum"));
- stockHolder.setEmail(stockHolderBO.getString("email"));
- stockHolder.setAddress(stockHolderBO.getString("address"));
- }catch(Exceptione){
- e.printStackTrace();
- stockHolder=null;
- }
- }
- returnstockHolder;
- }
同样,为Stock定义一个方法实现DataObject与JavaBean之间的相互转化,这里从略。
- 然后创建一个StockAccount的实例,并把StockHolder的实例sh和Stock的实例st 放到StockAccount类中。
- 最后调用Hibernate的Session.persiste等方法将StockAccount数据存储到数据库中。
清单-22所列的代码体现了Hibernate快速实现JavaBean到数据库持久层转化的能力。这里见不到任何与JDBC相关的操作,只是针对 JavaBean的OO操作,因为Hibernate已经为我们完成了底层的JDBC API调用。
清单-22:调用Hibernate API持久化JavaBean
- 1Sessionsession=HibernateUtil.getSessionFactory().getCurrentSession();
- 2session.beginTransaction();
- 3StockAccountsa=newStockAccount();
- …sa.setXXX(…)
- 4session.persist("StockAccount",sa);
- 5session.flush();
- 6session.close();
如果StockHolder所包含的股东信息在数据库中不存在,则在调用session.persist(“StockAccount”,sa);之前,需要调用以下方法,先将新的StockHolder信息存到数据库中:
session.persist(“StockHolder”,sh);
可以用下列方法判断StockHolder所包含的股东信息是否已经存在:
if(session.load(StockHolder.class, st.getId()) == null)
2) getStockList方法 – 演绎DB-JavaBean-SDO之路
该方法的功能是:根据股东代码idNum得到属于该股东的所有证券信息的详细列表,如清单-21所示:
清单-23: getStockList(String idNum)定义
- publicDataObjectgetStockList(StringidNum){
- DataObjectstockListBO=null;
- DataObjectstockBO=null;
- ArrayListstockList=newArrayList();
- if(idNum!=null){
- try{
- stockListBO=boFactory.create("http://StockModule/sdo","StockList");
- Sessionsession=HibernateUtil.getSessionFactory().getCurrentSession();
- session.beginTransaction();
- Iteratoriter;
- iter=session.createQuery(
- "selectsa.stockfromStockAccountsawheresa.stockHolder.id=?")
- .setString(0,idNum).iterate();
- while(iter.hasNext()){
- Stockstock=(Stock)iter.next();
- stockBO=convertToStockBO(stock);
- stockList.add(stockBO);
- }
- stockListBO.setList("stocks",stockList);
- session.close();
- }catch(Exceptione){
- e.printStackTrace();
- stockListBO=null;
- }
- }
- returnstockListBO;
- }
-boFactory是com.ibm.websphere.bo.BOFactory的一个实例,在StockServiceImpl的initialize方法中进行实例化, BOFactory是Business Object的实例化工厂,用来创建BO的实例。
完成StockService的实现后,使用WID提供的Module Test工具对模块进行测试。在Assembly Diagram中,点击StockService 模块右键菜单中的"Test Component",即可打开如图-19所示的模块测试界面,然后选择对应的操作并填写request入参,再点"continue"按钮运行测试。图-20显示了测试结果。
图-19:选择被测试方法并且填写request参数
图-20:测试结果
本文结合示例详细探讨了使用Hibernate构建SCA Module持久层的方法,并且在创建示例的过程中,使用了基于模型驱动的设计方法构建SCA Module和Java实现。
本文在使用Hibernate构建SCA Module的持久层时,结合示例探讨了处理O/R映射的各种情况的方法,包括如何正确定义id的 generator,如何定义many-to-one映射关系,如何定义composite-id,如何使用数据库内置的sequence和identity属性等。
在用Java对象实现SCA Module时,使用Hibernate构建SCA的持久层可以解耦SCA Module的Java实现和DBMS类型间的关系:通过修改配置 Hibernate的配置文件(hibernate.cfg.xml),即可与不同类型的数据库进行交互,而不用修改Java代码,这一特性可以使得 SCA Module的松耦合特性进一步加强。
StockModule.zip | 3954KB | HTTP |
相关推荐
一、背景二、先决条件三、创建示例项目四、引入Hibernate实现StockService组件五、总结下载参考资料本文将探讨在完成SCAModule建模后用Java对象进行实现时,如何采用Hibernate实现SCAModule的数据持久层为SDO提供...
先决条件导入示例项目引入iBATIS实现StockService组件总结下载参考资料在完成SCAModule建模后用Java对象进行实现时,采用Hibernate和采用iBATIS实现SCAModule的数据持久层,目的都是为SDO提供数据访问服务并加快SCA...
Tuscany SCA与Spring、Hibernate整合实例-简洁方法。为了控制大小,把项目lib中的jar都删了...
提供SCA核心框架CF源代码、IDL文件等,SCA采用SCA2.2.2标准
SCA100T加速度计中文详细使用说明书
soa sca服务构件架构spring构件实现方案
毕业论文,基于SCA的SOA架构研究与实现
使用C8051f系列单片机读取倾角传感器SCA100T的倾角数据,使用的是SPI读取,可以在lcd上实时显示倾角和重力分量
VTI SCA60 SCA60C 单轴倾角传感器 90度量程,0.5-4.5V模拟输出 特点: 1.单轴倾角传感器 2.测量范围1g(±90度) 3.单极5V供电,比例电压输出
SCA_EJB会话bean绑定规范,SCA_Java EE集成规范,SCA_JAVA构件实现规范,SCA_JAVA通用注解和API规范,SCA_JCA绑定规范,SCA_JMS绑定规范,SCA_SCA策略框架,SCA_Spring构件实现规范,SCA_Web服务绑定规范,SCA_WS-...
重要组成部分——核心框架的功能、实现方法。遵循SCA(Software Communica- tions Architecture)标准,作者就本身用C++所编写的domainprofile,devicemanager 等模块作了详细的介绍,包括部分具体的代码以及解释。...
Fortify SCA 安装使用手册
SCA算法实现,主要针对凸优化问题进行求解,可以在其他地方使用。
SCA100T中文资料 特征 Features • Dual axis inclination measurement (X and Y) • Measuring ranges ±30° SCA100T-D01 and± 90° SCA100T-D02 • 0.0025° resolution (10 Hz BW, 模拟输出) • Sensing ...
在文中将要讲的就是如何将一个外部的开源项目集成到基于SCA规范实现的服务框架中。注:ASF(ApplicationServiceFramework)是基于Tuscany作为解析内核,再次封装和扩展的符合SCA规范的服务框架,SCA基本元数据解析依赖...
中文SCA103T 数据手册,包含集中芯片的资料。两种输出接口,带温度测量
datasheet_sca3300-d01.pdf