﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-紫蝶∏飛揚↗-文章分类-Hibernate</title><link>http://www.blogjava.net/algz/category/27462.html</link><description>Purple Butterfly Flying
QQ群:7101519
Flex,Ext,Spring,Hibernate,EOS,SpringSecurity,Struts
http://algz.googlecode.com/svn/trunk/</description><language>zh-cn</language><lastBuildDate>Thu, 28 Feb 2013 15:43:56 GMT</lastBuildDate><pubDate>Thu, 28 Feb 2013 15:43:56 GMT</pubDate><ttl>60</ttl><item><title>[转]hibernate之生成的和默认的属性值(使用generated刷新实体)</title><link>http://www.blogjava.net/algz/articles/395824.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Thu, 28 Feb 2013 01:55:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/395824.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/395824.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/395824.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/395824.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/395824.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 生成的和默认的属性值&nbsp;如果类的一个特定属性有着数据库生成的值，通常在第一次插入实体行的时候。典型的数据库生成的值是创建的时间戳 , 还有其它默认值等. &nbsp; &nbsp; &nbsp;每当hibernate给定义了已生成或默认属性的实体执行SQL INSERT或UPDATE时，它在插入默认值或生成值之后立即执行SELECT。因为设置了generated=always，hibern...&nbsp;&nbsp;<a href='http://www.blogjava.net/algz/articles/395824.html'>阅读全文</a><img src ="http://www.blogjava.net/algz/aggbug/395824.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2013-02-28 09:55 <a href="http://www.blogjava.net/algz/articles/395824.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Hibernate Annotation几种关联映射 虽然是转载,但仔细看还是很有帮助的.</title><link>http://www.blogjava.net/algz/articles/366838.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Tue, 20 Dec 2011 06:10:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/366838.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/366838.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/366838.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/366838.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/366838.html</trackback:ping><description><![CDATA[<div><div>Hibernate Annotation几种关联映射</div><div></div><div>一对一(One-To-One)</div><div></div><div>使用@OneToOne注解建立实体Bean之间的一对一关联。一对一关联有三种情况：(1).关联的实体都共享同样的主键，(2).其中一个实体通过外键关联到另一个实体的主键(注意要模拟一对一关联必须在外键列上添加唯一约束)，(3).通过关联表来保存两个实体之间的连接关系(要模拟一对一关联必须在每一个外键上添加唯一约束)。</div><div></div><div>&nbsp;</div><div></div><div>1.共享主键的一对一关联映射：</div><div></div><div>@Entity</div><div></div><div>@Table(name="Test_Body")</div><div></div><div>public class Body {</div><div></div><div>&nbsp; &nbsp;private Integer id;</div><div></div><div>&nbsp; &nbsp;private Heart heart;</div><div></div><div>&nbsp; &nbsp;@Id</div><div></div><div>&nbsp; &nbsp;public Integer getId() {</div><div></div><div>&nbsp; &nbsp; &nbsp; return id;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;public void setId(Integer id) {</div><div></div><div>&nbsp; &nbsp; &nbsp; this.id = id;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;@OneToOne</div><div></div><div>&nbsp; &nbsp;@PrimaryKeyJoinColumn</div><div></div><div>&nbsp; &nbsp;public Heart getHeart() {</div><div></div><div>&nbsp; &nbsp; &nbsp; return heart;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;public void setHeart(Heart heart) {</div><div></div><div>&nbsp; &nbsp; &nbsp; this.heart = heart;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>}</div><div></div><div>@Entity</div><div></div><div>@Table(name="Test_Heart")</div><div></div><div>public class Heart {</div><div></div><div>&nbsp; &nbsp;private Integer id;</div><div></div><div>&nbsp; &nbsp;@Id</div><div></div><div>&nbsp; &nbsp;public Integer getId() {</div><div></div><div>&nbsp; &nbsp; &nbsp; return id;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;public void setId(Integer id) {</div><div></div><div>&nbsp; &nbsp; &nbsp; this.id = id;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>}</div><div></div><div>通过@PrimaryKeyJoinColumn批注定义了一对一关联</div><div></div><div>&nbsp;</div><div></div><div>2.使用外键进行实体一对一关联：</div><div></div><div>@Entity</div><div></div><div>@Table(name="Test_Trousers")</div><div></div><div>public class Trousers {</div><div></div><div>&nbsp; &nbsp;@Id</div><div></div><div>&nbsp; &nbsp;public Integer id;</div><div></div><div>&nbsp; &nbsp;@OneToOne</div><div></div><div>&nbsp; &nbsp;@JoinColumn(name = "zip_id")</div><div></div><div>&nbsp; &nbsp;public TrousersZip zip;</div><div></div><div>}</div><div></div><div>@Entity</div><div></div><div>@Table(name="Test_TrousersZip")</div><div></div><div>public class TrousersZip {</div><div></div><div>&nbsp; &nbsp;@Id</div><div></div><div>&nbsp; &nbsp;public Integer id;</div><div></div><div>&nbsp; &nbsp;@OneToOne(mappedBy = "zip")</div><div></div><div>&nbsp; &nbsp;public Trousers trousers;</div><div></div><div>}</div><div></div><div>上面的例子是指Trousers通过Trousers的外键列zip_id和TrousersZip关联，@JoinColumn批注定义了联接列，该批注和@Column批注有点类似，但是多了一个名为referencedColumnName的参数。该参数定义了所关联目标实体中的联接列，注意，当referencedColumnName关联到非主键列的时候，关联的目标类必须实现Serializable，还要注意的是所映像的属性对应单个列（否则映射无效）</div><div></div><div>一对一关联可能是双向的，在双向关联中，有且仅有一端作为主体（owner）端存在：主体端负责维护联接列（即更新），对于不需要维护这种关系的从表则通过mappedNy属性进行声明。mappedBy的值指向主体的关联属性。例子中，mappedBy的值为zip。最后，不必也不能再在被关联端（ownedside）定义联接列了，因为已经在主体端声明了。</div><div></div><div>如果在主体没有声明@JoinColumn，系统自动进行处理：在主表（owner table）中将创建联接列，列名为：主体的关联属性名+下划线+被关联端的主键列名。上面的例子中是zip_id,因为Trousers中的关联属性名为zip，TrousersZip的主键是id。</div><div></div><div>&nbsp;</div><div></div><div>3.通过关联表定义一对一关联</div><div></div><div>@Entity</div><div></div><div>@Table(name="Test_People")</div><div></div><div>public class People {</div><div></div><div>&nbsp; &nbsp;@Id</div><div></div><div>&nbsp; &nbsp;public Integer id;</div><div></div><div>&nbsp; &nbsp;@OneToOne</div><div></div><div>&nbsp; &nbsp;@JoinTable(name ="TestPeoplePassports",</div><div></div><div>&nbsp; &nbsp; &nbsp; joinColumns =@JoinColumn(name="people_fk"),</div><div></div><div>&nbsp; &nbsp; &nbsp; inverseJoinColumns =@JoinColumn(name="passport_fk")</div><div></div><div>&nbsp; &nbsp;)</div><div></div><div>&nbsp; &nbsp;public Passport passport;</div><div></div><div>}</div><div></div><div>@Entity</div><div></div><div>@Table(name="Test_Passport")</div><div></div><div>public class Passport {</div><div></div><div>&nbsp; &nbsp;@Id</div><div></div><div>&nbsp; &nbsp;public Integer id;</div><div></div><div>&nbsp; &nbsp;@OneToOne(mappedBy = "passport")</div><div></div><div>&nbsp; &nbsp;public People people;</div><div></div><div>}</div><div></div><div>People通过名为TestPeoplePassports的关联表和Passport关联。该关联表拥有名为passport_fk的外键列，该外键指向Passport表，该信息定义为inverseJoinColoumns的属性值，而people_fk外键列指向People表，该信息定义为joinColumns的属性值。</div><div></div><div>这种关联可能是双向的，在双向关联中，有且仅有一端作为主体（owner）端存在：主体端负责维护联接列（即更新），对于不需要维护这种关系的从表则通过mappedNy属性进行声明。mappedBy的值指向主体的关联属性。例子中，mappedBy的值为passport。最后，不必也不能再在被关联端（ownedside）定义联接列了，因为已经在主体端声明了。</div><div></div><div>以上是一对一关联的三种形式，下面介绍多对一关联。</div><div></div><div>&nbsp;</div><div></div><div>&nbsp;</div><div></div><div>&nbsp;</div><div></div><div>多对一(Many-to-One)</div><div></div><div>使用@ManyToOne批注来实现多对一关联。</div><div></div><div>@ManyToOne批注有一个名为targetEntity的参数，该参数定义了目标实体名，通常不需要定义该参数，因为在大部分情况下默认值(表示关联关系的属性类型)就可以很好的满足需求了。不过下面这种情况下这个参数就显得有意义了：使用接口作为返回值而不是常见的实体。</div><div></div><div>@ManyToOne(targetEntity=CompanyImpl.class)</div><div></div><div>@JoinColoumn(name=&#8221;COPM_ID&#8221;)</div><div></div><div>Public Company getCompany(){</div><div></div><div>&nbsp; &nbsp;return company;</div><div></div><div>}</div><div></div><div>多对一的配置方式有两种：(1)通过@JoinColoumn映像(2)通过关联表的方式来映像</div><div></div><div>&nbsp;</div><div></div><div>(1) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 通过@JoinColoumn映射</div><div></div><div>SRD Framework中Company,Category例子：</div><div></div><div>Company：</div><div></div><div>@ManyToOne</div><div></div><div>&nbsp; &nbsp;@JoinColumn(name = "CATEGORY_OPTION_ID")</div><div></div><div>&nbsp; &nbsp;private Category category = null;</div><div></div><div>&nbsp; &nbsp;Category：</div><div></div><div>@DiscriminatorValue("Category")</div><div></div><div>public class Category extends Option {</div><div></div><div>}</div><div></div><div>(2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 通过关联表映射</div><div></div><div>通过@JoinTable批注定义关联表，该关联表包含了指回实体表的外键(通过@JoinTable.joinColoumns)以及指向目标实体表的外键(通过@JoinTable.inverseJoinColoumns)</div><div></div><div>@Entity</div><div></div><div>@Table(name="Test_TreeType")</div><div></div><div>public class TreeType {</div><div></div><div>&nbsp; &nbsp;private Integer id;</div><div></div><div>&nbsp; &nbsp;private String name;</div><div></div><div>&nbsp; &nbsp;private ForestType forestType;</div><div></div><div>&nbsp; &nbsp;@ManyToOne(fetch = FetchType.LAZY)</div><div></div><div>&nbsp; &nbsp;@JoinTable(name="Test_Tree_Forest",</div><div></div><div>&nbsp; &nbsp; &nbsp; joinColumns = @JoinColumn(name="tree_id"),</div><div></div><div>&nbsp; &nbsp; &nbsp; inverseJoinColumns = @JoinColumn(name="forest_id") )</div><div></div><div>public ForestType getForestType() {// forestType的getter，setter方法必须在这里，否则会出错</div><div></div><div>&nbsp; &nbsp; &nbsp; return forestType;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;public void setForestType(ForestType forestType) {</div><div></div><div>&nbsp; &nbsp; &nbsp; this.forestType = forestType;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;@Id</div><div></div><div>&nbsp; &nbsp;@GeneratedValue</div><div></div><div>&nbsp; &nbsp;public Integer getId() {</div><div></div><div>&nbsp; &nbsp; &nbsp; return id;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;public void setId(Integer id) {</div><div></div><div>&nbsp; &nbsp; &nbsp; this.id = id;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;public String getName() {</div><div></div><div>&nbsp; &nbsp; &nbsp; return name;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;public void setName(String name) {</div><div></div><div>&nbsp; &nbsp; &nbsp; this.name = name;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>}</div><div></div><div>@Entity</div><div></div><div>@Table(name="Test_ForestType")</div><div></div><div>public class ForestType {</div><div></div><div>&nbsp; &nbsp;private Integer id;</div><div></div><div>&nbsp; &nbsp;private String name;</div><div></div><div>&nbsp; &nbsp;private Set&lt;TreeType&gt; trees;</div><div></div><div>&nbsp; &nbsp;@OneToMany(mappedBy="forestType")</div><div></div><div>public Set&lt;TreeType&gt; getTrees() {// trees的getter，setter方法必须在这里，否则会出错</div><div></div><div>&nbsp; &nbsp; &nbsp; return trees;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;public void setTrees(Set&lt;TreeType&gt; trees) {</div><div></div><div>&nbsp; &nbsp; &nbsp; this.trees = trees;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;@Id @GeneratedValue</div><div></div><div>&nbsp; &nbsp;public Integer getId() {</div><div></div><div>&nbsp; &nbsp; &nbsp; return id;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;public void setId(Integer id) {</div><div></div><div>&nbsp; &nbsp; &nbsp; this.id = id;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;public String getName() {</div><div></div><div>&nbsp; &nbsp; &nbsp; return name;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp;public void setName(String name) {</div><div></div><div>&nbsp; &nbsp; &nbsp; this.name = name;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>}</div><div></div><div>&nbsp;</div><div></div><div>一对多(One-to-Many)</div><div></div><div>使用@OneToMany批注可定义一对多关联，一对多关联可以是双向关联。</div><div></div><div>在EJB3规范中多对一这端几乎总是双向关联中的主体(owner)端，而一对多这端关联批注为@OneToMany(mappedBy...)</div><div></div><div>@Entity</div><div></div><div>Public class Troop{</div><div></div><div>&nbsp; &nbsp;@OneToMany(mappedBy=&#8221;troop&#8221;)</div><div></div><div>Public Set&lt;Soldier&gt; getSoldiers(){</div><div></div><div>......</div><div></div><div>}</div><div></div><div>@Entity</div><div></div><div>Public class Soldier{</div><div></div><div>&nbsp; &nbsp;@ManyToOne</div><div></div><div>&nbsp; &nbsp;@JoinColumn(name=&#8221;troop_fk&#8221;)</div><div></div><div>Public Troop getTroop(){</div><div></div><div>......</div><div></div><div>}</div><div></div><div>Troop通过troop属性和Soldier建立一对多的双向关联，在mappedBy端不必也不能再定义任何物理映射。</div><div></div><div>对于一对多的双向映射，如果要一对多这一端维护关联关系，你需要删除mappedBy元素并将多对一这端的@JoinColoumn的insertable和updatabel设置为false。这种方案不会得到什么明显的优化，而且还会增加一些附加的UPDATE语句。</div><div></div><div>&nbsp;</div><div></div><div>单向：</div><div></div><div>通过在被拥有的实体端(owned entity)增加一个外键列来实现一对多单向关联是很少见的，也是不推荐的，建议通过一个联接表来实现这种关联(下面会讲到)。</div><div></div><div>@JoinColoumn批注来描述这种单向关联关系</div><div></div><div>@Entity</div><div></div><div>Public class Customer{</div><div></div><div>&nbsp; &nbsp;@OneToMany</div><div></div><div>@JoinColoumn(name=&#8221;CUST_ID&#8221;)</div><div></div><div>Public Set&lt;ticket&gt; getTickets() {</div><div></div><div>......</div><div></div><div>}</div><div></div><div>@Entity</div><div></div><div>Public class Ticket{</div><div></div><div>&nbsp; &nbsp;...</div><div></div><div>}</div><div></div><div>Customer通过CUST_ID列和Ticket建立了单向关联关系</div><div></div><div>通过关联表处理单向关联：</div><div></div><div>通过联接表处理单向一对多关联是首选方式，这种关联通过@JoinTable批注进行描述</div><div></div><div>@Entity</div><div></div><div>Public class Trainer{</div><div></div><div>@OneToMany</div><div></div><div>@JoinTable(</div><div></div><div>&nbsp; &nbsp;name = "TrainedMonkeys",</div><div></div><div>&nbsp; &nbsp;jonColumns = {@JoinColumn(name = "trainer_id")},</div><div></div><div>&nbsp; &nbsp;inverseJoinColumns = @JoinColumn(name = "monkey_id")</div><div></div><div>&nbsp; &nbsp;)</div><div></div><div>public Set&lt;Monkey&gt; getTrainedMonkeys() {</div><div></div><div>&nbsp; &nbsp; &nbsp; return trainedMonkeys;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>......</div><div></div><div>}</div><div></div><div>@Entity</div><div></div><div>public class Monkey {</div><div></div><div>...//no bidir</div><div></div><div>}</div><div></div><div>上面这个例子中，Trainer通过TrainedMonkeys表和Monkey建立了单向关联，其中外键trainer_id关联到Trainer(joinColoumn),而外键monkey_id关联到Monkey(inversejionColoumns)</div><div></div><div>默认处理机制：</div><div></div><div>通过联接表来建立单向一对多关联不需要描述任何物理映像，表名由以下三个部分组成：主表(ownertable)表名+从表(the other side table)表名，指向主表的外键名：主表表名+下划线+主表主键列名，指向从表的外键名：主表所对应实体的属性名+下划线+从表主键列名，指向从表的外键定义为唯一约束，用来表示一对多的关联关系。</div><div></div><div>@Entity</div><div></div><div>public class Trainer{</div><div></div><div>&nbsp; &nbsp;@OneToMany</div><div></div><div>&nbsp; &nbsp;Public Set&lt;Tiger&gt; getTrainedTigers(){</div><div></div><div>... ...</div><div></div><div>}</div><div></div><div>@Entity</div><div></div><div>public class Tiger{</div><div></div><div>.. ..//no bidir</div><div></div><div>}</div><div></div><div>上面这个例子中，Trainer和Tiger通过联接表Trainer_Tiger建立单向关联关系，其中外键trainer_id关联到Trainer,而外键trainedTigers_id关联到Tiger</div><div></div><div>&nbsp;</div><div></div><div>多对多(Many-to-Many)</div><div></div><div>使用@ManyToMany批注可定义多对多关联，同时，你也许要通过批注@JoinTable描述关联表和关联条件。如果是双向关联，其中一段必须定义为Owner，另一端必须定义为inverse(在对关联表进行更新操作时这一端将被忽略)</div><div></div><div>@Entity()</div><div></div><div>public class Employer implements Serializable {</div><div></div><div>&nbsp; &nbsp;private Integer id;</div><div></div><div>&nbsp; &nbsp;private Collection employees;</div><div></div><div>&nbsp; &nbsp;@ManyToMany(</div><div></div><div>targetEntity = org.hibernate.test.annotations.manytomany.Employee.class,</div><div></div><div>&nbsp; &nbsp; &nbsp; cascade = {CascadeType.PERSIST, CascadeType.MERGE}</div><div></div><div>&nbsp; &nbsp;)</div><div></div><div>&nbsp; &nbsp;@JoinTable(</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;name = "EMPLOYER_EMPLOYEE",</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;joinColumns = {@JoinColumn(name = "EMPER_ID")},</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;inverseJoinColumns = {@JoinColumn(name = "EMPEE_ID")}</div><div></div><div>&nbsp; &nbsp;)</div><div></div><div>&nbsp; &nbsp;public Collection getEmployees() {</div><div></div><div>&nbsp; &nbsp; &nbsp; return employees;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>...</div><div></div><div>}</div><div></div><div>@Entity()</div><div></div><div>public class Employee implements Serializable {</div><div></div><div>&nbsp; &nbsp;@ManyToMany(</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cascade = {CascadeType.PERSIST, CascadeType.MERGE},</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mappedBy = "employees"</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;targetEntity = Employer.class</div><div></div><div>&nbsp; &nbsp;)</div><div></div><div>public Collection&lt;Employer&gt; getEmployers() {</div><div></div><div>&nbsp; &nbsp; &nbsp; return employers;</div><div></div><div>&nbsp; &nbsp;}</div><div></div><div>.. ..</div><div></div><div>}</div><div></div><div>@JoinTable批注定义了联接表的表名，联接列数组，以及invers联接列数组，后者是关联表中关联到Employee主键的列(the &#8220;other side&#8221;)。</div><div></div><div>被关联端不必也不能描述物理映射：只需要一个简单的mappedBy参数，该参数包含了主体端的属性名，这样就绑定了双方的关系。</div><div></div><div>默认值：</div><div></div><div>和其它许多批注一样，在多对多关联中很多值是自动生成，党双向多对多关联中没有定义任何物理映射时，Hibernate根据以下规则生成相应的值，关联表名：主表表名+下划线+从表表名，关联到主表的外键名：主表名+下划线+主表中的主键列名，关联到从表的外键名：主表中用于关联的属性名+下划线+从表的主键列名，以上规则对于双向一对多关联同样一样。</div><div></div><div>&nbsp;</div><div></div><div>以上是整理的一点简单的几种映射，可参考EJB3.pdf中P111&#8212;&#8212;P131，hibernate_annotation.pdf 第二章</div><div></div><div>在这里没有具体的例子，有很多内容还需要仔细查看文档。</div></div><img src ="http://www.blogjava.net/algz/aggbug/366838.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2011-12-20 14:10 <a href="http://www.blogjava.net/algz/articles/366838.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate 注解映射 设置默认值的异常及解决方法</title><link>http://www.blogjava.net/algz/articles/365534.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Mon, 05 Dec 2011 01:21:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/365534.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/365534.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/365534.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/365534.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/365534.html</trackback:ping><description><![CDATA[<div><div>Oracle 数据库:<br />Hibernate&nbsp;annotation :<br /><div><div><span style="white-space:pre">	</span>@Column(name="NUMBERS",columnDefinition="NUMBER(20,3) default 0 ")</div><div><span style="white-space:pre">	</span>public BigDecimal getNumbers() {</div><div><span style="white-space:pre">		</span>return numbers;</div><div><span style="white-space:pre">	</span>}<br /><br />异常:</div></div>Caused by: org.hibernate.HibernateException: Wrong column type: NUMBERS, expected: NUMBER(20,3) default 0&nbsp;</div><div><span style="white-space:pre">	</span>at org.hibernate.mapping.Table.validateColumns(Table.java:261)</div><div><span style="white-space:pre">	</span>at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1083)</div><div><span style="white-space:pre">	</span>at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:116)</div><div><span style="white-space:pre">	</span>at org.hibernate.impl.SessionFactoryImpl.&lt;init&gt;(SessionFactoryImpl.java:317)</div><div><span style="white-space:pre">	</span>at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1294)</div><div><span style="white-space:pre">	</span>at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:915)</div><div><span style="white-space:pre">	</span>at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:730)</div><div><span style="white-space:pre">	</span>... 122 more<br />解决方法:<br /><div><div><span style="white-space:pre">	</span>@Column(name="NUMBERS",columnDefinition="number(20,3) default 0 ")</div><div><span style="white-space:pre">	</span>public BigDecimal getNumbers() {</div><div><span style="white-space:pre">		</span>return numbers;</div><div><span style="white-space:pre">	</span>}<br />原因:hibernate 在列定义选项中,数据库中的所有类型应为小写number. hibernate在此直接面对数据库,所以区分大小写.</div></div></div></div><img src ="http://www.blogjava.net/algz/aggbug/365534.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2011-12-05 09:21 <a href="http://www.blogjava.net/algz/articles/365534.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate 级联(联表)删除的问题</title><link>http://www.blogjava.net/algz/articles/364066.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Thu, 17 Nov 2011 04:47:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/364066.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/364066.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/364066.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/364066.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/364066.html</trackback:ping><description><![CDATA[<div><div>dao.getHibernateSession().createQuery(hql).setParameter("bookid", bookid).setParameter("batch", batch).executeUpdate();&nbsp;<br /><br />(1)String hql="delete&nbsp;from&nbsp;TbProduceplanaccount&nbsp;ppa&nbsp;where&nbsp;ppa.tbBusinessplanaccount.batch=:batch&nbsp;and&nbsp;ppa.tbProduceplanbook.id=:bookid ";<br />异常:<br /><div><div>Hibernate:&nbsp;delete&nbsp;from&nbsp;Tb_ProducePlanAccount,&nbsp;Tb_BusinessplanAccount&nbsp;tbbusiness1_&nbsp;where&nbsp;batch=?&nbsp;and&nbsp;ProducePlanBook_ID=?<br />2011-11-17&nbsp;11:50:16,166&nbsp;WARN&nbsp;&nbsp;[JDBCExceptionReporter]&nbsp;SQL&nbsp;Error:&nbsp;933,&nbsp;SQLState:&nbsp;42000<br />2011-11-17&nbsp;11:50:16,166&nbsp;ERROR&nbsp;[JDBCExceptionReporter]&nbsp;ORA-00933:&nbsp;SQL&nbsp;命令未正确结束&nbsp;<br /><br />(2)hql="delete from TbProduceplanaccount ppa where ppa in (from TbProduceplanaccount ppa where ppa.tbBusinessplanaccount.batch=:batch and ppa.tbProduceplanbook.id=:bookid)";</div><div><div><span class="Apple-style-span" style="white-space: pre;">执行正常.</span></div></div></div><br />总结: hibernate的理解方式与人不同,不能自动生成子查询;<span style="color: #99cc00; ">更新或删除操作是不允许联表的,必须通过子查询找出数据.</span><br />题外语:级联删除是要设置映射的.<br /><div><div></div></div></div></div><img src ="http://www.blogjava.net/algz/aggbug/364066.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2011-11-17 12:47 <a href="http://www.blogjava.net/algz/articles/364066.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate中*.hbm.xml文件让其自动读取数据库默认值</title><link>http://www.blogjava.net/algz/articles/323438.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Sat, 12 Jun 2010 07:41:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/323438.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/323438.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/323438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/323438.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/323438.html</trackback:ping><description><![CDATA[<p>在hibernate.xml中的class加入dynamic-insert="true" dynamic-update="true"</p>
<p>数据库中表字段必须设置默认值</p>
<p>如：&lt;class name="com.hibernate.bean" table="TABLE" schema="DATABASE" <span style="color: #339966">dynamic-insert="true" dynamic-update="true"</span> &gt;</p>
<p><br />
注：dynamic-insert="true" dynamic-update="true"　的作用是当HQL语句中未指明的列将不进行insert和update操作，这样hibernate就不会在未指明默认列的情况下将数据库表中默认值字段清空。<br />
</p>
 <img src ="http://www.blogjava.net/algz/aggbug/323438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2010-06-12 15:41 <a href="http://www.blogjava.net/algz/articles/323438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>could not initialize proxy - no Session</title><link>http://www.blogjava.net/algz/articles/262823.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Mon, 30 Mar 2009 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/262823.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/262823.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/262823.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/262823.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/262823.html</trackback:ping><description><![CDATA[<span style="font-size: small"><span class="Apple-style-span" style="color: rgb(75,75,75); line-height: 17px; font-family: verdana"><span style="font-size: x-small"><span style="font-size: x-small"><span style="font-size: x-small"><span style="font-size: x-small">org.hibernate.LazyInitializationException:&nbsp;<span style="color: rgb(128,0,0)"><span style="color: rgb(255,0,0)">could not initialize proxy - no Session<br />
