??xml version="1.0" encoding="utf-8" standalone="yes"?> 对应SQL “field=value”表达?/p>
如:Expression.eq("name","Erica") 对应SQL“between”表达?/p>
如:Expression.between("age",new Integer(13),new Integer(50)); and关系l合Q如Q?/p>
Expression.add(Expression.eq("name","Erica"),Expression.add("sex",new Integer(1))) or关系l合Q如Q?/p>
Expression.or(Expression.eq("name","Erica"),Expression.add("sex",new Integer(1))) 作ؓ补充Q本Ҏ提供了原生SQL语法的支持,我们可以通过q个Ҏ直接通过SQL语句限定查询条g 下面的代码返回所有名UC"Erica"其实的记录: 上例对当前的TUser记录按照q龄q行分组。通过Projections.groupPropertyҎQ我们指定了用于分组的目标属?#8220;age”。生成的SQL语句Qselect this.age as y0_ from T_User this_group by this_.age?br />
另外Q对于多条gl合的统计、分l功能,我们可以借助ProjectionList完成Q下面的例子中,我们l计了各个年龄层ơ中的用h量:
]]>Criteria criteria=session.createCriteria(TUser.class);
criteria.add(Expression.eq("name","Erica"));
criteria.add(Expression.eq("sex",new Integer(1));
Criteria查询表达?br />
Criteria本n只是一个容器,具体的查询条件要通过Criteria.addҎd到Criteria实例中?br />
Ҏ
描述
Expression.eq
Expression.allEq
参数Z个Map对象Q其中包含了多个属?值对应关pR相当于多个Expression.eq关系的叠?/td>
Expression.gt
对应SQL“field>value”表达?/td>
Expression.ge
对应SQL“field>=value”表达?/td>
Expression.lt
对应SQL“field<value”表达?/td>
Expression.le
对应SQL“field<=value”表达?/td>
Expression.between
Expression.like
对应SQL"field like valule"表达?/td>
Expression.in
对应SQL“field in...”表达?/td>
Expression.eqproperty
用于比较两个属性之间的|对应SQL“field>field”
Expression.gtProperty
用于比较两个属性之间的|对应SQL“field>=field”
Expression.ltProperty
用于比较两个属性之间的|对应SQL"field<field"
Expression.leProperty
用于比较两个属性之间的|对应SQL"field<=field"
Expression.and
Expression.or
Expression.sql
Expression.sql("lower({alias}.name) like lower(?)","Erica%",Hibernate.STRING);
其中?{alias}"Hibernate在运行期使用当前兌的POJO别名替换
在Hibernate3中,引入了RestrictionscM为Expression的替代?br />
CZ查询
ExamplecdCCriteria接口Q同P它也可以用作Criteria的查询条件。Example的作用是Q根据已有对象,查找属性与之相W的其他对象?br />
Criteria criteria=session.CreateCriteria(TUser.class);
TUser exampleUser=new TUser();
exapleUser.getName("Erica");
criteria.add(Example.create(exampleUser));
List<TUser> list=criteria.list();
for(TUser user:list){
System.out.println(user.getName());
}
复合查询
Criteria criteria=session.createCriteria(TUser.class);
Criteria addrCriteria=criteria.createCriteria("addresses");
addrCriteria.add(Expression.like("addresses","%shanghai%"));
List<TUser> list = criteria.list();
for(TUser user:list){
System.out.println(user.getName());
Set<TAddress> addrSet=user.getAddresses();
for(TAddress addr:addrSet){
System.out.println(addr.getAddress());
}
}
DetachedCriteria
Hibernate2中,Criteria生命周期位于其宿主Session生命周期中,也就是说Q由某个session创徏的Criteria实例Q一旦session销毁,那么此Criteria实例也随之失效?br />
Hibernate3中引入了DetachedCriteriaQDetachedCriteria可以qsession实例独立存在Q这P我们可以将某些通用的Criteria查询条gq行抽离Q每ơ用时再与当前session实例l定以获得更好的代码重用效果?br />
DetachedCriteria deCriteria=DetachedCriteria.forClass(TUser.class);
deCriteria.add(Expression.eq("name","Erica"));
deCriteria.add(Expression.eq("sex",new Integer(1)));
Criteria criteria=deCriteria.getExecutableCriteria(session);
List<TUser> list=criteria.list();
for(TUser user:list){
System.out.println(user.getName());
}
DetachedCriteria aveAge=DetachedCriteria.forClass(TUser.class);
avgAge.setProjection(Projections.avg("age"));
Criteria criteria=session.createCriteria(TUser.class);
criteria.add(Subqueries.propertyGT("age",avgAge));
Criteria高Ҏ?br />
限定q回的记录范?/strong>
通过criteria.setFirstResult/setMaxResultsҎ可以限制一ơ查询返回的记录范围Q?br />
Criteria criteria=session.createCriteria(TUser.class);
//限定查询q回索结果中Q从100条结果开始的20条记?/span>
criteria.setFirstResult(100);
criteria.setMaxResults(20);
//
//
Criteria criteria=session.createCriteria(TUser.class);
criteria.add(Expression.eq("groupId",new Integer(2)));
criteria.addOrder(Order.asc("name"));
criteria.addOrder(Order.desc("groupId"));
分组与统?br />
在Hibernate3中,我们q可以通过Criteria完成分组和统计。分l、统计表辑ּ由Hibernate3新引入的Projections Classq行装?br />
Criteria criteria=session.createCriteria(TUser.class);
criteria.setProjection(Projections.groupProperty("age"));
List<TUser> list=criteria.list();
for(TUser user:list){
System.out.println(user);
}
ProjectionList projectionlist=Projections.ProjectionList();
projectionList.add(Projections.groupProperty("age"));
projectionList.add9Projections.rowCount());
Criteria criteria=session.createCriteria(TUser.class);
criteria.setProjection(projectionList);
]]>
主键兌Q?/strong>即两张表通过主键形成一对一映射关系?/p>
用户TUser与护照TPassport兌
TUer.hbm.xml
<hibernate-mapping>
<class
name="
TUser"
table="T_User">
<one-to-one
name="passport"
class="
TPassport"
cascade="all"
outer-join="true"/>
</class>
</hibernate-mapping>
TPassport.hbm.xml
<hibernate-mapping>
<class
name="
TPassport"
table="T_Passport">
<one-to-one
name="user"
class="
TUser"
constrain="true">
.
</class>
</hibernate-mapping>
试代码Q?br />
TUser user = new TUser();
user.setAge(new Integer(20));
user.setName("Carin");
TPassport passport = new TPassport();
passport.setSerial("PCN759386");
passport.setExpiry(new Integer(20080101));
//怺讄兌
passport.setUser(user);
user.setPassport(passport);
Transaction tx = sessioin.beginTransaction();
//׃TUsercȝone-to-one节点被设|成
//cascade=“all”其关联的passport对象被U联保存
session.save(user);
tx.commit();
TUser user=(TUser)Hibernate.load(TUser.class,new Integer(15));
System.out.println("User name=>"+user.getName());
System.out.println("Passport Serial=>"+user.getPassport().getSerial());
Hibernate:select tuser0_.id as id1_,
from T_USER tuser0_
left outer join
T_PASSPORT tpassport1_ on tuser0_.id=tpassport1_.id
where tuser0_.id=?
User name=>Carin
Passport Serial=>PCN759386
一对多兌
用户TUser和地址TAddress的一对多兌?br />
单向一对多兌
L方TUser的映配|:
<hibernate-mapping>
<class
name="
TUser"
table="t_user"
dynamic-update="true"
dynamic-insert="true">
.
<set
name="address"
table="t_address"
cascade="all"
order-by="zipcode asc">
<key column="user_id"/>
<one-to-many class="
TAddress">
</set>
</class>
</hibernate>
双向多对一兌
实际上是“一对多”?#8220;多对一”兌的组合。也是说我们必dL斚w|一对多关系的基上,在被控方配置与其对应的多对一兌?br />
TUser.hbm.xml
<hibernate-mapping>
<class
name="
TUser"
table="t_user"
dynamic-update="true"
dynamic-insert="true">
.
<set
name="address"
table="t_address"
lazy="false"
inverse="true"
cascade="all"
sort="unsorted"
order-by="zipcode asc">
<key column="user_id"/>
<one-to-many class="
TAddress"/>
</set>
.
</class>
</hibernate>
<hibernat-mapping>
<class
name="
TAddress"
table="t_address"
dynamic-update="false"
dynamic-insert="false">
.
<many-to-one
name="user"
class="TUser"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="user_id"
not-null="true"/>
.
</class>
</hibernate-mapping>
多对多关?br />
需要借助中间表来完成多对多映信息的保存?br />
׃多对多关联的性能不佳Q由于引入了中间表,一ơ读取操作需要反复多ơ查询)Q因此在设计中应该避免大量用。同Ӟ在多对多关系中,应根据情况,采取延迟加蝲机制来避免无谓的性能开销?br />
TGroup与TRole的多对多兌Q?br />
TGroup.hbm.xmlQ?br />
<hibernate-mapping>
<class
name="
TGroup"
table="t_group"
dynamic-update="false"
dynamic-insert="false">
.
<set
name="roles"
table="t_group_role"
lazy="false"
inverse="false"
cascade="save-update">
<key column="group_id"/>
<many-to-many
class="
TRole"
column="role_id"/>
</set>
.
</class>
</hibernate>
TRole.hbm.xmlQ?br />
<hibernate-mapping>
<class
name="
TRole"
table="t_role"
dynamic-update="false"
dynamic-insert="false">
.
<set
name="groups"
table="t_group_role"
lazy="false"
inverse="true"
cascade="save-update"
sort="unsorted">
<key column="role_id"/>
<many-to-many
class="
TGroup"
column="group_id"
outer-join="auto"/>
</set>
.
</class>
</hibernate>
]]>
]]>
<property name="addtime" column="add_time" type="date" not-null="true">
如果按照上面的提C?则发?生成的时?只能_到日,?2007-08-08,而我们需要的?2007-08-08 21:21:34
有h提示可以Ҏjava.sql.Datecd,我没试过,因ؓ在程序中用的多的?java.util.Date
其实,通过单的修改XML文g可以得?007-08-08 21:21:34
<property name="addTime">
<column name="add_time"
sql-type="datetime" not-null="true"/>
</property>
q样修改,应该更可以被大家所接受
在struts-config.xml的设计视图中可以选择"新增数据?QMyeclipse会弹出向导窗口,q里使用的缺省DataSource的Type?org.apache.struts.util.GenericDataSource"Q而用DBCP数据源的话需要改?org.apache.commons.dbcp.BasicDataSource"Q当然了通过Myeclipse插入的Struts框架中是~少DBCP的包的,好在Tomcat用的是q个Q因此能够在Tomcat\common\lib目录中找到需要的包:
1.commons-dbcp-1.2.1.jar
2.commons-pool-1.2.jar
在工E的配置路径中加入即?也可以从apache的网站上 下蝲
Myeclipse的向导窗口中h一些属性栏Q在q里可以输入数据源用的Drivercd以及URLQ当然还有用户名/密码?br /> 属性栏全部都配|完毕后Q会在struts-config.xml文g中加?lt;data-sources>标签Q这里面?lt;data-source>x刚刚新徏的数据源配置参数Q这里需要手工更改:
1.增加<data-source>标签的type属性,q样 <data-source type="org.apache.commons.dbcp.BasicDataSource">Q?br /> 2.属性名 driverClass 改ؓ dirverClassNameQ?br /> 3.属性名 user 改ؓusernameQ注意n是小写的Q?br /> 4.L属性标{?loginTimeout?/p>
改完以后可以启动Tomcat看效果了
(1)所有数据都应该隐藏在所在的cȝ内部。p13 |
(2)cȝ使用者必M赖类的共有接口,但类不能依赖它的使用者。p15 |
(3)量减少cȝ协议中的消息。p16 |
(4)实现所有类都理解的最基本公有接口[例如Q拷贝操?深拷贝和拷?、相{性判断、正输出内宏V从ASCII描述解析{等]?p16 |
(5)不要把实现细?例如攄q代码的私有函?攑ֈcȝ公有接口中。p17 |
如果cȝ两个Ҏ有一D公׃码,那么可以创Z个防止这些公׃码的U有函数?/td> |
(6)不要以用h法用或不感兴趣的东西扰q的公有接口。p17 |
(7)cM间应该零耦合Q或者只有导合关系。也卻I一个类要么同另一个类毫无关系Q要么只使用另一个类的公有接口中的操作?p18 |
(8)cd该只表示一个关键抽象。p19 |
包中的所有类对于同一cL质的变化应该是共同闭的。一个变化若对一个包影响Q则对包中的所有类产生影响Q而对其他的包不造成M影响 . |
(9)把相关的数据和行为集中放|。p19 |
设计者应当留意那些通过get之类操作从别的对象中获取数据的对象。这U类型的行ؓ暗示着q条l验原则被违反了?/td> |
(10)把不相关的信息放在另一个类?也即Q互不沟通的行ؓ)。p19 |
朝着E_的方向进行依? |
(11)保你ؓ之徏模的抽象概念是类Q而不只是对象扮演的角艌Ӏp23 |
(12)在水qx向上可能统一地分布系l功能,也即Q按照设计,层cd当统一地共享工作。p30 |
(13)在你的系l中不要创徏全能c?对象。对名字包含Driver、Manager、System、Susystem的类要特别多加小心。p30 |
规划一个接口而不是实C个接口?/td> |
(14)对公共接口中定义了大量访问方法的cd加小心。大量访问方法意味着相关数据和行为没有集中存放。p30 |
(15)对包含太多互不沟通的行ؓ的类多加心。p31 |
q个问题的另一表现是在你的应用E序中的cȝ公有接口中创Z很多的get和set函数?/td> |
(16)在由同用L面交互的面向对象模型构成的应用程序中Q模型不应该依赖于界面,界面则应当依赖于模型。p33 |
(17)可能地按照现实世界建模(我们常常Z遵守pȝ功能分布原则、避免全能类原则以及集中攄相关数据和行为的原则而违背这条原? 。p36 |
(18)从你的设计中去除不需要的cRp38 |
一般来_我们会把q个c降U成一个属性?/td> |
(19)去除pȝ外的cRp39 |
pȝ外的cȝ特点是,抽象地看它们只往pȝ领域发送消息但q不接受pȝ领域内其他类发出的消息? |
(20)不要把操作变成类。质疑Q何名字是动词或者派生自动词的类Q特别是只有一个有意义行ؓ的类。考虑一下那个有意义的行为是否应当迁Ud已经存在或者尚未发现的某个cM。p40 |
(21)我们在创建应用程序的分析模型时常常引入代理类。在设计阶段Q我们常会发现很多代理没有用的,应当去除。p43 |
(22)量减少cȝ协作者的数量。p52 |
一个类用到的其他类的数目应当尽量少? |
(23)量减少cd协作者之间传递的消息的数量。p55 |
(24)量减少cd协作者之间的协作量,也即Q减类和协作者之间传递的不同消息的数量。p55 |
(25)量减少cȝ扇出Q也卻I减少cd义的消息数和发送的消息数的乘积。p55 |
(26)如果cd含另一个类的对象,那么包含cd当给被包含的对象发送消息。也卻I包含关系L意味着使用关系。p55 |
(27)cM定义的大多数Ҏ都应当在大多数时间里使用大多数数据成员。p57 |
(28)cd含的对象数目不应当超q开发者短期记忆的定w。这个数目常常是6。p57 |
当类包含多于6个数据成员时Q可以把逻辑相关的数据成员划分ؓ一l,然后用一个新的包含类d含这一l成员? |
(29)让系l功能在H而深的承体pM垂直分布。p58 |
(30)在实现语义约束时Q最好根据类定义来实现。这常常会导致类泛滥成灾Q在q种情况下,U束应当在类的行Z实现Q通常是在构造函C实现Q但不是必须如此。p60 |
(31)在类的构造函C实现语义U束Ӟ把约束测试放在构造函数领域所允许的尽量深的包含层ơ中。p60 |
(32)U束所依赖的语义信息如果经常改变,那么最好放在一个集中式的第3方对象中。p60 |
(33)U束所依赖的语义信息如果很改变,那么最好分布在U束所涉及的各个类中。p60 |
(34)cdȝ道它包含什么,但是不能知道谁包含它。p61 |
(35)׃n字面范围(也就是被同一个类所包含)的对象相互之间不应当有用关pRp61 |
(36)l承只应被用来ؓ特化层次l构建模。p74 |
(37)zcdȝ道基c,基类不应该知道关于它们的zcȝM信息。p74 |
(38)基类中的所有数据都应当是私有的Q不要用保护数据。p75 |
cȝ设计者永q都不应该把cȝ使用者不需要的东西攑֜公有接口中? |
(39)在理ZQ承层ơ体pd当深一点,深好。p77 |
(40)在实践中Q承层ơ体pȝ深度不应当超Z个普通h的短期记忆能力。一个广为接受的深度值是6。p77 |
(41)所有的抽象c都应当是基cRp81 |
(42)所有的基类都应当是抽象cRp82 |
(43)把数据、行为和/或接口的共性尽可能地放到承层ơ体pȝ高端。p85 |
(44)如果两个或更多个cd享公共数?但没有公p?Q那么应当把公共数据攑֜一个类中,每个׃nq个数据的类都包含这个类?p88 |
(45)如果两个或更多个cL共同的数据和行ؓ(是Ҏ)Q那么这些类的每一个都应当从一个表CZq些数据和方法的公共基类l承?p89 |
(46)如果两个或更多个cd享公共接?指的是消息,而不是方?Q那么只有他们需要被多态地使用Ӟ他们才应当从一个公共基cȝѝ?p89 |
(47)对对象类型的昄的分情况分析一般是错误的。在大多数这L情况下,设计者应当用多态。p89 |
(48)对属性值的昄的分情况分析常常是错误的。类应当解耦合成一个承层ơ结构,每个属性值都被变换成一个派生类?p96 |
(49)不要通过l承关系来ؓcȝ动态语义徏模。试囄静态语义关pL为动态语义徏模会D在运行时切换cd。p97 |
(50)不要把类的对象变成派生类。对M只有一个实例的zc都要多加小心。p99 |
(51)如果你觉得需要在q行时刻创徏新的c,那么退后一步以认清你要创徏的是对象。现在,把这些对象概括成一个类?p103 |
(52)在派生类中用I方?也就是什么也不做的方?来覆写基cM的方法应当是非法的。p103 |
(53)不要把可选包含同对承的需要相h。把可选包含徏模成l承会带来泛滥成灄cRp108 |
(54)在创建承层ơ时Q试着创徏可复用的框架Q而不是可复用的组件。p112 |
(55)如果你在设计中用了多重l承Q先假设你犯了错误。如果没犯错误,你需要设法证明。p120 |
(56)只要在面向对象设计中用到了承,问自׃个问题:(1)zcL否是它承的那个东西的一个特D类型?(2)基类是不是派生类的一部分Qp121 |
(57)如果你在一个面向对象设计中发现了多重承关p,保没有哪个基类实际上是另一个基cȝzcRp122 |
(58)在面向对象设计中如果你需要在包含关系和关联关p间作出选择Q请选择包含关系。p123 |
(59)不要把全局数据或全局函数用于cȝ对象的薄记工作。应当用类变量或类Ҏ。p140 |
(60)面向对象设计者不应当让物理设计准则来破坏他们的逻辑设计。但是,在对逻辑设计作出决策的过E中我们l常用到物理设计准则?p149 |
(61)不要l开公共接口M改对象的状态。p164 |
<project name="timexdb">
<property name="hjar" value="WebRoot/WEB-INF/lib/hsqldb.jar" />
<property name="hclass" value="org.hsqldb.Server" />
<property name="hfile" value="-database.0 data/gogoudb" />
<property name="halias" value="gogou" />
<property name="hport" value="9005" />
<target name="starthsql">
<java fork="true"
classname="${hclass}"
classpath="${hjar}"
args="${hfile} -dbname.0 ${halias} -port ${hport}" />
</target>
<target name="execddl">
<sql classpath="${hjar}"
driver="org.hsqldb.jdbcDriver"
url="jdbc:hsqldb:hsql://localhost:${hport}/${halias}"
userid="sa"
password=""
print="yes">
-- SQL script for TimeX
-- Step 1: Drop objects if they exist
DROP TABLE Department IF EXISTS;
DROP TABLE Employee IF EXISTS;
DROP TABLE Timesheet IF EXISTS;
DROP INDEX TimesheetIndex IF EXISTS;
DROP INDEX DepartmentCodeIndex IF EXISTS;
DROP INDEX EmployeeIdIndex IF EXISTS;
DROP TABLE customer IF EXISTS;
DROP TABLE Item IF EXISTS;
DROP TABLE Item_subType IF EXISTS;
DROP TABLE Item_superType IF EXISTS;
DROP TABLE orders IF EXISTS;
-- Step 2: Create tables
CREATE TABLE Item_superType
(
superID BIGINT primary key,
superTypeName VARCHAR(20) NOT NULL
);
CREATE TABLE Item_subType
(
subID BIGINT primary key,
superID BIGINT,
subTypeName VARCHAR(20) NOT NULL,
FOREIGN KEY(superID) REFERENCES Item_superType(superID)
);
CREATE TABLE Item
(
itemID BIGINT primary key,
subID BIGINT,
itemName VARCHAR(20) NOT NULL,
Introduce VARCHAR(50) ,
Price VARCHAR(6) NOT NULL,
nowPrice VARCHAR(6) NOT NULL,
smallPicture VARCHAR(10) NOT NULL,
bigPicture VARCHAR(10) NOT NULL,
inTime datetime ,
newItem INT ,
Rebate INT ,
Hit INT ,
FOREIGN KEY(subID) REFERENCES Item_subType(subID)
);
CREATE TABLE customer
(
userID BIGINT IDENTITY,
username VARCHAR(20) NOT NULL,
Password VARCHAR(20) NOT NULL,
userCity VARCHAR(20) ,
userEmail VARCHAR(20) NOT NULL,
userAge INT ,
userSex INT
);
CREATE TABLE orders
(
orderID BIGINT IDENTITY,
consigneeName VARCHAR(20) NOT NULL,
consigneeAddress VARCHAR(20) NOT NULL,
Postalcode VARCHAR(6) NOT NULL,
Telephone VARCHAR(20) NOT NULL,
carryMethod VARCHAR(10) NOT NULL,
Orderdate datetime
);
CREATE TABLE visualOrder
(
id BIGINT IDENTITY,
itemID BIGINT,
userID BIGINT,
orderID BIGINT,
itemNumber BIGINT NOT NULL,
FOREIGN KEY(itemID) REFERENCES Item(itemID),
FOREIGN KEY(userID) REFERENCES customer(userID),
FOREIGN KEY(orderID) REFERENCES orders(orderID)
);
-- Step 3: Create indexes
CREATE UNIQUE INDEX visualOrderIndex ON visualOrder (userID);
CREATE UNIQUE INDEX ItemIndex ON Item (itemID);
CREATE UNIQUE INDEX userIdIndex ON customer (userId);
create view newItem_statistic as select * from item where item.newItem = 1;
create view saleItem_statistic as select * from item where item.Rebate = 1;
-- Step 4: Insert some reference and test data
INSERT INTO customer (userName, Password,userEmail)
VALUES ('kira', 'kira','xuguoliang@sina.com');
-- Step 5: Verify tables and test data look ok
SELECT * FROM customer;
</sql>
</target>
<target name="hsqldm">
<java fork="true" classpath="${hjar}" classname="org.hsqldb.util.DatabaseManagerSwing" />
</target>
<target name="sqltool">
<java fork="true" classpath="${hjar}" classname="org.hsqldb.util.SqlTool" args="localhost-sa" />
</target>
</project>