</span></span></span></span></span></span></span></span><br />
原因:可能是HQL语句没有进行联表查询,产生访问的属性不存在.引用了没有联表查询的外键.<br />
<span style="font-size: small"><span class="Apple-style-span" style="color: rgb(75,75,75); line-height: 17px; font-family: verdana"><span style="font-size: x-small"><span style="font-size: x-small"><span style="font-size: x-small"><span style="font-size: small"><span style="font-size: small"><span style="font-size: x-small"><strong>(1)</strong>hibernate3&nbsp;many-to-one</span><span style="font-size: x-small">的默认选项是&nbsp;</span><span style="font-size: x-small">lazy = "proxy"</span></span></span><br />
<span style="font-size: small"><span style="font-size: small"><strong>解决方法：</strong></span></span><span style="font-size: small"><span style="font-size: small">&lt;many-to-one&gt;&nbsp;&nbsp;&amp; &lt;set&gt; 中设置&nbsp;</span></span><span style="font-size: small"><span style="font-size: small">lazy="false"</span></span></span></span></span></span></span>&nbsp; //影响性能<br />
<br />
(2)即from A,正确为:from A&nbsp;a left join fetch a.集合(外键)&nbsp;&nbsp; //灵活.
<img src ="http://www.blogjava.net/algz/aggbug/262823.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2009-03-30 10:02 <a href="http://www.blogjava.net/algz/articles/262823.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]正则表达式30分钟入门教程</title><link>http://www.blogjava.net/algz/articles/229762.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Thu, 18 Sep 2008 09:48:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/229762.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/229762.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/229762.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/229762.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/229762.html</trackback:ping><description><![CDATA[<h1>正则表达式30分钟入门教程</h1>
<p id="meta">版本：v2.3 (2008-4-13) 作者：<a href="http://www.unibetter.com/members/deerchao.aspx">deerchao</a> 转载请注明<a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm">来源</a></p>
<h2 id="contents">目录</h2>
<p class="note" id="skipContents"><a title="转到正文内容" href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#mission">跳过目录</a></p>
<ol>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#mission">本文目标</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#howtouse">如何使用本教程</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#introduction">正则表达式到底是什么东西？</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#getstarted">入门</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#testing">测试正则表达式</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#metacode">元字符</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#escape">字符转义</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#repeat">重复</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#charclass">字符类</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#alternative">分枝条件</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#negation">反义</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#grouping">分组</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#backreference">后向引用</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#lookaround">零宽断言</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#negativelookaround">负向零宽断言</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#commenting">注释</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#greedyandlazy">贪婪与懒惰</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#regexoptions">处理选项</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#balancedgroup">平衡组/递归匹配</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#more">还有些什么东西没提到</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#contact">联系作者</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#ad">最后,来点广告...</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#resources">网上的资源及本文参考文献</a>
    </li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#updatelog">更新说明</a> </li>
</ol>
<h2 id="mission">本文目标</h2>
<p>30分钟内让你明白正则表达式是什么，并对它有一些基本的了解，让你可以在自己的程序或网页里使用它。</p>
<h2 id="howtouse">如何使用本教程</h2>
<p class="important note" id="giveMe30Minutes">最重要的是&#8212;&#8212;请给我<em>30分钟</em>，如果你没有使用正则表达式的经验，请不要试图在30<em>秒</em>内入门&#8212;&#8212;除非你是超人 :)</p>
<p>别被下面那些复杂的表达式吓倒，只要跟着我一步一步来，你会发现正则表达式其实并<span lang="zh-cn">没有</span>你想像中的那么困难。当然，如果你看完了这篇教程之后，发现自己明白了很多，却又几乎什么都记不得，那也是很正常的&#8212;&#8212;我认为，没接触过正则表达式的人在看完这篇教程后，能把提到过的语法记住80%以上的可能性为零。这里只是让你明白基本的原理，以后你还需要多练习，多使用，才能熟练掌握正则表达式。</p>
<p>除了作为入门教程之外，本文还试图成为可以在日常工作中使用的正则表达式语法参考手册。就作者本人的经历来说，这个目标还是完成得不错的&#8212;&#8212;你看，我自己也没能把所有的东西记下来，不是吗？</p>
<p><a id="clearButton" onclick="return clearFormats();" href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm">清除格式</a>&nbsp;文本格式约定：<span class="name">专业术语</span>&nbsp;<span class="code">元字符/语法格式</span>&nbsp;<span class="regex">正则表达式</span>&nbsp;<span class="part">正则表达式中的一部分(用于分析)</span>&nbsp;<span class="string">对其进行匹配的源字符串</span>&nbsp;<span class="desc">对正则表达式或其中一部分的说明</span></p>
<p><a id="hideButton" onclick="return hideNotes();" href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm">隐藏边注</a>&nbsp;本文右边有一些注释，主要是用来提供一些相关信息，或者给没有程序员背景的读者解释一些基本概念，通常可以忽略。</p>
<h2 id="introduction">正则表达式到底是什么东西？</h2>
<p class="note"><span class="name">字符</span>是计算机软件处理文字时最基本的单位，可能是字母，数字，标点符号，空格，换行符，汉字等等。<span class="name">字符串</span>是0个或更多个字符的序列。<span class="name">文本</span>也就是文字，字符串。说某个字符串<span class="name">匹配</span>某个正则表达式，通常是指这个字符串里有一部分（或几部分分别）能满足表达式给出的条件。</p>
<p>在编写处理字符串的程序或网页时，经常会有查找符合某些复杂规则的字符串的需要。<span class="name">正则表达式</span>就是用于描述这些规则的工具。换句话说，正则表达式就是记录文本规则的代码。</p>
<p>很可能你使用过Windows/Dos下用于文件查找的<span class="name">通配符(wildcard)</span>，也就是<span class="code">*</span>和<span class="code">?</span>。如果你想查找某个目录下的所有的Word文档的话，你会搜索<span style="color: red;">*.doc</span>。在这里，<span class="code">*</span>会被解释成任意的字符串。和通配符类似，正则表达式也是用来进行文本匹配的工具，只不过比起通配符，它能更精确地描述你的需求&#8212;&#8212;当然，代价就是更复杂&#8212;&#8212;比如你可以编写一个正则表达式，用来查找<span class="desc">所有以0开头，后面跟着2-3个数字，然后是一个连字号&#8220;-&#8221;，最后是7或8位数字的字符串</span>(像<span class="string">010-12345678</span>或<span class="string">0376-7654321</span>)。</p>
<h2 id="getstarted">入门</h2>
<p>学习正则表达式的最好方法是从例子开始，理解例子之后再自己对例子进行修改，实验。下面给出了不少简单的例子，并对它们作了详细的说明。</p>
<p>假设你在一篇英文小说里查找<span class="desc">hi</span>，你可以使用正则表达式<span class="regex">hi</span>。</p>
<p>这几乎是最简单的正则表达式了，它可以精确匹配这样的字符串：<span class="desc">由两个字符组成，前一个字符是h,后一个是i</span>。通常，处理正则表达式的工具会提供一个忽略大小写的选项，如果选中了这个选项，它可以匹配<span class="string">hi</span>,<span class="string">HI</span>,<span class="string">Hi</span>,<span class="string">hI</span>这四种情况中的任意一种。</p>
<p>不幸的是，很多单词里包含<span class="string">hi</span>这两个连续的字符，比如<span class="string">him</span>,<span class="string">history</span>,<span class="string">high</span>等等。用<span class="regex">hi</span>来查找的话，这里边的<span class="string">hi</span>也会被找出来。如果要<span class="desc">精确地查找hi这个单词</span>的话，我们应该使用<span class="regex">\bhi\b</span>。</p>
<p><span class="part">\b</span>是正则表达式规定的一个特殊代码（好吧，某些人叫它<span class="name">元字符，metacharacter</span>），代表着<span class="desc">单词的开头或结尾，也就是单词的分界处</span>。虽然通常英文的单词是由空格，标点符号或者换行来分隔的，但是<span class="code">\b</span>并不匹配这些单词分隔字符中的任何一个，它<strong>只匹配一个位置</strong>。</p>
<p class="note">如果需要更精确的说法，<span class="code">\b</span>匹配这样的位置：它的前一个字符和后一个字符不全是(一个是,一个不是或不存在)<span class="code">\w</span>。</p>
<p>假如你要找的是<span class="desc">hi后面不远处跟着一个Lucy</span>，你应该用<span class="regex">\bhi\b.*\bLucy\b</span>。</p>
<p>这里，<span class="part">.</span>是另一个元字符，匹配<span class="desc">除了换行符以外的任意字符</span>。<span class="part">*</span>同样是元字符，不过它代表的不是字符，也不是位置，而是数量&#8212;&#8212;它指定*<span class="desc">前边的内容可以连续重复出现任意次以使整个表达式得到匹配</span>。因此，<span class="part">.*</span>连在一起就意味着<span class="desc">任意数量的不包含换行的字符</span>。现在<span class="regex">\bhi\b.*\bLucy\b</span>的意思就很明显了：<span class="desc">先是一个单词hi,然后是任意个任意字符(但不能是换行)，最后是Lucy这个单词</span>。</p>
<p class="note">换行符就是'\n',ASCII编码为10(十六进制0x0A)的字符。</p>
<p>如果同时使用其它元字符，我们就能构造出功能更强大的正则表达式。比如下面这个例子：</p>
<p><span class="regex">0\d\d-\d\d\d\d\d\d\d\d</span>匹配这样的字符串：<span class="desc">以0开头，然后是两个数字，然后是一个连字号&#8220;-&#8221;，最后是8个数字</span>(也就是中国的电话号码。当然，这个例子只能匹配区号为3位的情形)。</p>
<p>这里的<span class="part">\d</span>是个新的元字符，匹配<span class="desc">一位数字(0，或1，或2，或&#8230;&#8230;)</span>。<span class="part">-</span>不是元字符，只匹配它本身&#8212;&#8212;连字符或者减号。</p>
<p>为了避免那么多烦人的重复，我们也可以这样写这个表达式：<span class="regex">0\d{2}-\d{8}</span>。 这里<span class="part">\d</span>后面的<span class="part">{2}</span>(<span class="part">{8}</span>)的意思是前面<span class="part">\d</span><span class="desc">必须连续重复匹配2次(8次)</span>。</p>
<h2 id="testing">测试正则表达式</h2>
<div class="note">
<p>其它可用的测试工具:</p>
<ul>
    <li><a href="http://www.regexbuddy.com/">RegexBuddy</a>
    </li>
    <li><a href="http://regexpal.com/">Javascript正则表达式在线测试工具</a> </li>
</ul>
</div>
<p>如果你不觉得正则表达式很难读写的话，要么你是一个天才，要么，你不是地球人。正则表达式的语法很令人头疼，即使对经常使用它的人来说也是如此。由于难于读写，容易出错，所以找一种工具对正则表达式进行测试是很有必要的。</p>
<p>由于在不同的环境下正则表达式的一些细节是不相同的，本教程介绍的是微软 .Net Framework 2.0下正则表达式的行为，所以，我向你介绍一个.Net下的工具<a title="转到RegexTester的官方网站（英文）" href="http://www.dotnet2themax.com/blogs/fbalena/PermaLink,guid,13bce26d-7755-441e-92b3-1eb5f9e859f9.aspx">Regex Tester</a>。首先你确保已经安装了<a title="转到下载.Net Framework 2.0的页面" href="http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&amp;FamilyID=0856eacb-4362-4b0d-8edd-aab15c5e04f5">.Net Framework 2.0</a>，然后<a title="从www.unibetter.com下载Regex Tester, 75KB" href="http://www.unibetter.com/deerchao/downloads/RegexTester.zip">下载Regex Tester</a>。这是个绿色软件，下载完后打开压缩包,直接运行RegexTester.exe就可以了。</p>
<p>下面是Regex Tester运行时的截图：</p>
<p><img alt="Regex Tester运行时的截图" src="http://unibetter.com/deerchao/images/RegexTester.jpg" /></p>
<h2 id="metacode">元字符</h2>
<p>现在你已经知道几个很有用的元字符了，如<span class="code">\b</span>,<span class="code">.</span>,<span class="code">*</span>，还有<span class="code">\d</span>.正则表达式里还有更多的元字符，比如<span class="code">\s</span>匹配<span class="desc">任意的空白符，包括空格，制表符(Tab)，换行符，中文全角空格等</span>。<span class="code">\w</span>匹配<span class="desc">字母或数字或下划线或汉字等</span>。</p>
<p class="note">对中文/汉字的特殊处理是由.Net提供的正则表达式引擎支持的，其它环境下的具体情况请查看相关文档。</p>
<p>下面来看看更多的例子：</p>
<p><span class="regex">\ba\w*\b</span>匹配<span class="desc">以字母<span class="part">a</span>开头的单词&#8212;&#8212;先是某个单词开始处(<span class="part">\b</span>)，然后是字母<span class="part">a</span>,然后是任意数量的字母或数字(<span class="part">\w*</span>)，最后是单词结束处(<span class="part">\b</span>)</span>。</p>
<p class="note">好吧，现在我们说说正则表达式里的单词是什么意思吧：就是多于一个的连续的<span class="code">\w</span>。不错，这与学习英文时要背的成千上万个同名的东西的确关系不大 :)</p>
<p><span class="regex">\d+</span>匹配<span class="desc">1个或更多连续的数字</span>。这里的<span class="part">+</span>是和<span class="code">*</span>类似的元字符，不同的是<span class="code">*</span>匹配<span class="desc">重复任意次(可能是0次)</span>，而<span class="code">+</span>则匹配<span class="desc">重复1次或更多次</span>。</p>
<p><span class="regex">\b\w{6}\b</span> 匹配<span class="desc">刚好6个字母/数字的单词</span>。</p>
<table cellspacing="0">
    <caption>表1.常用的元字符</caption>
    <thead>
        <tr>
            <th scope="col">代码</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><span class="code">.</span></td>
            <td><span class="desc">匹配除换行符以外的任意字符</span></td>
        </tr>
        <tr>
            <td><span class="code">\w</span></td>
            <td><span class="desc">匹配字母或数字或下划线或汉字</span></td>
        </tr>
        <tr>
            <td><span class="code">\s</span></td>
            <td><span class="desc">匹配任意的空白符</span></td>
        </tr>
        <tr>
            <td><span class="code">\d</span></td>
            <td><span class="desc">匹配数字</span></td>
        </tr>
        <tr>
            <td><span class="code">\b</span></td>
            <td><span class="desc">匹配单词的开始或结束</span></td>
        </tr>
        <tr>
            <td><span class="code">^</span></td>
            <td><span class="desc">匹配字符串的开始</span></td>
        </tr>
        <tr>
            <td><span class="code">$</span></td>
            <td><span class="desc">匹配字符串的结束</span></td>
        </tr>
    </tbody>
</table>
<p>元字符<span class="code">^</span>（和数字6在同一个键位上的符号）和<span class="code">$</span>都匹配一个位置，这和<span class="code">\b</span>有点类似。<span class="code">^</span>匹配你要用来查找的字符串的开头，<span class="code">$</span>匹配结尾。这两个代码在验证输入的内容时非常有用，比如一个网站如果要求你填写的QQ号必须为5位到12位数字时，可以使用：<span class="regex">^\d{5,12}$</span>。</p>
<p>这里的<span class="part">{5,12}</span>和前面介绍过的<span class="part">{2}</span>是类似的，只不过<span class="part">{2}</span>匹配<span class="desc">只能不多不少重复2次</span>，<span class="part">{5,12}</span>则是<span class="desc">重复的次数不能少于5次，不能多于12次</span>，否则都不匹配。</p>
<p>因为使用了<span class="part">^</span>和<span class="part">$</span>，所以输入的整个字符串都要用来和<span class="part">\d{5,12}</span>来匹配，也就是说整个输入<span class="desc">必须是5到12个数字</span>，因此如果输入的QQ号能匹配这个正则表达式的话，那就符合要求了。</p>
<p>和忽略大小写的选项类似，有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项，<span class="code">^</span>和<span class="code">$</span>的意义就变成了<span class="desc">匹配行的开始处和结束处</span>。</p>
<h2 id="escape">字符转义</h2>
<p>如果你想查找元字符本身的话，比如你查找<span class="desc">.</span>,或者<span class="desc">*</span>,就出现了问题：你没办法指定它们，因为它们会被解释成别的意思。这时你就得使用<span class="code">\</span>来取消这些字符的特殊意义。因此，你应该使用<span class="regex">\.</span>和<span class="regex">\*</span>。当然，要查找<span class="desc">\</span>本身，你也得用<span class="regex">\\</span>.</p>
<p>例如：<span class="regex">unibetter\.com</span>匹配<span class="desc">unibetter.com</span>，<span class="regex">C:\\Windows</span>匹配<span class="desc">C:\Windows</span>。</p>
<h2 id="repeat">重复</h2>
<p>你已经看过了前面的<span class="code">*</span>,<span class="code">+</span>,<span class="code">{2}</span>,<span class="code">{5,12}</span>这几个匹配重复的方式了。下面是正则表达式中所有的限定符(指定数量的代码，例如*,{5,12}等)：</p>
<table cellspacing="0">
    <caption>表2.常用的限定符</caption>
    <thead>
        <tr>
            <th scope="col">代码/语法</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><span class="code">*</span></td>
            <td><span class="desc">重复零次或更多次</span></td>
        </tr>
        <tr>
            <td><span class="code">+</span></td>
            <td><span class="desc">重复一次或更多次</span></td>
        </tr>
        <tr>
            <td><span class="code">?</span></td>
            <td><span class="desc">重复零次或一次</span></td>
        </tr>
        <tr>
            <td><span class="code">{n}</span></td>
            <td><span class="desc">重复n次</span></td>
        </tr>
        <tr>
            <td><span class="code">{n,}</span></td>
            <td><span class="desc">重复n次或更多次</span></td>
        </tr>
        <tr>
            <td><span class="code">{n,m}</span></td>
            <td><span class="desc">重复n到m次</span></td>
        </tr>
    </tbody>
</table>
<p>下面是一些使用重复的例子：</p>
<p><span class="regex">Windows\d+</span>匹配<span class="desc">Windows后面跟1个或更多数字</span></p>
<p><span class="regex">^\w+</span>匹配<span class="desc">一行的第一个单词(或整个字符串的第一个单词，具体匹配哪个意思得看选项设置)</span></p>
<h2 id="charclass">字符类</h2>
<p>要想查找数字，字母或数字，空白是很简单的，因为已经有了对应这些字符集合的元字符，但是如果你想匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u),应该怎么办？</p>
<p>很简单，你只需要在方括号里列出它们就行了，像<span class="regex">[aeiou]</span>就匹配<span class="desc">任何一个英文元音字母</span>，<span class="regex">[.?!]</span>匹配<span class="desc">标点符号(.或?或!)</span>。</p>
<p>我们也可以轻松地指定一个字符<span class="name">范围</span>，像<span class="regex">[0-9]</span>代表的含意与<span class="regex">\d</span>就是完全一致的：<span class="desc">一位数字</span>；同理<span class="regex">[a-z0-9A-Z_]</span>也完全等同于<span class="code">\w</span>（如果只考虑英文的话）。</p>
<p>下面是一个更复杂的表达式：<span class="regex">\(?0\d{2}[) -]?\d{8}</span>。</p>
<p class="note">&#8220;(&#8221;和&#8220;)&#8221;也是元字符，后面的<a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#grouping">分组节</a>里会提到，所以在这里需要使用<a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#escape">转义</a>。</p>
<p>这个表达式可以匹配<span class="desc">几种格式的电话号码</span>，像<span class="string">(010)88886666</span>，或<span class="string">022-22334455</span>，或<span class="string">02912345678</span>等。我们对它进行一些分析吧：首先是一个转义字符<span class="part">\(</span>,它能出现0次或1次(<span class="part">?</span>),然后是一个<span class="part">0</span>，后面跟着2个数字(<span class="part">\d{2}</span>)，然后是<span class="part">)</span>或<span class="part">-</span>或<span class="part">空格</span>中的一个，它出现1次或不出现(<span class="part">?</span>)，最后是8个数字(<span class="part">\d{8}</span>)。</p>
<h2 id="alternative">分枝条件</h2>
<p>不幸的是，刚才那个表达式也能匹配<span class="string">010)12345678</span>或<span class="string">(022-87654321</span>这样的&#8220;不正确&#8221;的格式。要解决这个问题，我们需要用到<span class="name">分枝条件</span>。正则表达式里的<span class="name">分枝条件</span>指的是有几种规则，如果满足其中任意一种规则都应该当成匹配，具体方法是用<span class="code">|</span>把不同的规则分隔开。听不明白？没关系，看例子：</p>
<p><span class="regex">0\d{2}-\d{8}|0\d{3}-\d{7}</span>这个表达式能<span class="desc">匹配两种以连字号分隔的电话号码：一种是三位区号，8位本地号(如010-12345678)，一种是4位区号，7位本地号(0376-2233445)</span>。</p>
<p><span class="regex">\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}</span>这个表达式<span class="desc">匹配3位区号的电话号码，其中区号可以用小括号括起来，也可以不用，区号与本地号间可以用连字号或空格间隔，也可以没有间隔</span>。你可以试试用分枝条件把这个表达式扩展成也支持4位区号的。</p>
<p><span class="regex">\d{5}-\d{4}|\d{5}</span>这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字，或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题：<strong>使用分枝条件时，要注意各个条件的顺序</strong>。如果你把它改成<span class="regex">\d{5}|\d{5}-\d{4}</span>的话，那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配分枝条件时，将会从左到右地测试每个条件，如果满足了某个分枝的话，就不会去再管其它的条件了。</p>
<h2 id="grouping">分组</h2>
<p>我们已经提到了怎么重复单个字符（直接在字符后面加上限定符就行了）；但如果想要重复多个字符又该怎么办？你可以用小括号来指定<span class="name">子表达式</span>(也叫做<span class="name">分组</span>)，然后你就可以指定这个子表达式的重复次数了，你也可以对子表达式进行其它一些操作(后面会有介绍)。</p>
<p><span class="regex">(\d{1,3}\.){3}\d{1,3}</span>是一个<span class="desc">简单的IP地址匹配</span>表达式。要理解这个表达式，请按下列顺序分析它：<span class="part">\d{1,3}</span>匹配<span class="desc">1到3位的数字</span>，<span class="part">(\d{1,3}\.){3}</span>匹配<span class="desc">三位数字加上一个英文句号(这个整体也就是这个<span class="name">分组</span>)重复3次</span>，最后再加上<span class="desc">一个一到三位的数字</span>(<span class="part">\d{1,3}</span>)。</p>
<p class="note">IP地址中每个数字都不能大于255，大家千万不要被《24》第三季的编剧给忽悠了...</p>
<p>不幸的是，它也将匹配<span class="string">256.300.888.999</span>这种不可能存在的IP地址。如果能使用算术比较的话，或许能简单地解决这个问题，但是正则表达式中并不提供关于数学的任何功能，所以只能使用冗长的分组，选择，字符类来描述一个正确的IP地址：<span class="regex">((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)</span>。</p>
<p>理解这个表达式的关键是理解<span class="part">2[0-4]\d|25[0-5]|[01]?\d\d?</span>，这里我就不细说了，你自己应该能分析得出来它的意义。</p>
<h2 id="negation">反义</h2>
<p>有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外，其它任意字符都行的情况，这时需要用到<span class="name">反义</span>：</p>
<table cellspacing="0">
    <caption>表3.常用的反义代码</caption>
    <thead>
        <tr>
            <th scope="col">代码/语法</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><span class="code">\W</span></td>
            <td><span class="desc">匹配任意不是字母，数字，下划线，汉字的字符</span></td>
        </tr>
        <tr>
            <td><span class="code">\S</span></td>
            <td><span class="desc">匹配任意不是空白符的字符</span></td>
        </tr>
        <tr>
            <td><span class="code">\D</span></td>
            <td><span class="desc">匹配任意非数字的字符</span></td>
        </tr>
        <tr>
            <td><span class="code">\B</span></td>
            <td><span class="desc">匹配不是单词开头或结束的位置</span></td>
        </tr>
        <tr>
            <td><span class="code">[^x]</span></td>
            <td><span class="desc">匹配除了x以外的任意字符</span></td>
        </tr>
        <tr>
            <td><span class="code">[^aeiou]</span></td>
            <td><span class="desc">匹配除了aeiou这几个字母以外的任意字符</span></td>
        </tr>
    </tbody>
</table>
<p>例子：<span class="regex">\S+</span>匹配<span class="desc">不包含空白符的字符串</span>。</p>
<p><span class="regex">&lt;a[^&gt;]+&gt;</span>匹配<span class="desc">用尖括号括起来的以a开头的字符串</span>。</p>
<h2 id="backreference">后向引用</h2>
<p>使用小括号指定一个子表达式后，<strong>匹配这个子表达式的文本</strong>(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下，每个分组会自动拥有一个<span class="name">组号</span>，规则是：从左向右，以分组的左括号为标志，第一个出现的分组的组号为1，第二个为2，以此类推。</p>
<p><span class="name">后向引用</span>用于重复搜索前面某个分组匹配的文本。例如，<span class="part">\1</span>代表<span class="desc">分组1匹配的文本</span>。难以理解？请看示例：</p>
<p><span class="regex">\b(\w+)\b\s+\1\b</span>可以用来匹配<span class="desc">重复的单词</span>，像<span class="string">go go</span>, 或者<span class="string">kitty kitty</span>。这个表达式首先是<span class="desc">一个单词</span>，也就是<span class="desc">单词开始处和结束处之间的多于一个的字母或数字</span>(<span class="part">\b(\w+)\b</span>)，这个单词会被捕获到编号为1的分组中，然后是<span class="desc">1个或几个空白符</span>(<span class="part">\s+</span>)，最后是<span class="desc">分组1中捕获的内容（也就是前面匹配的那个单词）</span>(<span class="part">\1</span>)。</p>
<p>你也可以自己指定子表达式的<span class="name">组名</span>。要指定一个子表达式的组名，请使用这样的语法：<span class="code">(?&lt;Word&gt;\w+)</span>(或者把尖括号换成<span class="code">'</span>也行：<span class="code">(?'Word'\w+)</span>),这样就把<span class="part">\w+</span>的组名指定为<span class="part">Word</span>了。要反向引用这个分组<span class="name">捕获</span>的内容，你可以使用<span class="code">\k&lt;Word&gt;</span>,所以上一个例子也可以写成这样：<span class="regex">\b(?&lt;Word&gt;\w+)\b\s+\k&lt;Word&gt;\b</span>。</p>
<p>使用小括号的时候，还有很多特定用途的语法。下面列出了最常用的一些：</p>
<table cellspacing="0">
    <caption>表4.常用分组语法</caption>
    <tbody>
        <tr>
            <th scope="col">分类</th>
            <th scope="col">代码/语法</th>
            <th scope="col">说明</th>
        </tr>
        <tr>
            <th rowspan="3">捕获</th>
            <td><span class="code">(exp)</span></td>
            <td><span class="desc">匹配exp,并捕获文本到自动命名的组里</span></td>
        </tr>
        <tr>
            <td><span class="code">(?&lt;name&gt;exp)</span></td>
            <td><span class="desc">匹配exp,并捕获文本到名称为name的组里，也可以写成(?'name'exp)</span></td>
        </tr>
        <tr>
            <td><span class="code">(?:exp)</span></td>
            <td><span class="desc">匹配exp,不捕获匹配的文本，也不给此分组分配组号</span></td>
        </tr>
        <tr>
            <th rowspan="4">零宽断言</th>
            <td><span class="code">(?=exp)</span></td>
            <td><span class="desc">匹配exp前面的位置</span></td>
        </tr>
        <tr>
            <td><span class="code">(?&lt;=exp)</span></td>
            <td><span class="desc">匹配exp后面的位置</span></td>
        </tr>
        <tr>
            <td><span class="code">(?!exp)</span></td>
            <td><span class="desc">匹配后面跟的不是exp的位置</span></td>
        </tr>
        <tr>
            <td><span class="code">(?&lt;!exp)</span></td>
            <td><span class="desc">匹配前面不是exp的位置</span></td>
        </tr>
        <tr>
            <th>注释</th>
            <td><span class="code">(?#comment)</span></td>
            <td><span class="desc">这种类型的分组不对正则表达式的处理产生任何影响，用于提供注释让人阅读</span></td>
        </tr>
    </tbody>
</table>
<p>我们已经讨论了前两种语法。第三个<span class="code">(?:exp)</span>不会改变正则表达式的处理方式，只是这样的组匹配的内容<span class="desc">不会像前两种那样被捕获到某个组里面，也不会拥有组号</span>。</p>
<h2 id="lookaround">零宽断言</h2>
<p class="note">地球人，是不是觉得这些术语名称太复杂，太难记了？我也和你一样。知道有这么一种东西就行了，它叫什么，随它去吧！&#8220;无名，万物之始...&#8221;</p>
<p>接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西，也就是说它们像<span class="code">\b</span>,<span class="code">^</span>,<span class="code">$</span>那样用于指定一个位置，这个位置应该满足一定的条件(即断言)，因此它们也被称为<span class="name">零宽断言</span>。最好还是拿例子来说明吧：</p>
<p class="note">断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。</p>
<p><span class="code">(?=exp)</span>也叫<span class="name">零宽度正预测先行断言</span>，它<span class="desc">断言自身出现的位置的后面能匹配表达式exp</span>。比如<span class="regex">\b\w+(?=ing\b)</span>，匹配<span class="desc">以ing结尾的单词的前面部分(除了ing以外的部分)</span>，如查找<span class="string">I'm singing while you're dancing.</span>时，它会匹配<span class="desc">sing</span>和<span class="desc">danc</span>。</p>
<p><span class="code">(?&lt;=exp)</span>也叫<span class="name">零宽度正回顾后发断言</span>，它<span class="desc">断言自身出现的位置的前面能匹配表达式exp</span>。比如<span class="regex">(?&lt;=\bre)\w+\b</span>会匹配<span class="desc">以re开头的单词的后半部分(除了re以外的部分)</span>，例如在查找<span class="string">reading a book</span>时，它匹配<span class="desc">ading</span>。</p>
<p>假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了)，你可以这样查找需要在前面和里面添加逗号的部分：<span class="regex">((?&lt;=\d)\d{3})*\b</span>，用它对<span class="string">1234567890</span>进行查找时结果是<span class="desc">234567890</span>。</p>
<p>下面这个例子同时使用了这两种断言：<span class="regex">(?&lt;=\s)\d+(?=\s)</span>匹配<span class="desc">以空白符间隔的数字(再次强调，不包括这些空白符)</span>。</p>
<h2 id="negativelookaround">负向零宽断言</h2>
<p>前面我们提到过怎么查找<strong>不是某个字符或不在某个字符类里</strong>的字符的方法(反义)。但是如果我们只是想要<strong>确保某个字符没有出现，但并不想去匹配它</strong>时怎么办？例如，如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样：</p>
<p><span class="regex">\b\w*q[^u]\w*\b</span>匹配<span class="desc">包含<strong>后面不是字母u的字母q</strong>的单词</span>。但是如果多做测试(或者你思维足够敏锐，直接就观察出来了)，你会发现，如果q出现在单词的结尾的话，像<strong>Iraq</strong>,<strong>Benq</strong>，这个表达式就会出错。这是因为<span class="part">[^u]</span>总要匹配一个字符，所以如果q是单词的最后一个字符的话，后面的<span class="part">[^u]</span>将会匹配q后面的单词分隔符(可能是空格，或者是句号或其它的什么)，后面的<span class="part">\w*\b</span>将会匹配下一个单词，于是<span class="regex">\b\w*q[^u]\w*\b</span>就能匹配整个<span class="string">Iraq fighting</span>。<span class="name">负向零宽断言</span>能解决这样的问题，因为它只匹配一个位置，并不<strong>消费</strong>任何字符。现在，我们可以这样来解决这个问题：<span class="regex">\b\w*q(?!u)\w*\b</span>。</p>
<p><span class="name">零宽度负预测先行断言</span><span class="code">(?!exp)</span>，<span class="desc">断言此位置的后面不能匹配表达式exp</span>。例如：<span class="regex">\d{3}(?!\d)</span>匹配<span class="desc">三位数字，而且这三位数字的后面不能是数字</span>；<span class="regex">\b((?!abc)\w)+\b</span>匹配<span class="desc">不包含连续字符串abc的单词</span>。</p>
<p>同理，我们可以用<span class="code">(?&lt;!exp)</span>,<span class="name">零宽度正回顾后发断言</span>来<span class="desc">断言此位置的前面不能匹配表达式exp</span>：<span class="regex">(?&lt;![a-z])\d{7}</span>匹配<span class="desc">前面不是小写字母的七位数字</span>。</p>
<p class="note">请详细分析表达式<span class="regex">(?&lt;=&lt;(\w+)&gt;).*(?=&lt;\/\1&gt;)</span>，这个表达式最能表现零宽断言的真正用途。</p>
<p>一个更复杂的例子：<span class="regex">(?&lt;=&lt;(\w+)&gt;).*(?=&lt;\/\1&gt;)</span>匹配<span class="desc">不包含属性的简单HTML标签内里的内容</span>。<span class="code">(&lt;?(\w+)&gt;)</span>指定了这样的<span class="name">前缀</span>：<span class="desc">被尖括号括起来的单词</span>(比如可能是&lt;b&gt;)，然后是<span class="part">.*</span>(任意的字符串),最后是一个<span class="name">后缀</span><span class="part">(?=&lt;\/\1&gt;)</span>。注意后缀里的<span class="part">\/</span>，它用到了前面提过的字符转义；<span class="part">\1</span>则是一个反向引用，引用的正是<span class="desc">捕获的第一组</span>，前面的<span class="part">(\w+)</span>匹配的内容，这样如果前缀实际上是&lt;b&gt;的话，后缀就是&lt;/b&gt;了。整个表达式匹配的是&lt;b&gt;和&lt;/b&gt;之间的内容(再次提醒，不包括前缀和后缀本身)。</p>
<h2 id="commenting">注释</h2>
<p>小括号的另一种用途是通过语法<span class="code">(?#comment)</span>来包含注释。例如：<span class="regex">2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)</span>。</p>
<p>要包含注释的话，最好是启用&#8220;忽略模式里的空白符&#8221;选项，这样在编写表达式时能任意的添加空格，Tab，换行，而实际使用时这些都将被忽略。启用这个选项后，在#后面到这一行结束的所有文本都将被当成注释忽略掉。例如，我们可以前面的一个表达式写成这样：</p>
<pre class="regex">      (?&lt;=    # 断言要匹配的文本的前缀<br />
&lt;(\w+)&gt; # 查找尖括号括起来的字母或数字(即HTML/XML标签)<br />
)       # 前缀结束<br />
.*      # 匹配任意文本<br />
(?=     # 断言要匹配的文本的后缀<br />
&lt;\/\1&gt;  # 查找尖括号括起来的内容：前面是一个"/"，后面是先前捕获的标签<br />
)       # 后缀结束</pre>
<h2 id="greedyandlazy">贪婪与懒惰</h2>
<p>当正则表达式中包含能接受重复的限定符时，通常的行为是（在使整个表达式能得到匹配的前提下）匹配<strong>尽可能多</strong>的字符。考虑这个表达式：<span class="regex">a.*b</span>，它将会匹配<span class="desc">最长的以a开始，以b结束的字符串</span>。如果用它来搜索<span class="string">aabab</span>的话，它会匹配整个字符串<span class="desc">aabab</span>。这被称为<span class="name">贪婪</span>匹配。</p>
<p>有时，我们更需要<span class="name">懒惰</span>匹配，也就是匹配<strong>尽可能少</strong>的字符。前面给出的限定符都可以被转化为懒惰匹配模式，只要在它后面加上一个问号<span class="code">?</span>。这样<span class="regex">.*?</span>就意味着<span class="desc">匹配任意数量的重复，但是在能使整个匹配成功的前提下使用最少的重复</span>。现在看看懒惰版的例子吧：</p>
<p><span class="regex">a.*?b</span>匹配<span class="desc">最短的，以a开始，以b结束的字符串</span>。如果把它应用于<span class="string">aabab</span>的话，它会匹配<span class="desc">aab（第一到第三个字符）</span>和<span class="desc">ab（第四到第五个字符）</span>。</p>
<p class="note">为什么第一个匹配是aab（第一到第三个字符）而不是ab（第二到第三个字符）？简单地说，因为正则表达式有另一条规则，比懒惰／贪婪规则的优先级更高：最先开始的匹配拥有最高的优先权&#8212;&#8212;The match that begins earliest wins。</p>
<table cellspacing="0">
    <caption>表5.懒惰限定符</caption>
    <thead>
        <tr>
            <th scope="col">代码/语法</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><span class="code">*?</span></td>
            <td><span class="desc">重复任意次，但尽可能少重复</span></td>
        </tr>
        <tr>
            <td><span class="code">+?</span></td>
            <td><span class="desc">重复1次或更多次，但尽可能少重复</span></td>
        </tr>
        <tr>
            <td><span class="code">??</span></td>
            <td><span class="desc">重复0次或1次，但尽可能少重复</span></td>
        </tr>
        <tr>
            <td><span class="code">{n,m}?</span></td>
            <td><span class="desc">重复n到m次，但尽可能少重复</span></td>
        </tr>
        <tr>
            <td><span class="code">{n,}?</span></td>
            <td><span class="desc">重复n次以上，但尽可能少重复</span></td>
        </tr>
    </tbody>
</table>
<h2 id="regexoptions">处理选项</h2>
<p class="note">在C#中，你可以使用<a title="MSDN 相关文档" href="http://msdn2.microsoft.com/zh-cn/library/h5845fdz.aspx">Regex(String, RegexOptions)构造函数</a>来设置正则表达式的处理选项。如：Regex regex = new Regex("\ba\w{6}\b", RegexOptions.IgnoreCase);</p>
<p>上面介绍了几个选项如忽略大小写，处理多行等，这些选项能用来改变处理正则表达式的方式。下面是.Net中常用的正则表达式选项：</p>
<table cellspacing="0">
    <caption>表6.常用的处理选项</caption>
    <thead>
        <tr>
            <th scope="col">名称</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>IgnoreCase(忽略大小写)</td>
            <td>匹配时不区分大小写。</td>
        </tr>
        <tr>
            <td>Multiline(多行模式)</td>
            <td>更改<span class="code">^</span>和<span class="code">$</span>的含义，使它们分别在任意一行的行首和行尾匹配，而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,<span class="code">$</span>的精确含意是:匹配\n之前的位置以及字符串结束前的位置.) </td>
        </tr>
        <tr>
            <td>Singleline(单行模式)</td>
            <td>更改<span class="code">.</span>的含义，使它与每一个字符匹配（包括换行符\n）。 </td>
        </tr>
        <tr>
            <td>IgnorePatternWhitespace(忽略空白)</td>
            <td>忽略表达式中的非转义空白并启用由<span class="code">#</span>标记的注释。</td>
        </tr>
        <tr>
            <td>RightToLeft(从右向左查找)</td>
            <td>匹配从右向左而不是从左向右进行。</td>
        </tr>
        <tr>
            <td>ExplicitCapture(显式捕获)</td>
            <td>仅捕获已被显式命名的组。</td>
        </tr>
        <tr>
            <td>ECMAScript(JavaScript兼容模式)</td>
            <td>使表达式的行为与它在JavaScript里的行为一致。</td>
        </tr>
    </tbody>
</table>
<p>一个经常被问到的问题是：是不是只能同时使用多行模式和单行模式中的一种？答案是：不是。这两个选项之间没有任何关系，除了它们的名字比较相似（以至于让人感到疑惑）以外。</p>
<h2 id="balancedgroup">平衡组/递归匹配</h2>
<p class="important note">这里介绍的平衡组语法是由.Net Framework支持的；其它语言／库不一定支持这种功能，或者支持此功能但需要使用不同的语法。</p>
<p>有时我们需要匹配像<span class="desc">( 100 * ( 50 + 15 ) )这样的可嵌套的层次性结构</span>，这时简单地使用<span class="code">\(.+\)</span>则只会匹配到最左边的左括号和最右边的右括号之间的内容(这里我们讨论的是贪婪模式，懒惰模式也有下面的问题)。假如原来的字符串里的左括号和右括号出现的次数不相等，比如<span class="string">( 5 / ( 3 + 2 ) ) )</span>，那我们的匹配结果里两者的个数也不会相等。有没有办法在这样的字符串里匹配到最长的，配对的括号之间的内容呢？</p>
<p>为了避免<span class="code">(</span>和<span class="code">\(</span>把你的大脑彻底搞糊涂，我们还是用尖括号代替圆括号吧。现在我们的问题变成了如何把<span class="string">xx &lt;aa &lt;bbb&gt; &lt;bbb&gt; aa&gt; yy</span>这样的字符串里，最长的配对的尖括号内的内容捕获出来？</p>
<p>这里需要用到以下的语法构造：</p>
<ul>
    <li><span class="code">(?'group')</span> 把捕获的内容命名为group,并压入<span class="name">堆栈(Stack)</span>
    </li>
    <li><span class="code">(?'-group')</span> 从堆栈上弹出最后压入堆栈的名为group的捕获内容，如果堆栈本来为空，则本分组的匹配失败
    </li>
    <li><span class="code">(?(group)yes|no)</span> 如果堆栈上存在以名为group的捕获内容的话，继续匹配yes部分的表达式，否则继续匹配no部分
    </li>
    <li><span class="code">(?!)</span> 零宽负向先行断言，由于没有后缀表达式，试图匹配总是失败 </li>
</ul>
<p class="note">如果你不是一个程序员（或者你自称程序员但是不知道堆栈是什么东西），你就这样理解上面的三种语法吧：第一个就是在黑板上写一个"group"，第二个就是从黑板上擦掉一个"group"，第三个就是看黑板上写的还有没有"group"，如果有就继续匹配yes部分，否则就匹配no部分。</p>
<p>我们需要做的是每碰到了左括号，就在压入一个"Open",每碰到一个右括号，就弹出一个，到了最后就看看堆栈是否为空－－如果不为空那就证明左括号比右括号多，那匹配就应该失败。正则表达式引擎会进行回溯(放弃最前面或最后面的一些字符)，尽量使整个表达式得到匹配。</p>
<pre class="regex">&lt;                         #最外层的左括号<br />
[^&lt;&gt;]*                #最外层的左括号后面的不是括号的内容<br />
(<br />
(<br />
(?'Open'&lt;)    #碰到了左括号，在黑板上写一个"Open"<br />
[^&lt;&gt;]*       #匹配左括号后面的不是括号的内容<br />
)+<br />
(<br />
(?'-Open'&gt;)   #碰到了右括号，擦掉一个"Open"<br />
[^&lt;&gt;]*        #匹配右括号后面不是括号的内容<br />
)+<br />
)*<br />
(?(Open)(?!))         #在遇到最外层的右括号前面，判断黑板上还有没有没擦掉的"Open"；如果还有，则匹配失败<br />
&gt;                         #最外层的右括号</pre>
<p>平衡组的一个最常见的应用就是匹配HTML,下面这个例子可以匹配<span class="desc">嵌套的&lt;div&gt;标签</span>：<span class="regex">&lt;div[^&gt;]*&gt;[^&lt;&gt;]*(((?'Open'&lt;div[^&gt;]*&gt;)[^&lt;&gt;]*)+((?'-Open'&lt;/div&gt;)[^&lt;&gt;]*)+)*(?(Open)(?!))&lt;/div&gt;</span>.</p>
<h2 id="more">还有些什么东西没提到</h2>
<p>我已经描述了构造正则表达式的大量元素，还有一些我没有提到的东西。下面是未提到的元素的列表，包含语法和简单的说明。你可以在网上找到更详细的参考资料来学习它们--当你需要用到它们的时候。如果你安装了MSDN Library,你也可以在里面找到关于.net下正则表达式详细的文档。</p>
<table cellspacing="0">
    <caption>表7.尚未详细讨论的语法</caption>
    <thead>
        <tr>
            <th scope="col">代码/语法</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><span class="code">\a</span></td>
            <td><span class="desc">报警字符(打印它的效果是电脑嘀一声)</span></td>
        </tr>
        <tr>
            <td><span class="code">\b</span></td>
            <td><span class="desc">通常是单词分界位置，但如果在字符类里使用代表退格</span></td>
        </tr>
        <tr>
            <td><span class="code">\t</span></td>
            <td><span class="desc">制表符，Tab</span></td>
        </tr>
        <tr>
            <td><span class="code">\r</span></td>
            <td><span class="desc">回车</span></td>
        </tr>
        <tr>
            <td><span class="code">\v</span></td>
            <td><span class="desc">竖向制表符</span></td>
        </tr>
        <tr>
            <td><span class="code">\f</span></td>
            <td><span class="desc">换页符</span></td>
        </tr>
        <tr>
            <td><span class="code">\n</span></td>
            <td><span class="desc">换行符</span></td>
        </tr>
        <tr>
            <td><span class="code">\e</span></td>
            <td><span class="desc">Escape</span></td>
        </tr>
        <tr>
            <td><span class="code">\0nn</span></td>
            <td><span class="desc">ASCII代码中八进制代码为nn的字符</span></td>
        </tr>
        <tr>
            <td><span class="code">\xnn</span></td>
            <td><span class="desc">ASCII代码中十六进制代码为nn的字符</span></td>
        </tr>
        <tr>
            <td><span class="code">\unnnn</span></td>
            <td><span class="desc">Unicode代码中十六进制代码为nnnn的字符</span></td>
        </tr>
        <tr>
            <td><span class="code">\cN</span></td>
            <td><span class="desc">ASCII控制字符。比如\cC代表Ctrl+C</span></td>
        </tr>
        <tr>
            <td><span class="code">\A</span></td>
            <td><span class="desc">字符串开头(类似^，但不受处理多行选项的影响)</span></td>
        </tr>
        <tr>
            <td><span class="code">\Z</span></td>
            <td><span class="desc">字符串结尾或行尾(不受处理多行选项的影响)</span></td>
        </tr>
        <tr>
            <td><span class="code">\z</span></td>
            <td><span class="desc">字符串结尾(类似$，但不受处理多行选项的影响)</span></td>
        </tr>
        <tr>
            <td><span class="code">\G</span></td>
            <td><span class="desc">当前搜索的开头</span></td>
        </tr>
        <tr>
            <td><span class="code">\p{name}</span></td>
            <td><span class="desc">Unicode中命名为name的字符类，例如\p{IsGreek}</span></td>
        </tr>
        <tr>
            <td><span class="code">(?&gt;exp)</span></td>
            <td><span class="desc">贪婪子表达式</span></td>
        </tr>
        <tr>
            <td><span class="code">(?&lt;x&gt;-&lt;y&gt;exp)</span></td>
            <td><span class="desc">平衡组</span></td>
        </tr>
        <tr>
            <td><span class="code">(?im-nsx:exp)</span></td>
            <td><span class="desc">在子表达式exp中改变处理选项</span></td>
        </tr>
        <tr>
            <td><span class="code">(?im-nsx)</span></td>
            <td><span class="desc">为表达式后面的部分改变处理选项</span></td>
        </tr>
        <tr>
            <td><span class="code">(?(exp)yes|no)</span></td>
            <td><span class="desc">把exp当作零宽正向先行断言，如果在这个位置能匹配，使用yes作为此组的表达式；否则使用no</span></td>
        </tr>
        <tr>
            <td><span class="code">(?(exp)yes)</span></td>
            <td><span class="desc">同上，只是使用空表达式作为no</span></td>
        </tr>
        <tr>
            <td><span class="code">(?(name)yes|no)</span></td>
            <td><span class="desc">如果命名为name的组捕获到了内容，使用yes作为表达式；否则使用no</span></td>
        </tr>
        <tr>
            <td><span class="code">(?(name)yes)</span></td>
            <td><span class="desc">同上，只是使用空表达式作为no</span></td>
        </tr>
    </tbody>
</table>
<h2 id="contact">联系作者</h2>
<p>好吧,我承认,我骗了你,读到这里你肯定花了不止30分钟.相信我,这是我的错,而不是因为你太笨.我之所以说"30分钟",是为了让你有信心,有耐心继续下去.既然你看到了这里,那证明我的阴谋成功了.被忽悠的感觉很爽吧？</p>
<p>要投诉我,或者觉得我其实可以做得更好,或者有任何其它问题,欢迎来<a href="http://www.cnblogs.com/deerchao/archive/2006/08/24/zhengzhe30fengzhongjiaocheng.html">我的博客</a>让我知道.<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----------------------http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm</p><img src ="http://www.blogjava.net/algz/aggbug/229762.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-09-18 17:48 <a href="http://www.blogjava.net/algz/articles/229762.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jsf+spring+hibernate 整合出现的错误集合</title><link>http://www.blogjava.net/algz/articles/228548.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Fri, 12 Sep 2008 03:25:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/228548.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/228548.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/228548.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/228548.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/228548.html</trackback:ping><description><![CDATA[一.错误信息提示:<br />
<span style="color: #99cc00;">WARN [main] (Configurator.java:126) - No configuration found. Configuring ehcache from <span style="color: #339966;">ehcache-failsafe.xml </span>found in the classpath: </span>jar:file:/E:/Users/algz/workspace/.metadata/.plugins/com.genuitec.eclipse.easie.tomcat.myeclipse/tomcat/webapps/item/WEB-INF/lib/ehcache-1.1.jar!/ehcache-failsafe.xml<br />
<br />
解决方案:<br />
ehcache-1.1.jar 包下的ehcache-failsafe.xml 文件复制到 src 目录下(新建文件,复制内容). <br />
<br />
二.错误信息提示:<br />
<span style="color: #99cc00;">log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader).</span><br />
<span style="color: #339966;">log4j:WARN Please initialize the log4j system properly.</span><br />
<br />
解决方案:<br />
src 目录下创建 log4j.properties 文件(具体内容,详见log4j配置文件).<br />
<br />
三.错误信息提示:<br />
<p><span style="color: #99cc00;">ERROR [main] (CGLIBLazyInitializer.java:130) - CGLIB Enhancement failed:</span> item.common.hibernate.query.partsum.Partsum<br />
<span style="color: #99cc00;">java.lang.NoSuchMethodError:</span> org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V</p>
<p><span style="color: #339966;">&nbsp;WARN [main] (PojoEntityTuplizer.java:173) - could not create proxy factory for:</span> item.common.hibernate.query.partsum.Partsum<br />
<span style="color: #339966;">org.hibernate.HibernateException: CGLIB Enhancement failed:</span> item.common.hibernate.query.partsum.Partsum</p>
<p><span style="color: #33cccc;">Caused by: java.lang.NoSuchMethodError:</span> org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V</p>
<p>///////////////////////////////////////////////////////////////////////////////////////////</p>
<p>ERROR [main] (CGLIBLazyInitializer.java:130) - CGLIB Enhancement failed: item.common.hibernate.fourm.Fourm<br />
java.lang.NoClassDefFoundError</p>
<p>&nbsp;WARN [main] (PojoEntityTuplizer.java:173) - could not create proxy factory for:item.common.hibernate.fourm.Fourm<br />
org.hibernate.HibernateException: CGLIB Enhancement failed: item.common.hibernate.fourm.Fourm</p>
<p>Caused by: java.lang.NoClassDefFoundError<br />
&nbsp;at org.hibernate.proxy.CGLIBLazyInitializer.getProxyFactory(CGLIBLazyInitializer.java:116)</p>
<p>////////////////////////////////////////////////////////////////////////////////////////////</p>
<p>ERROR [main] (CGLIBLazyInitializer.java:130) - CGLIB Enhancement failed: item.common.hibernate.picture<br />
java.lang.NoClassDefFoundError</p>
<p>&nbsp;WARN [main] (PojoEntityTuplizer.java:173) - could not create proxy factory for:item.common.hibernate.picture<br />
org.hibernate.HibernateException: CGLIB Enhancement failed: item.common.hibernate.picture</p>
<p>Caused by: java.lang.NoClassDefFoundError<br />
&nbsp;at org.hibernate.proxy.CGLIBLazyInitializer.getProxyFactory(CGLIBLazyInitializer.java:116)</p>
<p><br />
解决方案:<br />
Spring 和 Hibernate 共用的一些 jar 文件发生了版本冲突, 删除 WEB-INF/lib/asm-2.2.3.jar 然后重启 Tomcat.<br />
<br />
四.错误提示:<br />
<span>org.springframework.beans.factory.BeanCreationException:&nbsp;Error&nbsp;creating&nbsp;bean&nbsp;with&nbsp;name&nbsp;'SessionFactory'&nbsp;defined&nbsp;in&nbsp;<span class="keyword">class</span><span>&nbsp;path&nbsp;resource&nbsp;[applicationContext.xml]:&nbsp;Invocation&nbsp;of&nbsp;init&nbsp;method&nbsp;failed;&nbsp;nested&nbsp;exception&nbsp;is&nbsp;java.lang.NoSuchMethodError:&nbsp;org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V&nbsp;&nbsp;</span></span><br />
...<br />
Caused by: java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V<br />
<br />
解决方法:<br />
并不是真正的bean name错了,也不是找不到他的方法.是asm-2.2.3.jar与asm.jar冲突.<br />
<span style="color: #339966;">正确的删除asm-2.2.3.jar方法是到项目的发布文件夹\WEB-INF\lib中删除,不能用MyEclipse里删除.因为他在发布时仍没删除.</span></p>
<p><br />
</p>
<p>五。</p>
<p>严重: Exception sending context initialized event to listener instance of class <br />
<br />
org.springframework.web.context.ContextLoaderListener<br />
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in <br />
<br />
ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is <br />
<br />
org.hibernate.DuplicateMappingException: Duplicate class/entity mapping Check<br />
&nbsp;&nbsp;&nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean<br />
<br />
(AbstractAutowireCapableBeanFactory.java:1336)<br />
<br />
&nbsp;&nbsp;&nbsp; ... 39 more<br />
2009-8-21 11:52:37 org.apache.catalina.core.StandardContext start<br />
<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;property name="mappingResources"&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;list&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;value&gt;com/dao/Check.hbm.xml&lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;value&gt;./Check.hbm.xml&lt;/value&gt;&lt;/list&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/property&gt;</p>
<p><br />
</p>
<p>六。</p>
<p>&nbsp;&lt;class catalog="page" name="com.dao.Check" table="check0908100816"&gt;<br />
&nbsp; &lt;id name="checkid" type="java.lang.Integer"&gt;<br />
&nbsp;&nbsp; &lt;column name="checkid"/&gt;<br />
&nbsp;&nbsp; &lt;generator class="native"/&gt;<br />
&nbsp; &lt;/id&gt;<br />
<br />
<br />
严重: Exception sending context initialized event to listener instance of class <br />
<br />
org.springframework.web.context.ContextLoaderListener<br />
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in <br />
<br />
ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is <br />
<br />
org.hibernate.MappingException: entity class not found: Check<br />
&nbsp;&nbsp;&nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean<br />
&nbsp;&nbsp;&nbsp; ... 52 more<br />
2009-8-21 11:56:45 org.apache.catalina.core.StandardContext start<br />
</p>
<img src ="http://www.blogjava.net/algz/aggbug/228548.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-09-12 11:25 <a href="http://www.blogjava.net/algz/articles/228548.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]sql的left join 命令详解</title><link>http://www.blogjava.net/algz/articles/228220.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Wed, 10 Sep 2008 13:58:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/228220.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/228220.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/228220.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/228220.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/228220.html</trackback:ping><description><![CDATA[给个通俗的解释吧. <br />
例表a <br />
aid adate <br />
1 a1 <br />
2 a2 <br />
3 a3 <br />
表b <br />
bid bdate <br />
1 b1 <br />
2 b2 <br />
4 b4 <br />
两个表a,b相连接,要取出id相同的字段 <br />
select * from a inner join b on a.aid = b.bid这是仅取出匹配的数据. <br />
此时的取出的是: <br />
1 a1 b1 <br />
2 a2 b2 <br />
那么left join 指: <br />
select * from a left join b on a.aid = b.bid <br />
首先取出a表中所有数据,然后再加上与a,b匹配的的数据 <br />
此时的取出的是: <br />
1 a1 b1 <br />
2 a2 b2 <br />
3 a3 空字符 <br />
同样的也有right join <br />
指的是首先取出b表中所有数据,然后再加上与a,b匹配的的数据 <br />
此时的取出的是: <br />
1 a1 b1 <br />
2 a2 b2 <br />
4 空字符 b4<br />
<br />
LEFT JOIN 或 LEFT OUTER JOIN。 <br />
左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行，而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行，则在相关联的结果集行中右表的所有选择列表列均为空值。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------------http://www.phpweblog.net/zwws/archive/2007/02/23/944.html<br />
<img src ="http://www.blogjava.net/algz/aggbug/228220.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-09-10 21:58 <a href="http://www.blogjava.net/algz/articles/228220.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]SQL中的left outer join,inner join,right outer join用法</title><link>http://www.blogjava.net/algz/articles/228219.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Wed, 10 Sep 2008 13:55:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/228219.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/228219.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/228219.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/228219.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/228219.html</trackback:ping><description><![CDATA[使用关系代数合并数据<br />
1 关系代数<br />
合并数据集合的理论基础是关系代数，它是由E.F.Codd于1970年提出的。<br />
在关系代数的形式化语言中：<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用表、或者数据集合表示关系或者实体。<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用行表示元组。<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用列表示属性。<br />
关系代数包含以下8个关系运算符<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 选取――返回满足指定条件的行。<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 投影――从数据集合中返回指定的列。<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 笛卡尔积――是关系的乘法，它将分别来自两个数据集合中的行以所有可能的方式进行组合。<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 并――关系的加法和减法，它可以在行的方向上合并两个表中的数据，就像把一个表垒在另一个表之上一样。<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 交――返回两个数据集合所共有的行。<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 差――返回只属于一个数据集合的行。<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 连接――在水平方向上合并两个表，其方法是：将两个表中在共同数据项上相互匹配的那些行合并起来。<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 除――返回两个数据集之间的精确匹配。<br />
此外，作为一种实现现代关系代数运算的方法，SQL还提供了：<br />
?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 子查询――类似于连接，但更灵活；在外部查询中，方式可以使用表达式、列表或者数据集合的地方都可以使用子查询的结果。<br />
本章将主要讲述多种类型的连接、简单的和相关的子查询、几种类型的并、关系除以及其他的内容。<br />
2 使用连接<br />
2.1 连接类型<br />
在关系代数中，连接运算是由一个笛卡尔积运算和一个选取运算构成的。首先用笛卡尔积完成对两个数据集合的乘运算，然后对生成的结果集合进行选取运算，确保
只把分别来自两个数据集合并且具有重叠部分的行合并在一起。连接的全部意义在于在水平方向上合并两个数据集合（通常是表），并产生一个新的结果集合，其方
法是将一个数据源中的行于另一个数据源中和它匹配的行组合成一个新元组。<br />
SQL提供了多种类型的连接方式，它们之间的区别在于：从相互交叠的不同数据集合中选择用于连接的行时所采用的方法不同。<br />
连接类型&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 定义<br />
内连接&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 只连接匹配的行<br />
左外连接&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 包含左边表的全部行（不管右边的表中是否存在与它们匹配的行），以及右边表中全部匹配的行<br />
右外连接&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 包含右边表的全部行（不管左边的表中是否存在与它们匹配的行），以及左边表中全部匹配的行<br />
全外连接&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 包含左、右两个表的全部行，不管另外一边的表中是否存在与它们匹配的行。<br />
(H)(theta)连接&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用等值以外的条件来匹配左、右两个表中的行<br />
交叉连接&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 生成笛卡尔积－它不使用任何匹配或者选取条件，而是直接将一个数据源中的每个行与另一个数据源的每个行都一一匹配<br />
在INFORMIX中连接表的查询<br />
如果FROM子句指定了多于一个表引用，则查询会连接来自多个表的行。连接条件指定各列之间（每个表至少一列）进行连接的关系。因为正在比较连接条件中的列，所以它们必须具有一致的数据类型。<br />
SELECT语句的FROM子句可以指定以下几种类型的连接<br />
FROM子句关键字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 相应的结果集<br />
CROSS <strong style="color: black; background-color: #99ff99;">JOIN</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 笛卡尔乘积（所有可能的行对）<br />
INNER <strong style="color: black; background-color: #99ff99;">JOIN</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 仅对满足连接条件的CROSS中的列<br />
<strong style="color: black; background-color: #ffff66;">LEFT</strong> <strong style="color: black; background-color: #a0ffff;">OUTER</strong> <strong style="color: black; background-color: #99ff99;">JOIN</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个表满足条件的行，和另一个表的所有行<br />
RIGHT <strong style="color: black; background-color: #a0ffff;">OUTER</strong> <strong style="color: black; background-color: #99ff99;">JOIN</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 与<strong style="color: black; background-color: #ffff66;">LEFT</strong>相同，但两个表的角色互换<br />
FULL <strong style="color: black; background-color: #a0ffff;">OUTER</strong> <strong style="color: black; background-color: #99ff99;">JOIN</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong style="color: black; background-color: #ffff66;">LEFT</strong> <strong style="color: black; background-color: #a0ffff;">OUTER</strong> 和 RIGHT <strong style="color: black; background-color: #a0ffff;">OUTER</strong>中所有行的超集<br />
<br />
2.2 内连接（Inner <strong style="color: black; background-color: #99ff99;">Join</strong>）<br />
内连接是最常见的一种连接，它页被称为普通连接，而E.FCodd最早称之为自然连接。<br />
下面是ANSI SQL－92标准<br />
select * <br />
from&nbsp;&nbsp;&nbsp; t_institution i <br />
inner <strong style="color: black; background-color: #99ff99;">join</strong> t_teller t <br />
on i.inst_no = t.inst_no<br />
where i.inst_no = "5801"<br />
其中inner可以省略。<br />
等价于早期的连接语法<br />
select * <br />
from t_institution i, t_teller t <br />
where i.inst_no = t.inst_no<br />
and i.inst_no = "5801"<br />
<br />
2.3 外连接<br />
2.3.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 左外连接(<strong style="color: black; background-color: #ffff66;">Left</strong> <strong style="color: black; background-color: #a0ffff;">Outer</strong> Jion)<br />
select * <br />
from&nbsp;&nbsp;&nbsp; t_institution i <br />
<strong style="color: black; background-color: #ffff66;">left</strong> <strong style="color: black; background-color: #a0ffff;">outer</strong> <strong style="color: black; background-color: #99ff99;">join</strong> t_teller t <br />
on i.inst_no = t.inst_no<br />
其中<strong style="color: black; background-color: #a0ffff;">outer</strong>可以省略。<br />
2.3.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 右外连接(Rigt <strong style="color: black; background-color: #a0ffff;">Outer</strong> Jion)<br />
select * <br />
from&nbsp;&nbsp;&nbsp; t_institution i <br />
right <strong style="color: black; background-color: #a0ffff;">outer</strong> <strong style="color: black; background-color: #99ff99;">join</strong> t_teller t <br />
on i.inst_no = t.inst_no<br />
2.3.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 全外连接(Full <strong style="color: black; background-color: #a0ffff;">Outer</strong>)<br />
全外连接返回参与连接的两个数据集合中的全部数据，无论它们是否具有与之相匹配的行。在功能上，它等价于对这两个数据集合分别进行左外连接和右外连接，然后再使用消去重复行的并操作将上述两个结果集合并为一个结果集。<br />
在现实生活中，参照完整性约束可以减少对于全外连接的使用，一般情况下左外连接就足够了。在数据库中没有利用清晰、规范的约束来防范错误数据情况下，全外连接就变得非常有用了，你可以使用它来清理数据库中的数据。<br />
select * <br />
from&nbsp;&nbsp;&nbsp; t_institution i <br />
full <strong style="color: black; background-color: #a0ffff;">outer</strong> <strong style="color: black; background-color: #99ff99;">join</strong> t_teller t <br />
on i.inst_no = t.inst_no<br />
2.3.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 外连接与条件配合使用<br />
当在内连接查询中加入条件是，无论是将它加入到<strong style="color: black; background-color: #99ff99;">join</strong>子句，还是加入到where子句，其效果是完全一样的，但对于外连接情况就不同了。当把条件加入到<strong style="color: black; background-color: #99ff99;">join</strong>子
句时，SQL Server、Informix会返回外连接表的全部行，然后使用指定的条件返回第二个表的行。如果将条件放到where子句中，SQL
Server将会首先进行连接操作，然后使用where子句对连接后的行进行筛选。下面的两个查询展示了条件放置位子对执行结果的影响：<br />
条件在<strong style="color: black; background-color: #99ff99;">join</strong>子句<br />
select * <br />
from&nbsp;&nbsp;&nbsp; t_institution i <br />
<strong style="color: black; background-color: #ffff66;">left</strong> <strong style="color: black; background-color: #a0ffff;">outer</strong> <strong style="color: black; background-color: #99ff99;">join</strong> t_teller t <br />
on i.inst_no = t.inst_no<br />
and i.inst_no = &#8220;5801&#8221;<br />
结果是：<br />
inst_no&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inst_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inst_no&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; teller_no&nbsp;&nbsp;&nbsp; teller_name<br />
5801&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 天河区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5801&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tom<br />
5801&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 天河区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5801&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; david<br />
5802&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 越秀区<br />
5803&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 白云区<br />
条件在where子句<br />
select * <br />
from&nbsp;&nbsp;&nbsp; t_institution i <br />
<strong style="color: black; background-color: #ffff66;">left</strong> <strong style="color: black; background-color: #a0ffff;">outer</strong> <strong style="color: black; background-color: #99ff99;">join</strong> t_teller t <br />
on i.inst_no = t.inst_no<br />
where i.inst_no = &#8220;5801&#8221;<br />
结果是：<br />
inst_no&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inst_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inst_no&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; teller_no&nbsp;&nbsp;&nbsp; teller_name<br />
5801&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 天河区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5801&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tom<br />
5801&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 天河区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5801&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; david<br />
<br />
2.4 自身连接<br />
自身连接是指同一个表自己与自己进行连接。这种一元连接通常用于从自反关系（也称作递归关系）中抽取数据。例如人力资源数据库中雇员与老板的关系。<br />
下面例子是在机构表中查找本机构和上级机构的信息。<br />
select s.inst_no superior_inst, s.inst_name sup_inst_name, i.inst_no, i.inst_name<br />
from t_institution i<br />
<strong style="color: black; background-color: #99ff99;">join</strong> t_institution s<br />
on i.superior_inst = s.inst_no<br />
<br />
结果是：<br />
superior_inst sup_inst_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inst_no&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inst_name<br />
800&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 广州市&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5801&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 天河区<br />
800&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 广州市&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5802&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 越秀区<br />
800&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 广州市&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5803&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 白云区<br />
<br />
2.5 交叉(无限制) 连接<br />
交叉连接用于对两个源表进行纯关系代数的乘运算。它不使用连接条件来限制结果集合，而是将分别来自两个数据源中的行以所有可能的方式进行组合。数据集合中
一的每个行都要与数据集合二中的每一个行分别组成一个新的行。例如，如果第一个数据源中有5个行，而第二个数据源中有4个行，那么在它们之间进行交叉连接
就会产生20个行。人们将这种类型的结果集称为笛卡尔乘积。<br />
大多数交叉连接都是由于错误操作而造成的；但是它们却非常适合向数据库中填充例子数据，或者预先创建一些空行以便为程序执行期间所要填充的数据保留空间。<br />
select *<br />
from&nbsp;&nbsp;&nbsp; t_institution i <br />
cross <strong style="color: black; background-color: #99ff99;">join</strong> t_teller t<br />
在交叉连接中没有on条件子句<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -----http://hi.baidu.com/llscompazz/blog/item/dc5e23d9ce2b62eb39012fb4.html<br />
<img src ="http://www.blogjava.net/algz/aggbug/228219.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-09-10 21:55 <a href="http://www.blogjava.net/algz/articles/228219.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]SQL中的各种JOIN（inner join,full outer join,left join,right join,cross join ）</title><link>http://www.blogjava.net/algz/articles/228218.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Wed, 10 Sep 2008 13:53:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/228218.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/228218.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/228218.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/228218.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/228218.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt; color: #868374;">
<p style="margin: 0cm 0cm 0pt; line-height: 150%; text-align: left;" align="left"><font color="#000000"><strong><span style="font-size: 12pt; line-height: 150%;">SQL</span></strong><strong><span style="font-size: 12pt; line-height: 150%;">中的各种JOIN</span></strong><strong><span style="font-size: 12pt; line-height: 150%;">（<span>inner
join,full outer join,left join,right join,cross join
</span>）</span></strong></font></p>
<p style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><font color="#000000" size="3">SQL</font><font color="#000000" size="3">中的连接可以分为内连接，外连接，以及交叉连接 <span>(即是笛卡尔积</span></font><font size="3"><font color="#000000">) <br />
<br />
a. 交叉连接</font></font><font size="3"><font color="#000000"><span>CROSS
JOIN<br />
</span>如果不带WHERE条件子句，它将会返回被连接的两个表的笛卡尔积，返回结果的行数等于两个表行数的乘积；</font></font><br />
<br />
<font color="#000000" size="3">举例,下列A、B、<span>C
</span>执行结果相同，但是效率不一样：</font><span><br />
<font size="3"><font color="#000000">A:SELECT
* FROM table1 CROSS JOIN table2<br />
B:SELECT * FROM
table1,table2</font></font></span></p>
</span>
<p style="margin: 0cm 0cm 0pt; background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" align="left"><font size="3"><font color="#000000">C:<span>select * from table1 a inner join table2
b</span></font></font></p>
<p style="margin: 0cm 0cm 0pt; background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" align="left"><span><br />
<font color="#000000" size="3">A:select a.*,b.* from table1
a,table2 b where a.id=b.id<br />
B:select * from table1 a cross join table2 b where a.id=b.id
(</font></span><span><font size="3"><font color="#000000">注：<span>cross
join</span>后加条件只能用where,不能用on)</font></font></span><br />
<font color="#000000" size="3">C:</font><font size="3"><font color="#000000"><span>select * from table1
a inner join table2 b on a.id=b.id</span></font></font></p>
<p style="margin: 0cm 0cm 0pt; background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" align="left"><br />
<font color="#000000" size="3">一般不建议使用方法<span>A和B，因为如果有WHERE子句的话，往往会先生成两个表行数乘积的行的数据表然后才根据WHERE条件从中选择。</span></font><font size="3"><font color="#000000"><span>
<br />
</span>因此，如果两个需要求交际的表太大，将会非常非常慢，不建议使用。</font></font><br />
<br />
<font color="#000000" size="3">b. </font><font color="#000000" size="3">内连接</font><font size="3"><font color="#000000"><span>INNER
JOIN<br />
</span>两边表同时符合条件的组合</font></font></p>
<p style="margin: 0cm 0cm 0pt; background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" align="left"><span><font color="#000000" size="3">如果仅仅使用</font><span><br />
<font size="3"><font color="#000000">SELECT * FROM table1 INNER JOIN
table2</font></font></span></span></p>
<p style="margin: 0cm 0cm 0pt; background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" align="left"><font color="#000000" size="3">内连接如果没有指定连接条件的话，和笛卡尔积的交叉连接结果一样，但是不同于笛卡尔积的地方是，没有笛卡尔积那么复杂要先生成行数乘积的数据表，内连接的效率要高于笛卡尔积的交叉连接。</font><span><br />
<br />
<font size="3"><font color="#000000">但是通常情况下，使用<span>INNER
JOIN</span>需要指定连接条件。</font></font></span></p>
<p style="margin: 0cm 0cm 0pt; background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" align="left"><font size="3"><font color="#000000">***************关于等值连接和自然连接</font></font></p>
<p style="margin: 0cm 0cm 0pt; background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" align="left"><font size="3"><font color="#000000">等值连接<span>(=号应用于连接条件<span>,
</span>不会去除重复的列)</span></font></font></p>
<p style="margin: 0cm 0cm 0pt; background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" align="left"><font size="3"><font color="#000000">自然连接(会去除重复的列)</font></font></p>
<p style="margin: 0cm 0cm 0pt; background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" align="left"><font color="#000000" size="3">数据库的连接运算都是自然连接，因为不允许有重复的行（元组）存在。</font><br />
<font size="3"><font color="#000000">例如：</font></font></p>
<p style="margin: 0cm 0cm 0pt; background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" align="left"><span><font color="#000000" size="3">SELECT * FROM table1 AS a INNER JOIN table2 AS b on
a.column=b.column<br />
<br />
c. </font></span><span><font color="#000000" size="3">外连接</font><font size="3"><font color="#000000"><span>OUTER
JOIN<br />
</span>指定条件的内连接，仅仅返回符合连接条件的条目。</font></font><br />
<font color="#000000" size="3">外连接则不同，返回的结果不仅包含符合连接条件的行，而且包括左表(左外连接时<span>),
</span>右表(右连接时)或者两边连接(全外连接时)的所有数据行。</font><br />
<br />
<font color="#000000" size="3">1)</font><font color="#000000" size="3">左外连接</font><font size="3"><font color="#000000"><span>LEFT [OUTER] JOIN
<br />
</span>显示符合条件的数据行，同时显示左边数据表不符合条件的数据行，右边没有对应的条目显示</font></font><font size="3"><font color="#000000">NULL<br />
例如</font></font><span><br />
<font color="#000000" size="3">SELECT * FROM table1 AS a LEFT [OUTER] JOIN ON
a.column=b.column<br />
2)</font></span><font color="#000000" size="3">右外连接</font><font size="3"><font color="#000000"><span>RIGHT [OUTER]
JOIN<br />
</span>显示符合条件的数据行，同时显示右边数据表不符合条件的数据行，左边没有对应的条目显示</font></font><font size="3"><font color="#000000">NULL<br />
例如</font></font><span><br />
<font color="#000000" size="3">SELECT * FROM table1 AS a RIGHT [OUTER] JOIN ON
a.column=b.column<br />
3)</font></span><font color="#000000" size="3">全外连接</font><font size="3"><font color="#000000"><span>full [outer]
join<br />
</span>显示符合条件的数据行，同时显示左右不符合条件的数据行，相应的左右两边显示NULL，即显示左连接、右连接和内连接的并集</font></font></span></p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------http://hi.baidu.com/magickerr/blog/item/393c0a01aa13290b7aec2c63.html
<img src ="http://www.blogjava.net/algz/aggbug/228218.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-09-10 21:53 <a href="http://www.blogjava.net/algz/articles/228218.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>String,int,Integer,char 类型转换</title><link>http://www.blogjava.net/algz/articles/227937.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Tue, 09 Sep 2008 06:18:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/227937.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/227937.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/227937.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/227937.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/227937.html</trackback:ping><description><![CDATA[<p><strong>&nbsp;如何将字串 String 转换成整数 int?</strong> <br />
int i = Integer.valueOf(my_str).intValue(); </p>
<p>int i=Integer.parseInt(str); </p>
<p><strong>如何将字串 String 转换成Integer ?</strong><br />
Integer integer=Integer.valueOf(str); </p>
<p><strong>如何将整数 int 转换成字串 String ?</strong> <br />
1.) String s = String.valueOf(i);<br />
&nbsp;<br />
2.) String s = Integer.toString(i); <br />
&nbsp;<br />
3.) String s = "" + i; <br />
<br />
<strong>如何将整数 int 转换成Integer ?</strong> <br />
Integer integer=new Integer(i); </p>
<p><strong>如何将Integer 转换成字串 String ?</strong> <br />
Integer integer＝String </p>
<p><strong>如何将Integer 转换成 int ?</strong> <br />
int num=Integer.intValue(); </p>
<p><strong>如何将String转换成&nbsp; BigDecimal&nbsp; ?</strong> <br />
&nbsp;BigDecimal d_id = new BigDecimal(str); <br />
</p>
<p><br />
<strong>如何将 String 转换成 char ?</strong><br />
char[] ca="123".toCharArray();<br />
<br />
<strong>如何将char转换成String?</strong><br />
String s=ca.toString();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //任何类型都可以采用toString()转换成String类型<br />
<br />
//-----------------日期------------------------- </p>
<p>Calendar calendar=Calendar.getInstance();<br />
&nbsp; int year=calendar.get(Calendar.YEAR);<br />
&nbsp; int month=calendar.get(Calendar.MONTH)+1;<br />
&nbsp; int day=calendar.get(Calendar.DATE); </p>
<p>获取今天的日期字符串<br />
String today=java.text.DateFormat.getDateInstance().format(new java.util.Date());<br />
获取今天的日期<br />
new java.sql.Date(System.currentTimeMillis()) </p>
 <img src ="http://www.blogjava.net/algz/aggbug/227937.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-09-09 14:18 <a href="http://www.blogjava.net/algz/articles/227937.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate 分页查询</title><link>http://www.blogjava.net/algz/articles/227905.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Tue, 09 Sep 2008 03:47:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/227905.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/227905.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/227905.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/227905.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/227905.html</trackback:ping><description><![CDATA[<p><span style="color: #99cc00">&nbsp;/**<br />
&nbsp; * 使用 hql 语句进行操作<br />
&nbsp; * @param hql&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HSQL 查询语句<br />
&nbsp; * @param offset&nbsp;&nbsp; 开始取数据的下标<br />
&nbsp; * @param length&nbsp;&nbsp;&nbsp;读取数据记录数<br />
&nbsp; * @return List&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;结果集<br />
&nbsp; */</span><br />
&nbsp;public List getListForPage ( final String hql , final int offset , final int length ) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; List list = getHibernateTemplate().executeFind ( new HibernateCallback ( ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Object doInHibernate ( Session session ) throws HibernateException, SQLException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #99cc00">//final String queryString = "from Fourm f where f.identity='" + property+"'";</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query query = session.createQuery ( hql ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #99cc00">//&nbsp;&nbsp;&nbsp;&nbsp;query.setString(0, value);&nbsp; //设置查询参数</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.setFirstResult ( offset ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.setMaxResults ( length ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List list = query.list ( ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return list ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }) ;<br />
&nbsp;&nbsp;&nbsp; return list ;<br />
&nbsp;}</p>
<img src ="http://www.blogjava.net/algz/aggbug/227905.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-09-09 11:47 <a href="http://www.blogjava.net/algz/articles/227905.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Spring托管的Hibernate中使用二级缓存的三种方法</title><link>http://www.blogjava.net/algz/articles/227902.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Tue, 09 Sep 2008 03:37:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/227902.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/227902.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/227902.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/227902.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/227902.html</trackback:ping><description><![CDATA[<p>１．在spring的配置文件中 applicationContent.xml，hibernate部分加入<br />
xml 代码<br />
&lt;prop key="hibernate.cache.provider_class"&gt;org.hibernate.cache.EhCacheProvider&lt;/prop&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;prop key="hibernate.cache.use_query_cache"&gt;true&lt;/prop&gt;&nbsp;&nbsp; </p>
<p>２．为 hibernate的配置文件中设置cache策略</p>
<p>xml 代码<br />
&lt;cache usage="nonstrict-read-write"/&gt;&nbsp;&nbsp; </p>
<p>３．在DAO中，调用find方法查询之前，设置使用缓存</p>
<p>java 代码<br />
getHibernateTemplate().setCacheQueries(true);&nbsp; </p>
<img src ="http://www.blogjava.net/algz/aggbug/227902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-09-09 11:37 <a href="http://www.blogjava.net/algz/articles/227902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HIbernate的参数使用说明</title><link>http://www.blogjava.net/algz/articles/197799.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Fri, 02 May 2008 14:43:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/197799.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/197799.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/197799.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/197799.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/197799.html</trackback:ping><description><![CDATA[<strong>set节点有以下属性</strong>（摘自Hibernate文档）：<br />
(1)&nbsp;name&nbsp;集合属性的名称&nbsp;<br />
&nbsp;<br />
(2)&nbsp;table&nbsp;（可选默认为属性的名称）这个集合表的名称(不能在一对多的关联关系中使用)&nbsp;<br />
&nbsp;<br />
(3)&nbsp;schema&nbsp;(可选)&nbsp;表的schema的名称,&nbsp;他将覆盖在根元素中定义的schema&nbsp;<br />
&nbsp;<br />
(4)&nbsp;lazy&nbsp;(可选默认为false)&nbsp;lazy(可选--默认为false)&nbsp;允许延迟加载（lazy&nbsp;initialization&nbsp;）(不能在数组中使用)&nbsp;<br />
&nbsp;<br />
(5)&nbsp;inverse&nbsp;(可选默认为false)&nbsp;标记这个集合作为双向关联关系中的方向一端。&nbsp;<br />
&nbsp;<br />
(6)&nbsp;cascade&nbsp;(可选默认为none) 不进行级联操作,如保存,修改,删除&nbsp;<br />
&nbsp;<br />
(7)&nbsp;sort(可选)指定集合的排序顺序,&nbsp;其可以为自然的(natural)或者给定一个用来比较的类。&nbsp;<br />
&nbsp;<br />
(8)&nbsp;order-by&nbsp;(可选,&nbsp;仅用于jdk1.4)&nbsp;指定表的字段(一个或几个)再加上asc或者desc(可选),&nbsp;定义Map,Set和Bag的迭代顺序&nbsp;<br />
&nbsp;<br />
(9)&nbsp;where&nbsp;(可选)&nbsp;指定任意的SQL&nbsp;where条件,&nbsp;该条件将在重新载入或者删除这个集合时使用(当集合中的数据仅仅是所有可用数据的一个子集时这个条件非常有用)&nbsp;<br />
&nbsp;<br />
(10)&nbsp;outer-join(可选)指定这个集合,只要可能,应该通过外连接(outer&nbsp;join)取得。在每一个SQL语句中,&nbsp;只能有一个集合可以被通过外连接抓取(译者注:&nbsp;这里提到的SQL语句是取得集合所属类的数据的Select语句)&nbsp;<br />
&nbsp;<br />
(11)&nbsp;batch-size&nbsp;(可选,&nbsp;默认为1)&nbsp;指定通过延迟加载取得集合实例的批处理块大小（"batch&nbsp;size"）。&nbsp;<br />
&nbsp;<br />
(12)&nbsp;access(可选-默认为属性property):Hibernate取得属性值时使用的策略&nbsp;<br />
&nbsp;<br />
<strong>many-to-one节点有以下属性</strong>（摘自Hibernate文档）：<br />
(1)&nbsp;name:&nbsp;属性名。&nbsp;<br />
&nbsp;<br />
(2)&nbsp;column&nbsp;(可选):&nbsp;字段名。&nbsp;<br />
&nbsp;<br />
(3)&nbsp;class&nbsp;(可选&nbsp;-&nbsp;默认是通过反射得到属性类型):&nbsp;关联的类的名字。&nbsp;<br />
&nbsp;<br />
(4)&nbsp;cascade（级联）&nbsp;(可选):&nbsp;指明哪些操作会从父对象级联到关联的对象。&nbsp;<br />
&nbsp;<br />
(5)&nbsp;outer-join（外连接）&nbsp;(可选&nbsp;-&nbsp;默认为&nbsp;自动):&nbsp;当设置hibernate.use_outer_join的时候，对这个关联允许外连接抓取。&nbsp;<br />
&nbsp;<br />
(6)&nbsp;update,&nbsp;insert&nbsp;(可选&nbsp;-&nbsp;defaults&nbsp;to&nbsp;true)&nbsp;指定对应的字段是否在用于UPDATE&nbsp;和/或&nbsp;INSERT的SQL语句中包含。如果二者都是false,则这是一个纯粹的&#8220;外源性（derived）&#8221;关联，它的值是通过映射到同一个（或多个）字段的某些其他属性得到的，或者通过trigger(除法器），或者是其他程序。&nbsp;<br />
&nbsp;<br />
(7)&nbsp;property-ref:&nbsp;(可选)&nbsp;指定关联类的一个属性，这个属性将会和本外键相对应。如果没有指定，会使用对方关联类的主键。&nbsp;<br />
&nbsp;<br />
(8)&nbsp;access&nbsp;(可选&nbsp;-&nbsp;默认是&nbsp;property):&nbsp;Hibernate用来访问属性的策略。&nbsp;<br />
&nbsp;<br />
cascade&nbsp;属性允许下列值：&nbsp;all,&nbsp;save-update,&nbsp;delete,&nbsp;none。设置除了none以外的其它值会传播特定的操作到关联的（子）对象中。参见后面的&#8220;Lifecycle&nbsp;Objects(自动管理生命周期的对象）&#8221;。&nbsp;<br />
<br />
outer-join参数允许下列三个不同值：&nbsp;<br />
<br />
auto&nbsp;(默认)&nbsp;使用外连接抓取关联（对象），如果被关联的对象没有代理(proxy)&nbsp;<br />
<br />
true&nbsp;一直使用外连接来抓取关联&nbsp;<br />
<br />
false&nbsp;永远不使用外连接来抓取关联&nbsp;<img src ="http://www.blogjava.net/algz/aggbug/197799.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-05-02 22:43 <a href="http://www.blogjava.net/algz/articles/197799.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate  HQL 语法 及相关的外键关联</title><link>http://www.blogjava.net/algz/articles/191835.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Thu, 10 Apr 2008 05:33:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/191835.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/191835.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/191835.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/191835.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/191835.html</trackback:ping><description><![CDATA[<div class="cnt"><span class="Apple-style-span" style="color: #339966; ">pa.equipmentaccount.id=?pa.equipmentaccount.idpa.equipmentaccount.id</span><a class="postTitle2" href="http://www.blogjava.net/myblog/archive/2006/07/07/56865.html"><font color="#56b6e9">HQL</font> </a><br />
<br />
例如对于TUser类<br />
<br />
1.实体查询<br />
<font style="background-color: #deb887">String hql = " from User"; </font><br />
<br />
执行这条语句会<span style="color: #339966">返回User</span>以及User子类的<span style="color: #339966">纪录</span>。<br />
<span style="color: #99cc00">注:&nbsp; 如果 TUser 类具有外键, 查询结果不会报错,但结果中的外键为空值,访问就报空指针错误!<br />
<span style="color: #000000">解决方法:&nbsp;&nbsp;select 别名.属性 from 类 as 别名. 没有别名.属性仍然报错!&nbsp; //此方法不一定能解决,但不会错.<br />
</span></span><br />
<br />
<font style="background-color: #deb887">hql = "from java.lang.Object"</font><br />
会返回数据库中所有库表的纪录。<br />
<br />
where 语句，as可以省略<br />
<font style="background-color: #deb887">hql = "from User as user where user.name='yyy'";&nbsp;&nbsp;&nbsp; //user.name为类的属性</font><br />
<br />
<font style="background-color: #deb887">hql = "from User user where user.name='yyy'";</font><br />
<br />
where子句中，我们可以通过比较运算符设定条件，如：<br />
=, &lt;&gt;, &gt;, &lt;, &gt;=, &lt;=, between XX and XX, not between, in (xx,xx), not in, is, like %XX% 等。<br />
<br />
2.属性查询<br />
<font style="background-color: #deb887"><span style="color: #000000"><font style="background-color: #deb887"><span style="background-color: #000000"><span style="color: #000000; background-color: #ffffff">(1)List list = session.createQuery("<span style="color: #993300">select user.name, user.age from User&nbsp; user</span>").list();<br />
<br />
还可以在HQL中动态构造对象实例的方法，将数据封装。<br />
(2)List list = session.createQuery("select new User(user.name, user.age) from TUser as user").list();<br />
<br />
Iterator it = list.iterator();<br />
while(it.hasNext() ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; User user = (User)it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(user.getName());<br />
}</span><br />
</span></font></span></font><font style="background-color: #deb887; "><font style="background-color: #ffffff">但是要注意这里的User对象只是对name和age属性的封装，其他状态均未赋值，所以不能用它来进行更新操作。<br />
</font><br />
<font style="background-color: #ffffff">也可以在HQL的Select子句中使用统计函数<br />
</font><font style="background-color: #ffffff"><span style="color: #993300"><font style="background-color: #ffffff">"select count(*) ,min(user.age) from User as user"<br />
</font></span><br />
也可以使用distinct关键字来删除重复纪录。<br />
<span style="color: #993300">select distinct user.name from User as user;</span><br />
<br />
3.实体的更新与删除<br />
<br />
hibernate 3中，提供了更灵活的方式(bulk(集体) delete/update)<br />
更新：<br />
&nbsp;&nbsp;&nbsp;&nbsp; Query query = session.createQuery("<span style="color: #993300">update User set age=18 where id=1</span>"); //age==User.age<br />
&nbsp;&nbsp;&nbsp;&nbsp; query.executeUpdate();<br />
删除：<br />
</font><font style="background-color: #000000; "><font style="background-color: #ffffff; " color="#000000">&nbsp;&nbsp;&nbsp;&nbsp; session.createQuery("<span style="color: #993300">delete User where age&gt;=18</span>");<br />
&nbsp;&nbsp;&nbsp;&nbsp; query.executeUpdate();<br />
<br />
<span style="color: #339966; ">注:不支持联表更新,即此处的User对象不能外键关联.因为更新操作不允许多表联接更新,只能更新一张表(SQL规定).</span><br />
<span style="color: #339966; ">如:</span></font></font></font><span class="Apple-style-span" style="background-color: #ffffff; color: #339966; ">update TbPartaccount pa set inoutflag=9 where pa.equipmentaccount.id=:id instr(pa.equipmentaccount.id,'Z')=1<br />
</span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">pa.equipmentaccount.inoutcode报错,
<div style="display: inline-block; "></div>
</span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">pa.equipmentaccount.id还是
<div style="display: inline-block; "></div>
</span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">TbPartaccount&nbsp;的字段(外键关联)<br /><br />
Hibernate 不能像我们想像的那样转换成以下方式,所以还是需要手工写子查询:</span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">
<div>
<div>UPDATE TB_PARTACCOUNT pa set PA.INOUTFLAG=9 where pa.equipmentaccount.id=? and pa.eaccount_code=(</div></div></span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">
<div>
<div>SELECT ea.id from TB_EQUIPMENTACCOUNT ea&nbsp;</div>
</div>
</span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">
<div>
<div>where ea.id=pa.EACCOUNT_CODE and INSTR(ea.inoutcode, 'Z')=1)</div>
</div>
</span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">
<div>
<div>而是转成以下形式并报异常:没有找到SET关键字:</div>
</div>
</span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">
<div>
<div>UPDATE TB_PARTACCOUNT pa set PA.INOUTFLAG=9 where&nbsp;<div style="display: inline-block; "></div></div>
</div>
</span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">pa.equipmentaccount.id=?</span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">&nbsp;and&nbsp;</span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">INSTR(pa.eaccount_code, 'Z')=1</span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; "><div>
<div>&nbsp;</div></div></span><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; "><div>
<div>&nbsp;&nbsp;</div></div></span><font class="Apple-style-span" color="#339966"><br />
</font><span class="Apple-style-span" style="color: #339966; background-color: #ffffff; ">
<div>
<div>&nbsp;&nbsp;</div>
</div>
</span><font style="background-color: #deb887; "><font style="background-color: #000000"><font style="background-color: #ffffff" color="#000000">
<div>
<div></div>
</div>
</font></font></font><font style="background-color: #deb887; "><font style="background-color: #000000"><font style="background-color: #ffffff" color="#000000">
<div>
<div>
<div>
<div></div>
</div>
</div>
</div>
<br />
4.分组与排序<br />
Order by子句：<br />
&nbsp;&nbsp;&nbsp;&nbsp; from User user order by user.name, user.age desc<br />
Group by子句和Having子句<br />
&nbsp;&nbsp;&nbsp;&nbsp; "select count(user), user.age from User user group by user.age having count(user)&gt;10"<br />
<br />
5.参数邦定<br />
通过顺序占位符?来填充参数：<br />
1)hibernate 2 中通过session.find方法来填充<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.find("from User user where user.name=?", "Erica", Hibernate.STRING);<br />
&nbsp;&nbsp; 多个参数的情况：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object[] args = new Object[] {"Erica", new Integer(20)};<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Type[] types = new Type{Hibernate.STRING, Hibernate.INTEGER};<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.find("from TUser user where user.name=? and user.age=?", args, types);<br />
<br />
2)<span style="color: #808000">通过Query接口进行参数填充</span>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query query = session.createQuery("from User user where user.name=? and user.age&gt;?");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.setString(0,"Erica");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.setInteger(1, 20);<br />
<br />
通过引用占位符来填充参数：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String hql = "from User where name=:name";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query query = session.createQuery(hql);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.setParameter("name","Erica");<br />
<br />
甚至可以将查询条件封装为一个JavaBean<br />
class UserQuery {<br />
&nbsp;&nbsp;&nbsp;&nbsp; private String name;<br />
&nbsp;&nbsp;&nbsp;&nbsp; private Integer age;<br />
&nbsp;&nbsp;&nbsp;&nbsp; //getter and setter<br />
}<br />
String hql = "from TUser where name=:name and age=:age";<br />
Query query = session.createQuery(hql);<br />
UserQuery uq = new UserQuery();<br />
uq.setName("Erica");<br />
uq.setAge(new Integer(20));<br />
<br />
query.setProperties(uq); //会调用里面的getter?<br />
query.iterate();<br />
<br />
6.联合查询 <br />
(<span style="font-size: small"><span class="Apple-style-span" style="color: #4b4b4b; line-height: 17px; font-family: verdana; "><span style="font-size: x-small"><span style="font-size: x-small"><span style="font-size: x-small"><span style="font-size: x-small">org.hibernate.LazyInitializationException:&nbsp;<span style="color: #800000"><span style="color: #ff0000">could not initialize proxy - no Session</span></span></span></span></span></span></span></span> 异常,可能是HQL语句没有进行联表查询,产生访问的属性不存在.)<br />
&nbsp;&nbsp; User表: id, name<br />
&nbsp;&nbsp; Addresses表: user_id, addresses<br />
(1)自然联接(内联接):&nbsp; inner join [fetch]<br />
<span style="color: #808000">1.HQL: from User u inner join<span style="color: #339966">&nbsp;fetch </span>u.addresses <span style="color: #000000"><br />
</span></span>&nbsp;&nbsp; SQL: select * from User表 u inner join Addresses a on u.id=a.user_id //u.id=a.user_id在XML中已配置,所以可以省略.<br />
<span style="color: #000000">&nbsp;&nbsp; fetch: Addresses对象读出后,立即填充到User对象对应的外键(集合)中.<br />
<br />
</span><span style="color: #808000">2.HQL: from User u inner join<span style="color: #339966">&nbsp; </span>u.addresses&nbsp;</span><br />
&nbsp;&nbsp; 不加fetch,则返回的结果集中的每一条记录是一个Object数组,数组包括User和Addresses两个对象, 并且User对象.addresses集合已被Addresses对象自动填充.<br />
<br />
(2)左连接:&nbsp; left outer join [fetch]<br />
&nbsp;&nbsp;&nbsp; 同(1), 返回的结果不同而已.<br />
<br />
(3)右连接:&nbsp; right out join&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;fetch无效,因为User对象可能为NULL,无法进行填充,但返回结果里的记录是数组.<br />
<br />
(4)笛卡尔交集: full join (使用很少)&nbsp;<br />
&nbsp;&nbsp;&nbsp; 同(3), 返回结果不同而已.<br />
<br />
(5)笛卡尔集:&nbsp; 排列组合：form User, Address<br />
<br />
联合查询如有不懂, 详见SQL联合语句:<br />
SQL中的left outer join,inner join,right outer join用法<a href="http://www.blogjava.net/algz/articles/228219.html">:&nbsp;&nbsp; http://www.blogjava.net/algz/articles/228219.html</a><br />
SQL中的各种JOIN（inner join,full outer join,left join,right join,cross join ）<a href="http://www.blogjava.net/algz/articles/228218.html"><font color="#000000">:</font>http://www.blogjava.net/algz/articles/228218.html</a><br />
sql的left join 命令详解 <a href="http://www.blogjava.net/algz/articles/228220.html">: http://www.blogjava.net/algz/articles/228220.html</a><br />
</font></font></font></div><img src ="http://www.blogjava.net/algz/aggbug/191835.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-04-10 13:33 <a href="http://www.blogjava.net/algz/articles/191835.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>webapps JSF+Spring+Hibernate项目开发流程</title><link>http://www.blogjava.net/algz/articles/190077.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Tue, 01 Apr 2008 06:48:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/190077.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/190077.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/190077.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/190077.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/190077.html</trackback:ping><description><![CDATA[&lt;h:outputText value="主题：#{index.appinfo.maxdocsum} value里不能加入HTML代码但可以加入EL" /&gt;<br />
<br />
序.画流程图.<br />
<span style="color: #008000">一.创建数据库.</span><br />
注:<br />
1.数据库中设计INT(java.lang.Interger),&nbsp; VARCHAR(N)(java.lang.String),&nbsp; DATE(java.lang.Date)<br />
2.1:N的情况下, 数据库中设计外键(N方)和集合(一方).<br />
2.hibernate 返向工程.<br />
<br />
<span style="color: #008000">二.添加JSF, Spring,&nbsp;Hibernate 库引用.<br />
<span style="color: #000000">Spring 添加如下：</span><br />
</span><img height="98" alt="" src="http://www.blogjava.net/images/blogjava_net/algz/addspring1.jpg" width="397" border="0" /><br />
<img height="95" alt="" src="http://www.blogjava.net/images/blogjava_net/algz/addspring2.jpg" width="394" border="0" /><br />
<br />
<span style="color: #008000">三. 为spring 配置 web.xml 和 faces-config.xml .</span><br />
(1)web.xml<br />
&nbsp;&lt;context-param&gt;<br />
&nbsp;&nbsp;&lt;param-name&gt;<span style="color: #339966">contextConfigLocation</span>&lt;/param-name&gt;<br />
&nbsp;&nbsp;&lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;<br />
&nbsp;&lt;/context-param&gt;<br />
<br />
(2)web.xml<br />
&lt;listener&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;listener-class&gt;<span style="color: #339966">org.springframework.web.context.ContextLoaderListener</span>&lt;/listener-class&gt;<br />
&lt;/listener&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Servlet API 2.3以后<br />
或:<br />
&nbsp;&lt;servlet&gt;<br />
&nbsp;&nbsp;&lt;servlet-name&gt;context&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&lt;servlet-class&gt;org.springframework.web.context.ContextLoaderServlet&lt;/servlet-class&gt;<br />
&nbsp;&nbsp;&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />
&nbsp;&lt;/servlet&gt;
<p><br />
(3)faces-config.xml<br />
&lt;application&gt;<br />
&lt;variable-resolver&gt;<span style="color: #339966">org.springframework.web.jsf.DelegatingVariableResolver</span>&lt;/variable-resolver&gt;<br />
&lt;/application&gt;<br />
<br />
(4)设置过滤器,解决乱码问题<br />
详见:<a href="http://www.blogjava.net/algz/articles/201833.html ">http://www.blogjava.net/algz/articles/201833.html </a>第二条<br />
<br />
以上配置完成后.<span style="color: #33cccc">JSF</span>就可以访问<span style="color: #33cccc">SPRING管理的BEAN</span>.<br />
<br />
<span style="color: #339966"><span style="color: #339966"><span style="color: #008000">四.spring+hiberante集成时,asm-2.2.3.jar与asm.jar冲突:</span><br />
</span></span><span>org.springframework.beans.factory.BeanCreationException:&nbsp;Error&nbsp;creating&nbsp;bean&nbsp;with&nbsp;name&nbsp;'SessionFactory'&nbsp;defined&nbsp;in&nbsp;<span class="keyword">class</span><span>&nbsp;path&nbsp;resource&nbsp;[applicationContext.xml]:&nbsp;Invocation&nbsp;of&nbsp;init&nbsp;method&nbsp;failed;&nbsp;nested&nbsp;exception&nbsp;is&nbsp;java.lang.NoSuchMethodError:&nbsp;org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V&nbsp;&nbsp;</span></span><br />
...<br />
Caused by: java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V<br />
<br />
正确的解决方法:<br />
<span style="color: #000000">是到项目的发布文件夹\WEB-INF\lib下删除<span style="color: #339966">asm-2.2.3.jar</span>,不能用MyEclipse里删除.因为他在发布时仍没删除.</span><br />
<br />
<span style="color: #008000">五.创建进行分类的包.<br />
</span>com.dao(数据访问层), com.service(业务层), com.web(表示层)<br />
<br />
<span style="color: #008000">六.创建类.(完成MODEL层设计).&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; <br />
<span style="color: #000000">*****************************(<u>也可以利用MyEclipse反向ORM功能自动产生,<span style="color: #339966">但应注意自动配置引起的"类完全名"的错误</span></u>)*******************</span><br />
<br />
</span>&nbsp; (一)数据访问层(<span style="color: #008000">DAO</span>)开发:&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Spring 配置文件（附加）&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)配置数据源&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; <span style="color: #000000">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">dataSource</span><span style="color: #000000">"</span> ...&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Myeclipse Hibernate自动反转工具自动配置<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)配置会话工厂&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">sessionFactory</span><span style="color: #000000">" ...&gt;&nbsp; //Myeclipse Hibernate自动反转工具自动配置<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3)<span style="color: #000000"><span style="color: #000000"><span style="color: #000000">配置事务管理器</span>&nbsp; </span>&lt;bean id="transactionManager" ...&gt;<br />
</span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4)配置事务代理&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.blogjava.net/algz/articles/163236.html">www.blogjava.net/algz/articles/163236.html</a><br />
<span style="color: #339966">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808000">&nbsp;<span style="color: #000000">(5)数据访问层<span style="color: #808000">Bean</span>作为属性注入业务层<span style="color: #808000">Property</span>中. </span></span>(注:不要用NEW创建数据访问层对象,否则得不到ServletContext而报错.)<br />
</span>例:<br />
/**数据访问层Bean（Myeclipse Hibernate自动反转工具配置）*/<br />
&nbsp;&lt;bean id="<span style="color: #99cc00">userDao</span>" class="com.data.dao.impl.UserDaoImpl"&gt;<br />
&nbsp;&nbsp;&lt;property name="sessionFactory"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;ref local="sessionFactory" /&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
<br />
&nbsp;/**业务层Bean（Myeclipse Spring配置文档中可以配置，但需先定义好相关类）*/<br />
&nbsp;&lt;bean id="<span style="color: #33cccc">userService</span>" class="com.model.service.impl.UserServiceImpl"&gt;<br />
&nbsp;&nbsp;&lt;property name="userDao"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;ref bean="<span style="color: #99cc00">userDao</span>" /&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. 创建&nbsp;<span style="color: #99cc00">数据访问层接口:&nbsp;&nbsp;&nbsp; </span><span style="color: #008080">必须创建</span>,详见:<a href="http://www.blogjava.net/algz/articles/262893.html">http://www.blogjava.net/algz/articles/262893.html</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public interface <span style="color: #99cc00">数据访问层接口 </span>{&nbsp;&nbsp; //在类已存在的情况下,添加其接口:Refactor(重构）-&gt;Extract Interfaces提取接口<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public String add...();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public String save...();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //update, delete, load<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 .创建<span style="color: #33cccc">数据访问层实现类</span>&nbsp;&nbsp;&nbsp; //<span style="color: #000000"><span style="color: #000000">ORM反向功能自动配置<br />
</span></span><span style="color: #339966">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000">&nbsp;public class </span><span style="color: #33cccc">数据访问层实现类</span> <span style="color: #000000">extends&nbsp;<span style="color: #339966">HibernateDaoSupport</span>&nbsp;implements </span><span style="color: #99cc00">数据访问层接口 </span></span>{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //getHibernateTemplate().save(user)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在实现类的方法(throw DataAccessException)中封装 getHibernateTemplate().save(user) 等Spring已封装的持久化方法.(注:如果使用Hibernate API 要用try{...}catch{...}自行处理导常.)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.注意事项:<span style="color: #3366ff">&nbsp;could not initialize proxy - no Session&nbsp;</span>异常,&nbsp; 可能是没有联表查询.详见<a href="http://www.blogjava.net/algz/articles/191835.html"><font color="#000000">: </font>http://www.blogjava.net/algz/articles/191835.html</a><br />
<br />
<br />
<span style="color: #000000"><span style="color: #000000">*****************************(<u>也可以利用MyEclipse反向ORM功能自动产生</u>)***********************************</span></span><br />
<br />
&nbsp;&nbsp;&nbsp;(二)业务逻辑层(<span style="color: #33cccc"><span style="color: #008000">Service</span></span>)开发:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.创建<span style="color: #99cc00">业务逻辑层接口</span>.&nbsp;<br />
package com.service;<br />
import com.dao.CheckDAO;<br />
public interface <span style="color: #99cc00">ICheckService </span>{<br />
&nbsp;&nbsp;&nbsp; public abstract CheckDAO getCheckDAO();<br />
&nbsp;&nbsp;&nbsp; public abstract void setCheckDAO(CheckDAO checkDAO);<br />
&nbsp;&nbsp;&nbsp; public abstract String searchCheck();<br />
}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.创建<span style="color: #33cccc">业务逻辑层实现类</span>&nbsp;<br />
<span style="color: #339966">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public class&nbsp;<span style="color: #33cccc">业务逻辑层实现类</span>&nbsp;implements <span style="color: #99cc00">业务逻辑层接口</span></span>.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在实现类中. 引用的数据访问层对象实例采用DI的设值方式注入<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在业务逻辑方法(throw DataAccessException)中,使用数据访问层对象实例来访问数据库.&nbsp;&nbsp;<br />
package com.service;<br />
import java.util.List;<br />
import org.json.simple.JSONArray;<br />
import org.json.simple.JSONObject;<br />
import com.dao.Check;<br />
import com.dao.CheckDAO;<br />
import com.dao.ICheckDAO;<br />
<br />
public class <span style="color: #33cccc">CheckService </span>implements <span style="color: #99cc00">ICheckService </span>{<br />
private CheckDAO checkDAO;</p>
<p>public CheckDAO getCheckDAO() {<br />
&nbsp;return checkDAO;<br />
}</p>
<p>public void setCheckDAO(CheckDAO checkDAO) {<br />
&nbsp;this.checkDAO = checkDAO;<br />
}<br />
<br />
public String searchCheck(){<br />
&nbsp;List&lt;Check&gt; l=checkDAO.findAll();<br />
&nbsp;JSONArray ja=new JSONArray();<br />
&nbsp;JSONObject jo=new JSONObject();<br />
for(Check c:l){<br />
//&nbsp;&nbsp;jo.put("department", c.getDepartment());<br />
//&nbsp;&nbsp;jo.put("checkid", c.getCheckid());<br />
//&nbsp;&nbsp;jo.put("nam", c.getNam());<br />
//&nbsp;&nbsp;jo.put("num", c.getNum());<br />
//&nbsp;&nbsp;jo.put("ondutytime", c.getOndutytime());<br />
//&nbsp;&nbsp;jo.put("offdutytime", c.getOffdutytime1());<br />
//&nbsp;&nbsp;jo.put("registerdate", c.getRegisterdate());<br />
//&nbsp;&nbsp;jo.put("overtime", c.getOvertime());<br />
//&nbsp;&nbsp;ja.add(jo.clone());<br />
//&nbsp;&nbsp;jo.clear();<br />
&nbsp;}<br />
&nbsp;&nbsp;return "";<br />
}</p>
<p>}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808000"><span style="color: #000000">3.数据</span><span style="color: #000000">访问层<span style="color: #808000">Bean</span>作为属性注入<span style="color: #33cccc">业务逻辑层实现类</span>的<span style="color: #808000">Property</span>中. </span></span>(注:不要用NEW创建数据访问层对象,否则得不到ServletContext而报错.)<br />
例:<br />
/**数据访问层Bean（Hibernate自动反转工具<span style="color: #008000">自动</span>配置）*/<br />
&nbsp;&lt;bean id="<span style="color: #99cc00">userDao</span>" class="com.data.dao.impl.UserDaoImpl"&gt;<br />
&nbsp;&nbsp;&lt;property name="sessionFactory"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;ref local="sessionFactory" /&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
<br />
&nbsp;/**业务逻辑层Bean（Spring配置文档中<span style="color: #008000">手动</span>配置，但需先定义好相关类）*/<br />
&nbsp;&lt;bean id="<span style="color: #33cccc">userService</span>" class="com.model.service.impl.UserServiceImpl"&gt;<br />
&nbsp;&nbsp;&lt;property name="userDao"&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;ref bean="<span style="color: #99cc00">userDao</span>" /&gt;<br />
&nbsp;&nbsp;&lt;/property&gt;<br />
&nbsp;&lt;/bean&gt;<br />
<br />
<span style="color: #008000">&nbsp;&nbsp;&nbsp;(三).表示层开发<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">(1)在 faces-config.xml 中配置托管BEAN</span></span>.(实现<font color="#008000">控制层</font>层设计) <br />
<span style="color: #339966">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 业务层bean作为属性注入CONTROL层中.<br />
</p>
<p><span style="color: #000000"><br />
package com.web;</span><span style="color: #000000"><br />
import com.service.ICheckService;<br />
</span><span style="color: #000000"><br />
public class SearchAll {<br />
&nbsp;private <span style="color: #339966">ICheckService </span>searchService;<br />
&nbsp;private String searchData;</span></p>
<p><span style="color: #000000">&nbsp;public SearchAll() {<br />
&nbsp;}</span></p>
<p><span style="color: #000000">&nbsp;public <span style="color: #339966">ICheckService </span>getSearchService() {<br />
&nbsp;&nbsp;return searchService;<br />
&nbsp;}</span></p>
<p><span style="color: #000000">&nbsp;public void setSearchService(<span style="color: #339966">ICheckService </span>searchService) {<br />
&nbsp;&nbsp;this.searchService = searchService;<br />
&nbsp;}</span></p>
<p><span style="color: #000000">&nbsp;public String getSearchData() {<br />
&nbsp;&nbsp;searchData = searchService.searchCheck();<br />
&nbsp;&nbsp;return searchData;<br />
&nbsp;}</span></p>
<p><span style="color: #000000">&nbsp;public void setSearchData(String searchData) {<br />
&nbsp;&nbsp;this.searchData = searchData;<br />
&nbsp;}<br />
}</span><br />
<br />
<span style="color: #000000">&nbsp;&lt;managed-bean&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-name&gt;<span style="color: #3366ff">userBean</span>&lt;/managed-bean-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-class&gt;com.web.SearchAll&lt;/managed-bean-class&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-scope&gt;session&lt;/managed-bean-scope&gt;<br />
&nbsp;&nbsp; &nbsp;&lt;managed-property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&lt;property-name&gt;searchService&lt;/property-name&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt; <span style="color: #33cccc">#{userService}</span>&lt;/value&gt;&nbsp;&nbsp;&nbsp;<span style="color: #3366ff"><span style="color: #008080">&nbsp;//直接引用spring定义的bean</span><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/managed-property&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property-name&gt;searchData&lt;/property-name&gt;&nbsp;&nbsp;&nbsp; //页面中 userBean.name访问属性的数据<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;123&lt;/value&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//属性默认值<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/managed-property&gt;<br />
&nbsp;&lt;/managed-bean&gt;</span><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">(2)Bean访问客户端传来的参数值<br />
</span>&nbsp;&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletRequest request=(HttpServletRequest)<span style="color: #008000">&nbsp;FacesContext</span>.<span style="color: #008000">getCurrentInstance</span>().<span style="color: #008000">getExternalContext</span>().<span style="color: #008000">getRequest</span>();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s=request.<span style="color: #008000">getParameter</span>("webnam");</span><br />
<br />
</span><span style="color: #008000">七.页面设计</span>.(实现<span style="color: #008000">VIEW</span>层设计)&nbsp;<br />
<br />
index.faces：(共二行)<br />
<span style="color: #008000"><span style="color: #99cc00">&lt;%@ page language="java" pageEncoding="UTF-8"%&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//解决EXTJS&nbsp;接收数据中有中文出现"?????"等乱码<br />
&nbsp;${searchAll.searchData}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//解决JS接收数据.Ext.store({url：index.faces，...})</span></span><br />
<br />
&nbsp;&nbsp;&nbsp; 页面中访问Bean的二种方法<br />
<span style="color: #99cc00">&nbsp;&nbsp;&nbsp; <span style="color: #3366ff">方法一：直接在.faces页面中使用${<span style="color: #00ccff">userBean</span>.property} <strong>(推荐)&nbsp;</strong></span><strong>&nbsp;//property:get/set&nbsp;methord</strong></span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注,不能使用${<span style="color: #00ccff">userBean</span>.method}<br />
<span style="color: #339966"><br />
</span>&nbsp;&nbsp;&nbsp; &lt;f:view&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //JSF标签必须放在里面<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 名稱1: ${userBean.searchData}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //正确<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #339966">&nbsp; <span style="color: #008080">//#{userBean.searchData}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //报错</span><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 名稱2: &lt;h:inputText value="#{userBean.searchData}"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //正确<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080">//&lt;h:inputText value="${userBean.searchData}"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //报错<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&lt;input value="#{userBean.searchData}"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //报错<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000">名稱3:</span>&nbsp;<span style="color: #000000">&lt;input value="${userBean.searchData}"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //正确,而且仍然可以使用JSF的ManagedBean</span><br />
</span>&nbsp;&nbsp;&nbsp; &lt;/f:view&gt;<br />
JSF表达式<span style="color: #339966">#{...}</span>只能用在JSF标签里，JSP表达式<span style="color: #339966">${...}</span>也只能用JSP页面里.<br />
JSP EL的语法格式:${...} 不能放在&lt;%...%&gt;中.&nbsp;<span style="color: #008000"><span style="color: #99cc00"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3366ff">方法二： 在.JSP页面中,直接获取业务层定义的BEAN<br />
</span></span></span>&lt;%@ page import="javax.servlet.ServletContext" %&gt;<br />
&lt;%@ page import="org.springframework.context.ApplicationContext" %&gt;<br />
&lt;%@ page import="org.springframework.web.context.support.WebApplicationContextUtils" %&gt;<br />
<br />
&lt;% <br />
<span style="color: #339966">//获取ApplicationContext对象</span><br />
ServletContext&nbsp;&nbsp; servletContext&nbsp;&nbsp; =&nbsp;&nbsp; request.getSession().getServletContext();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
ApplicationContext&nbsp;&nbsp; ac&nbsp;&nbsp; =&nbsp;&nbsp; WebApplicationContextUtils.getWebApplicationContext(servletContext); </p>
<p><span style="color: #339966">//获取ApplicationContext.xml文件中定义的BEAN</span><br />
userServiceps=(userService)ac.getBean("userService");<br />
<br />
<span style="color: #339966">八.导出war</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File-&gt;Export-&gt;J2EE-&gt;WAR file</p>
<img src ="http://www.blogjava.net/algz/aggbug/190077.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-04-01 14:48 <a href="http://www.blogjava.net/algz/articles/190077.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>映射对象标识符 </title><link>http://www.blogjava.net/algz/articles/187212.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Wed, 19 Mar 2008 04:11:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/187212.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/187212.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/187212.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/187212.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/187212.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1)increment 代理主键,hibernate自动以递增的方式来生成标识符,每次增加1.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2)identity 代理主键,由底层数据库生成标识符,前提就是底层的数据库支持自动增长的类型.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3)sequence 代理主键,hibernate根据底层数据库生成的标识符,前提是底层数据库支持序列<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4)hilo 代理主键,hibernate根据higg/low算法来生成的标识符,把特定表的字段作为high的值,默认选用hibernate_unique_key表的next_hi字段<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5)native 代理主键,根据底层数据库对自动生成标识符的支持能力,还选择identity,sequence,或hilo.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6)uuid.hex 代理主键,hibernate采用128位的UUID算法生成标识符,UUID算法能够在网络环境下生成唯一字符串标识符.不过字符串要比数据占用的空间多的多.所以不流行使用.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7)assigned 适用于自然主键,由JAVA应用程序负责生成标识符,为了能让JAVA设置OID.不能吧setId方法设置为非公共类型了,这种方式也尽量避免使用.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这里个人觉得第一种方式,也就是说由Hibernate来生成对象标识符的方式比较好.但是这种方式的缺点是只能一个Hibernate对应一个数据库的表.当同时创建了SeesionFactory实例的时候.两个或者更多的Hibernate对应同一个数据库的时候就会插入出错.这个时候我们可以选择第二种方式把标识符的生成工作交给底层数据库.还有一个小知识点要注意就是OID必须定义为long,int,short类型,如果定义为byte会报异常,这里推荐用long.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;总结一下,这7中生成OID标识符的方法,increment 比较常用,把标识符生成的权力交给Hibernate处理.但是当同时多个Hibernate应用操作同一个数据库,甚至同一张表的时候.就推荐使用identity 依赖底层数据库实现,但是数据库必须支持自动增长,sequence 以来底层数据库实现,但是数据库必须支持系列.hilo 根据特定的表实现.这三种方式了.当然针对不同的数据库选择不同的方法.如果你不能确定你使用的数据库具体支持什么的情况下.可以选择第三种.或者用native 让Hibernate来帮选择identity,sequence,或hilo.后边的自然主键不推荐使用,因为自然主键就是具有业务含义的主键,在现在的软件开发结构中,已经很少有人用了.下面总结一下几种常用数据库,可以使用的标识符类型.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MySQL:identity数据库底层实现,需要支持自动增长,increment由Hibernate实现,hilo用特定的表实现,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSSQL:identity数据库底层实现,需要支持自动增长,increment由Hibernate实现,hilo用特定的表实现,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Oracle:sequence数据库底层实现,需要支持序列,increment由Hibernate实现,hilo用特定的表实现,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;以上不难发现,所有的数据库都支持Hibernate用increment实现OID的生成,MYSQL和MSSQL数据库底层实现支持自动增长,而Oracle支持序列,还有用特殊表的实现方式这三个数据库都支持.还有一种实现方式适用于所有的数据库,就是native,由Hibernate去选择使用什么样的方式来生成IOD对象标识符,这种方式也是跨平台的. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --------------摘自:http://www.blogjava.net/action/archive/2007/05/22/119134.html
 <img src ="http://www.blogjava.net/algz/aggbug/187212.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-03-19 12:11 <a href="http://www.blogjava.net/algz/articles/187212.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate 瞬态( Transient )对象,持久化( Persistence )对象,游离( Detached )对象</title><link>http://www.blogjava.net/algz/articles/186924.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Tue, 18 Mar 2008 02:08:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/186924.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/186924.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/186924.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/186924.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/186924.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 瞬态对象: 没有进行持久化操作的新对象.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User user=new&nbsp;User();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.name="name";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Transient 对象<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 持久化对象: 持久化操作过的 Transient 对象.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Persistence 对象与数据库记录相关联,持久化对象的属性变化,同时数据库中相关联的记录也变化.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.save(user);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //持久化操作,同时数据库中name="name";现在user为Persistence&nbsp;对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.name="name1";&nbsp;&nbsp;&nbsp;&nbsp; //user对象属性直接影响数据库中记录name="name1";<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 游离对象: 失去与数据库中记录相关联的 Persistence 对象(主键已存在),或有主键(ID)的瞬态.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;对象====&gt;瞬态对象==持久化操作 save() ( INSERT )==&gt;持久对象==数据库中记录失去关联( tx.commit() )==&gt;游离对象==对象.属性修改(UPDATE)==&gt;持久化对象<br />
<br />
<img height="503" alt="" src="http://www.blogjava.net/images/blogjava_net/algz/Hibernateobjectstate.png" width="457" border="0" /></p>
<img src ="http://www.blogjava.net/algz/aggbug/186924.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-03-18 10:08 <a href="http://www.blogjava.net/algz/articles/186924.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hiberante 中多对一,一对多,多对多映射文件的混淆不清楚讲解</title><link>http://www.blogjava.net/algz/articles/186709.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Mon, 17 Mar 2008 02:50:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/186709.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/186709.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/186709.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/186709.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/186709.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在多对一和一对多的映射中.如一个部门对应多个人员,既可以看成是多个人员对应一个部门.所以在一对多或多对一映射关系中,没有区别.<br />
以多对一映射文件说明:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 多的一方,如<span style="color: #339966;">人员持久化类</span>映射文件需加入多对一元素:&nbsp; &lt;many-to-one class="<span style="color: #99cc00;">部门类</span>" colum="<span style="color: #00ff00;">外键</span>" /&gt;&nbsp;&nbsp;&nbsp; //<span style="color: #33cccc;"><span style="color: #3366ff;">外键的定义方式,代替&lt;property /&gt;定义.</span></span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一的一方,如<span style="color: #99cc00;">部门持久化类</span>映射文件.由于为了<span style="color: #33cccc;">体现一一对应的原则</span>(个人理解),需把多的一方映射为一个集合(因为一的一方要把多的一方看成一个整体,所以集合当然就放在一的一方.) , 需加入:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set name="集合名"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //集合中name&nbsp;属性必须.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;key&gt;&nbsp;&nbsp; &lt;colum&nbsp;name="<span style="color: #00ff00;">外键</span>" not-null="true/&gt;&nbsp; &lt;/key&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//在集合中<span style="color: #3366ff;">指定多的一方的外键元素</span>(集合中<span style="color: #33cccc;">两个子元素</span>的一个),<span style="color: #3366ff;">不代替&lt;property /&gt;定义.</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;one-to-many class="<span style="color: #339966;">人员类</span>" /&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//一对多元素(集合中<span style="color: #33cccc;">两个子元素</span>的一个).<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/set&gt;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(有外键的那一方,即为多方)&nbsp;&nbsp; (持久化即序列化)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 多对多的映射讲解:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 多对多的映射文件中,由于JAVA类无法表示多对多的映射,所以把他们分解成两个多对一/一对多,在中间引入一个JAVA BEAN 对象进行关联.这个中间BEAN除了主键用&lt;id /&gt;定义,其他属性由于均为外键,所以采用外键定义方式---&lt;many-to-one /&gt;.<br />
<br />
<br />
以上讲解有问题.举的例子是一对多的.多对一比一对多简单些.<br />
<img src ="http://www.blogjava.net/algz/aggbug/186709.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2008-03-17 10:50 <a href="http://www.blogjava.net/algz/articles/186709.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring+Hibernate DAO 持久层开发, Spring 用 Hibernate 访问数据库的三种方法.推荐使用回调.</title><link>http://www.blogjava.net/algz/articles/162578.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Fri, 23 Nov 2007 03:30:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/162578.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/162578.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/162578.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/162578.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/162578.html</trackback:ping><description><![CDATA[DAO开发<br />
<br />
注:<br />
(1)以下两者都需在Spring XML配置文件中,注册Bean(实现类)来依赖注入SessionFactory. <br />
(2.1)Spring 中进行事务管理的通常方式是利用AOP（面向切片编程）的方式，为普通java类封装事务控制，它是通过动态代理实现的，由于接口是<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 延迟实例化的， spring在这段时间内通过拦截器，加载事务切片。原理就是这样，具体细节请参考jdk中有关动态代理的文档。本文主要讲解<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如何在spring中进行事务控制。<br />
(2.2)动态代理的一个重要特征是，它是针对接口的,所以我们的DAO要通过动态代理来让spring接管事务，就必须在DAO前面抽象出一个接口.&nbsp; 当然<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果没有这样的接口，那么spring会使用CGLIB来解决问题，但这不是spring推荐的方式.<br />
<br />
(一)直接使用Hibernate API <span style="color: #339966">(不推荐使用)</span><br />
public class DaoImp implate Dao{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private SessionFactory sessionFactory;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static String hql = "from User u where u.username=? ";<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setSessionFactory(SessionFactory sessionFactory){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.sessionFactory=sessionFactory;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public boolean isValidUser(String username) {&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List userList = sessionFactory.getCurrentSession().creatQuery(hql).setParameter(0,username).list(); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (userList.size() &gt; 0) { <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (HibernateException ex){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw converHibernaterAccessException(ex);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
} <br />
&nbsp; <br />
优点:与Spring框架完全分离<br />
缺点:(1)无法使用Spring框架封装所提供的额外功能.如,直接使用Hibernate API 需用try...catch()处理HibernateException异常.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)需在实现类中加入setSessionFactory(SessionFactory sessionFactory)属性,接收依赖注入的SessionFactory.<br />
<br />
(二)继承 Spring 的 HibernateDaoSupport 使用 HibernateTemplate <span style="color: #339966">(不推荐使用getSession())<br />
</span>public class DaoImp extend HibernateDaoSupport implates Dao{<br />
<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//private SessionFactory sessionFactory;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static String hql = "from User u where u.username=? ";<br />
<br />
<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //public void setSessionFactory(SessionFactory sessionFactory){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.sessionFactory=sessionFactory;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //}</span><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public boolean isValidUser(String username) {&nbsp;<br />
<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; try{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp; List userList = sessionFactory.getCurrentSession().creatQuery(hql).setParameter(0,username).list();&nbsp;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List userList = getHibernateTemplate().find(hql,username);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (userList.size() &gt; 0) { <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;&nbsp;<br />
<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;} catch (HibernateException ex){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw converHibernaterAccessException(ex);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;}&nbsp;&nbsp;</span>&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public boolean isValidUser(String username,String password) throw DataAccessException {&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #008000">Session session = getSession();</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//不推荐使用,用完后需手动关闭<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] userlist=new String[2];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userlist[0]=username;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; userlist[1]=password;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List userList = <span style="color: #008000">session</span>.find(hql,userlist);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #008000">//Hibernate语句;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.close();<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (userList.size() &gt; 0) { <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;} catch (HibernateException ex){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw converHibernaterAccessException(ex);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
}<br />
<br />
特点:对HibernateTemplate没有提供的功能,可以直接调用HibernateDaoSuppor对象的<span style="color: #339966">getSession()</span>方法(极其不推荐使用)得到Session对象实例用try{ Hibernate API }catch&nbsp;(HibernateException ex )操作.<br />
<br />
(三)对 HibernateTemplate 没有提供的功能, 还可以用HibernateCallback 回调的方法管理数据库. <span style="color: #339966">(极其推荐)</span><br />
<br />
<p>&nbsp;/**<br />
&nbsp; * 使用 hql 语句进行操作<br />
&nbsp; * @param hql&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HSQL 查询语句<br />
&nbsp; * @param offset&nbsp;&nbsp; 开始取数据的下标<br />
&nbsp; * @param length&nbsp;&nbsp;&nbsp;读取数据记录数<br />
&nbsp; * @return List&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;结果集<br />
&nbsp; */<br />
&nbsp;public List getListForPage ( <span style="color: #99cc00">final </span>String hql , <span style="color: #99cc00">final </span>int offset , <span style="color: #99cc00">final</span> int length ) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; List list = getHibernateTemplate().executeFind ( new <span style="color: #339966">HibernateCallback</span> ( ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Object doInHibernate ( Session session ) throws HibernateException, SQLException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query query = session.createQuery ( hql ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.setFirstResult ( offset ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.setMaxResults ( length ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List list = query.list ( ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return list ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }) ;<br />
&nbsp;&nbsp;&nbsp; return list ;<br />
&nbsp;}<br />
</p>
<p><br />
//---------------------------------------------------------------------------<br />
<br />
final String queryString = "from Fourm";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #99cc00">//必须定义final类型</span><br />
&nbsp;&nbsp;&nbsp;List l= getHibernateTemplate().executeFind(new HibernateCallback(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;public Object doInHibernate ( Session session ) throws HibernateException, SQLException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query query = session.createQuery ( queryString ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.setFirstResult ( 0 ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.setMaxResults ( 10 ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List list = query.list ( ) ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return list ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
//------------------------------------------------------------<br />
<br />
<br />
<br />
为什么不使用getSession(),而使用回调的详细说明:</p>
<p>紫蝶&#8719;飛揚↗<br />
听个SPRING+HIBERNATE开发的问题.<br />
SPRING想调用HIBERNATE的方法有两种,一种是使用getSession();一种是:HibernateCallback回调.<br />
他们有什么不同?<br />
海绵♂宝宝<br />
前者没有事务管控，Spring把Hibernate最原始的Session给你！但是它不被声明式事务管理的服务！<br />
紫蝶&#8719;飛揚↗<br />
...声明式事务不会对他进行事务管理?<br />
海绵♂宝宝<br />
后者也是把Session返给你，但是通过闭包回调的形式给你使用，Spring会在给你之前做一下手脚，例如：添加声明式事务管理中声明的事务属性！<br />
海绵♂宝宝<br />
因为你写的方法通过匿名函数闭包，然后由Spring去负责执行闭包体内的方法！<br />
海绵♂宝宝<br />
Java里的借口回调基本都是借用匿名内部类实现的闭包！<br />
海绵♂宝宝<br />
你看一下Spring的HibernateDaoSupport的源代码就知道运行过程了！<br />
海绵♂宝宝<br />
直接使用getSession()还不享有Spring提供的模板支持，也就是说你得手动关闭连接，否则会一直挂在那儿，直到超时连接池才会回收这个连接！<br />
海绵♂宝宝<br />
这样很容器连接池连接数量溢出！你懂了啊？<br />
紫蝶&#8719;飛揚↗<br />
嗯.<br />
紫蝶&#8719;飛揚↗<br />
new HibernateCallback(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;public Object doInHibernate ( Session session ) throws HibernateException, SQLException {<br />
必须这样的方式吗?<br />
海绵♂宝宝<br />
建议补习一下编程中的闭包、回调的知识，再看看Spring的那段代码就可以彻底理解了！<br />
海绵♂宝宝<br />
恩！<br />
紫蝶&#8719;飛揚↗<br />
哦.明白了.<br />
海绵♂宝宝<br />
如果你觉得getHibernateTemplate()提供的方法不足以满足你的要求！你就得这么使用！<br />
紫蝶&#8719;飛揚↗<br />
明白.不够用的情况下用回调.<br />
海绵♂宝宝<br />
闭包JavaScript支持的比较好，因为它是以函数为单元的，Java过于强调面向对象，所以只能用匿名内部类来有限的支持闭包！标准的回调都是方法回调，也就是闭包到方法中，而不是类中！所以Java中的闭包和其他的语言有一些区别的，例如访问外部变量必须是final的！<br />
海绵♂宝宝<br />
据说JDK1.7会加入对函数闭包调用的支持！<br />
紫蝶&#8719;飛揚↗<br />
...历害.<br />
紫蝶&#8719;飛揚↗<br />
偶只知道这样用,不知道为什么这样用.<br />
海绵♂宝宝<br />
那可不行啊！呵呵！我最一开始也不大明白，后来仔细研究了闭包、回调的知识就懂了！<br />
其实这种用法在Swing编程里天天都用啊！把一个匿名的监听器实现类注册到事件源，只不过那个时候没有注意到这是闭包和回调罢了！<br />
紫蝶&#8719;飛揚↗<br />
看来有时间得好好看看了...<br />
</p>
<img src ="http://www.blogjava.net/algz/aggbug/162578.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2007-11-23 11:30 <a href="http://www.blogjava.net/algz/articles/162578.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate核心API及其查询分析</title><link>http://www.blogjava.net/algz/articles/162112.html</link><dc:creator>紫蝶∏飛揚↗</dc:creator><author>紫蝶∏飛揚↗</author><pubDate>Wed, 21 Nov 2007 08:02:00 GMT</pubDate><guid>http://www.blogjava.net/algz/articles/162112.html</guid><wfw:comment>http://www.blogjava.net/algz/comments/162112.html</wfw:comment><comments>http://www.blogjava.net/algz/articles/162112.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/algz/comments/commentRss/162112.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/algz/services/trackbacks/162112.html</trackback:ping><description><![CDATA[<span style="color: #008080">(一)&nbsp; org.hibernate.cfg.Configuration类</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;读取配置文件并创建唯一的SessionFactory对象.(一般,程序初始化hibernate时创建.)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Configuration config=new Configuration().config();&nbsp;&nbsp;&nbsp;&nbsp; //自动查找CLASS指定路径下的hibernate.cfg.xml文件.<br />
<br />
<span style="color: #008080">(二)&nbsp; org.hibernate.SessionFactory接口</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 主要作用是创建Session对象.(N个数据库只有N个SessionFactory对象并通过N个Configuration实例根据不同的配置文件创建.因此对象是不可改变的,所以为接口.)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SessionFactory sessionFactory=config.buildSessionFactory();<br />
<br />
<span style="color: #008080">(三)&nbsp; org.hibernate.Session接口</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 持久化操作的核心API,java程序与hibernate进行交互时所使用的主要接口.他有生命周期,以事务开始和结束为边界.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;主要功能是读取,创建和删除映射的实体对象的实例.这一系列的操作会转化为对数据库表中数据的增加,修改,查询和删除操作.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Session session =sessionFactory.openSession();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (实体对象:与数据库中表进行映射的类.)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 操作实体方法:所有方法都是在事务提交结束时才真正执行相应操作.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void save(Object object)&nbsp;:用于瞬态对象实例的转持久化操作,相当于INSERT.<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void update(Object object):必须设置标识符(object.setId(....)),根据标识符更新数据.相当于UPDATE.<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void delete(Object object) :相当于DELETE.<br />
<br />
&nbsp;&nbsp;&nbsp;(1)创建查询对象:调用方法获得持久对象.(结果集,数据库中的数据.)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query createQuery(String queryString)&nbsp;&nbsp;&nbsp; //用的最多.可用HQL语句直接更新,删除数据.<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Criteria createCriteria(Class persistentClass)&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQLQuery createSQLQuery(String queryString)&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;(2)创建事务<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transaction beginTransaction() <br />
<br />
<span style="color: #008080">(四)&nbsp; org.hibernate.Transaction接口<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>用于事务管理.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void commit():提交事务.&nbsp;<br />
<br />
<span style="color: #008080">(五)&nbsp; org.hibernate.Query接口</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setXxx:设置HQL语句中的输入参数.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Query&nbsp; setMaxResults (int maxResults)&nbsp; :结果集的最大记录<span style="color: #33cccc">总数</span>.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ****************以下两属性,常用于分页处理*****************<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Query&nbsp;&nbsp;setFirstResult(int firstResult)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :从结果集的<span style="color: #33cccc">第几条</span>记录<span style="color: #33cccc">开始</span>.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Query&nbsp;&nbsp;setFetchSize(int fetchSize)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :从结果集中<span style="color: #33cccc">取(fetch)多少条</span>记当出来.<br />
-------------------------------------------------------------------------------------------------------<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List list():返回查询结果集为List类型.(<span style="color: #33cccc">读取全部数据映射</span>为内存的实体对象(即内存中的数据库).资源消耗大, 但可以<span style="color: #33cccc">按索引</span>位置随机查找数据.)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Iterator iterate():返回查询结果集为Iterator类型.(只能<span style="color: #33cccc">按照从前向后</span>的顺序查找数据.但节省资源,<span style="color: #33cccc">只对查找的数据映射</span>为实体对象.)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object uniqueResult():只返回查询结果集中,满足第一个条件的数据.<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ScrollableResults scroll():返回查询结果集为Iterator类型.&nbsp;
<img src ="http://www.blogjava.net/algz/aggbug/162112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/algz/" target="_blank">紫蝶∏飛揚↗</a> 2007-11-21 16:02 <a href="http://www.blogjava.net/algz/articles/162112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>