??xml version="1.0" encoding="utf-8" standalone="yes"?>
喜欢的话p多多支持Q有好的资料Q大家不要忘记告诉我?BR>谢谢
15.1. 大小写敏感性问?/STRONG>
除了JavacM属性的名称外,查询语句对大写q不敏感?nbsp;所?nbsp;SeLeCT ?nbsp;sELEct 以及 SELECT 是相同的Q但?nbsp;org.hibernate.eg.FOO q不{h?nbsp;org.hibernate.eg.Foo q且 foo.barSet 也不{h?nbsp;foo.BARSET?nbsp;
本手册中的HQL关键字将使用写字母. 很多用户发现使用完全大写的关键字会查询语句 的可L更? 但我们发玎ͼ当把查询语句嵌入到Java语句中的时候用大写关键字比较隄?nbsp;
15.2. from子句
Hibernate中最单的查询语句的Ş式如下:
代码内容 from eg.Cat |
代码内容 from Cat |
代码内容 from Cat as cat |
代码内容 from Cat cat |
15.3. 兌(Association)与连?Join)
我们也可以ؓ相关联的实体甚至是对一个集合中的全部元素指定一个别? q时要用关键字join?nbsp;
代码内容 from Cat as cat inner join cat.mate as mate left outer join cat.kittens as kitten from Cat as cat left join cat.mate.kittens as kittens from Formula form full join form.parameter param |
代码内容 from Cat as cat join cat.mate as mate left join cat.kittens as kitten |
代码内容 from Cat as cat inner join fetch cat.mate left join fetch cat.kittens |
代码内容 from Document fetch all properties order by name from Document doc fetch all properties where lower(doc.name) like ?cats%?/FONT> |
代码内容 select distinct cat.name from Cat cat select count(distinct cat.name), count(cat) from Cat cat |
代码内容 from Cat as cat |
代码内容 from java.lang.Object o |
代码内容 from Named n, Named m where n.name = m.name |
代码内容 from Cat where name=’Fritz?nbsp; |
代码内容 from Cat as cat where cat.name=’Fritz?nbsp; |
代码内容 select foo from Foo foo, Bar bar where foo.startDate = bar.date |
代码内容 from Foo foo where foo.bar.baz.customer.address.city is not null |
代码内容 from Cat cat, Cat rival where cat.mate = rival.mate select cat, mate from Cat cat, Cat mate where cat.mate = mate |
代码内容 from Cat as cat where cat.id = 123 from Cat as cat where cat.mate.id = 69 |
代码内容 from bank.Person person where person.id.country = ’AU?nbsp; and person.id.medicareNumber = 123456 from bank.Account account where account.owner.id.country = ’AU?nbsp; and account.owner.id.medicareNumber = 123456 |
代码内容 from Cat cat where cat.class = DomesticCat |
代码内容 store.owner.address.city // 正确 store.owner.address // 错误! |
代码内容 from AuditLog log, Payment payment where log.item.class = ’Payment?nbsp;and log.item.id = payment.id |
代码内容 from DomesticCat cat where cat.name between ’A?nbsp;and ’B?nbsp; from DomesticCat cat where cat.name in ( ’Foo? ’Bar? ’Baz?nbsp;) |
代码内容 from DomesticCat cat where cat.name not between ’A?nbsp;and ’B?nbsp; from DomesticCat cat where cat.name not in ( ’Foo? ’Bar? ’Baz?nbsp;) |
代码内容 <property name="hibernate.query.substitutions">true 1, false 0</property> |
代码内容 from Cat cat where cat.alive = true |
代码内容 from Cat cat where cat.kittens.size > 0 from Cat cat where size(cat.kittens) > 0 |
代码内容 from Calendar cal where maxelement(cal.holidays) > current date from Order order where maxindex(order.items) > 100 from Order order where minelement(order.items) > 10000 |
代码内容 select mother from Cat as mother, Cat as kit where kit in elements(foo.kittens) select p from NameList list, Person p where p.name = some elements(list.names) from Cat cat where exists elements(cat.kittens) from Player p where 3 > all elements(p.scores) from Show show where ’fizard?nbsp;in indices(show.acts) |
代码内容 from Order order where order.items[0].id = 1234 select person from Person person, Calendar calendar where calendar.holidays[’national day’] = person.birthDay and person.nationality.calendar = calendar select item from Item item, Order order where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11 select item from Item item, Order order where order.items[ maxindex(order.items) ] = item and order.id = 11 在[]中的表达式甚臛_以是一个算数表辑ּ?nbsp; select item from Item item, Order order where order.items[ size(order.items) - 1 ] = item |
代码内容 select item, index(item) from Order order join order.items item where index(item) < 5 |
代码内容 select cust from Product prod, Store store inner join store.customers cust where prod.name = ’widget?nbsp; and store.location.name in ( ’Melbourne? ’Sydney?nbsp;) and prod = all elements(cust.currentOrder.lineItems) 提示: 会像如下的语?nbsp; SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order FROM customers cust, stores store, locations loc, store_customers sc, product prod WHERE prod.name = ’widget?nbsp; AND store.loc_id = loc.id AND loc.name IN ( ’Melbourne? ’Sydney?nbsp;) AND sc.store_id = store.id AND sc.cust_id = cust.id AND prod.id = ALL( SELECT item.prod_id FROM line_items item, orders o WHERE item.order_id = o.id AND cust.current_order = o.id ) |
代码内容 from DomesticCat cat order by cat.name asc, cat.weight desc, cat.birthdate |
代码内容 select cat.color, sum(cat.weight), count(cat) from Cat cat group by cat.color select foo.id, avg(name), max(name) from Foo foo join foo.names name group by foo.id having子句在这里也允许使用. select cat.color, sum(cat.weight), count(cat) from Cat cat group by cat.color having cat.color in (eg.Color.TABBY, eg.Color.BLACK) |
代码内容 select cat from Cat cat join cat.kittens kitten group by cat having avg(kitten.weight) > 100 order by count(kitten) asc, sum(kitten.weight) desc |
代码内容 from Cat as fatcat where fatcat.weight > ( select avg(cat.weight) from DomesticCat cat ) from DomesticCat as cat where cat.name = some ( select name.nickName from Name as name ) from Cat as cat where not exists ( from Cat as mate where mate.mate = cat ) from DomesticCat as cat where cat.name not in ( select name.nickName from Name as name ) |
代码内容 from Cat as cat where not ( cat.name, cat.color ) in ( select cat.name, cat.color from DomesticCat cat ) |
代码内容 from Person where name = (’Gavin? ’A? ’King? |
代码内容 from Person where name.first = ’Gavin?nbsp;and name.initial = ’A?nbsp;and name.last = ’King? |
代码内容 select order.id, sum(price.amount), count(item) from Order as order join order.lineItems as item join item.product as product, Catalog as catalog join catalog.prices as price where order.paid = false and order.customer = :customer and price.product = product and catalog.effectiveDate < sysdate and catalog.effectiveDate >= all ( select cat.effectiveDate from Catalog as cat where cat.effectiveDate < sysdate ) group by order having sum(price.amount) > :minAmount order by sum(price.amount) desc |
代码内容 select order.id, sum(price.amount), count(item) from Order as order join order.lineItems as item join item.product as product, Catalog as catalog join catalog.prices as price where order.paid = false and order.customer = :customer and price.product = product and catalog = :currentCatalog group by order having sum(price.amount) > :minAmount order by sum(price.amount) desc |
代码内容 select count(payment), status.name from Payment as payment join payment.currentStatus as status join payment.statusChanges as statusChange where payment.status.name <> PaymentStatus.AWAITING_APPROVAL or ( statusChange.timeStamp = ( select max(change.timeStamp) from PaymentStatusChange change where change.payment = payment ) and statusChange.user <> :currentUser ) group by status.name, status.sortOrder order by status.sortOrder |
代码内容 select count(payment), status.name from Payment as payment join payment.currentStatus as status where payment.status.name <> PaymentStatus.AWAITING_APPROVAL or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :currentUser group by status.name, status.sortOrder order by status.sortOrder |
代码内容 select account, payment from Account as account left outer join account.payments as payment where :currentUser in elements(account.holder.users) and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID) order by account.type.sortOrder, account.accountNumber, payment.dueDate |
代码内容 select account, payment from Account as account join account.holder.users as user left outer join account.payments as payment where :currentUser = user and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID) order by account.type.sortOrder, account.accountNumber, payment.dueDate |
代码内容 select usr.id, usr.name from User as usr left join usr.messages as msg group by usr.id, usr.name order by count(msg) |
代码内容 from User usr where size(usr.messages) >= 1 |
代码内容 select usr.id, usr.name from User usr.name join usr.messages msg group by usr.id, usr.name having count(msg) >= 1 |
代码内容 select usr.id, usr.name from User as usr left join usr.messages as msg group by usr.id, usr.name having count(msg) = 0 |
代码内容 Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size"); q.setProperties(fooBean); // fooBean包含ҎgetName()与getSize() List foos = q.list(); |
代码内容 Query q = s.createFilter( collection, "" ); // 一个简单的qo?nbsp; q.setMaxResults(PAGE_SIZE); q.setFirstResult(PAGE_SIZE * pageNumber); List page = q.list(); |
代码内容 Collection orderedCollection = s.filter( collection, "order by this.amount" ); Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" ); |
代码内容 ( (Integer) session.iterate("select count(*) from ....").next() ).intValue(); |
单的Log4j使用只需要导入下面的包就可以?BR>// import log4j packages
import org.apache.log4j.Logger;
然后你需要在cȝ开头写上下面一?BR>private final static Logger log =
Logger.getLogger(ClassName.class);//注意q里写的是当前类的类名?BR>q样你就有了一个日志对象叫?logQ这个log有以下集中用?BR>log.info();//一般信?BR>log.debug();//调试信息
log.error();//错误信息
log.warn();//警告信息
log.fatal();//致命错误信息
上面列出的就是所谓log4j的输出别,log4j只?个别,它们从上C分别?BR>ERROR、WARN、INFO、DEBUGQ假设你定义的别是infoQ那么error和warn的日志可以显C比他低的debug信息׃昄了?BR>知道了上面的内容q不够,要想很好的用log4j你还需要配|log4j的环境。因为每个log都可以通过配置它的属性文件来辑ֈ控制日志输出的格式的目的Q下面我l出一个在weblogic下用log4j的配|过E,首先l出q个配置文g的完整信息?BR>
#log4j.rootLogger=INFO,A1,R //q一句指定了日志输出的别ؓinfo,A1和R分别代表日志输出C么地斏V?BR>log4j.category.hybl_wshabcm=debug,A1,R //q一句指定了日志具体输出哪个包的信息Q以及输Z|?BR>log4j.appender.A1=org.apache.log4j.ConsoleAppender //q里指定了日志输出的W一个位|A1是控制台ConsoleAppender
/*
*其中QLog4j提供的appender有以下几U:
*org.apache.log4j.ConsoleAppenderQ控制台Q,
*org.apache.log4j.FileAppenderQ文ӞQ?BR>*org.apache.log4j.DailyRollingFileAppenderQ每天生一个日志文ӞQ?BR>*org.apache.log4j.RollingFileAppenderQ文件大到达指定尺寸的时候生一个新的文ӞQ?BR>*org.apache.log4j.WriterAppenderQ将日志信息以流格式发送到L指定的地方)
*
*/
log4j.appender.A1.layout=org.apache.log4j.PatternLayout //指定A1的布局模式
/*
*其中QLog4j提供的layout有以下几U:
×org.apache.log4j.HTMLLayoutQ以HTML表格形式布局Q,
*org.apache.log4j.PatternLayoutQ可以灵zd指定布局模式Q,
*org.apache.log4j.SimpleLayoutQ包含日志信息的U别和信息字W串Q,
*org.apache.log4j.TTCCLayoutQ包含日志生的旉、线E、类别等{信息)
*/
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n //指定日志的输出格?/P>
log4j.appender.R=org.apache.log4j.RollingFileAppender //指定以文件的方式输出日志
log4j.appender.R.File=c:/sys.html //文g位置
log4j.appender.R.MaxFileSize=500KB //文g最大尺?BR>log4j.appender.R.MaxBackupIndex=1 //备䆾?BR>log4j.appender.R.layout=org.apache.log4j.HTMLLayout //文g的格式ؓHtml格式
#log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n
有了上面的这个文件我们还要在weblogic启动的时候通过一个类加蝲q个文gQ可以用下面的方式
1、加载配|文件的Servlet
package hybl_wshabcm.servelet;
import java.io.File;
import java.io.LineNumberReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Vector;
import java.sql.Driver;
import java.sql.DriverManager;
// import servlet packages
import javax.servlet.http.HttpServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
// import log4j packages
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class SetupServlet extends HttpServlet{
public void init(ServletConfig config) throws ServletException{
super.init(config);
// first thing to do, is to set up the Driver that we might be using
// in case of JDBCAppender
try{
Driver d =
(Driver)(Class.forName(
"org.gjt.mm.mysql.Driver").newInstance());
DriverManager.registerDriver(d);
//加蝲JDBC驱动E序Q当准备日志记录到数据库的时候可以?BR>}catch(Exception e){ System.err.println(e); }
// next load up the properties
//启动时从web.xml中获得配|文件的信息
String props = config.getInitParameter("props");
if(props == null || props.length() == 0 ||
!(new File(props)).isFile()){
System.err.println(
"ERROR: Cannot read the configuration file. " +
"Please check the path of the config init param in web.xml");
throw new ServletException();
}
}
public void destroy(){
super.destroy();
}
}
2、web.xml文g的部|?BR>上面的这个Servlet在服务器启动的时候将一些初始化信息加蝲Q那么如何在weblogic启动的时候将q个cM
加蝲呢?看一个例?BR>
好了Q现在你可以象开头那样用log4j来记录日志了
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="myeclipse.connection.profile">thin</property>
<!-- JDBC驱动E序 -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<!-- JDBC URL -->
<property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:test</property>
<!-- 数据库用户名 -->
<property name="connection.username">test</property>
<!-- 数据库密?-->
<property name="connection.password">test</property>
<!-- sql的方aQ不同db的sql略有不同 -->
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<!-- 后台昄sql语句Q主要是调试?->
<property name="show_sql">ture</property>
</session-factory>
</hibernate-configuration>
?struts+ hibernate q种l构中,是不应该把Hibernate产生的PO直接传递给JSP的,不管他是IteratorQ还是ListQ这是一个设计错误?
我来谈谈在J2EE架构中各层的数据表示ҎQ?
Web层的数据表示是FormBeanQ数据来源于HTML Form POST
业务层的数据表示是VO
持久层的数据表示是POQ其数据来源于数据库Q持久层的数据表CZ如CMP
在一个规范的J2EE架构中,不同层的数据表示应该被限制在层内Q而不应该扩散到其它层Q这样可以降低层间的耦合性,提高J2EE架构整体的可l护性和可扩展性。比如说Web层的逻辑q行了修改,那么只需要修改FormBean的结构,而不需要触动业务层和持久层的代码修攏V同hQ当数据库表q行了小的调_那么也只需要修Ҏ久层数据表示Q而不需要触动业务层代码和Web层代码?
不过׃Hibernate的强大功能,例如动态生成POQPO的状态管理可以脱SessionQ得在应用了Hibernate的J2EE框架中,PO完全可以充当VOQ因此我们下面把PO和VO合ƈQ统UCؓPO?
先来谈谈ActionFormBean和持久层的PO之间的重大区别?
在简单的应用中,ActionFormBean和PO几乎是没有区别,所以很多hq脆是用ActionFormBean来充当POQ于是ActionFormBean从JSP面到Servlet控制层再C务层Q然后穿q持久层Q最后一直映到数据库表。真是一竿子捅到了底Q?
但是在复杂的应用中,ActionFormBean和PO是分ȝQ他们也不可能一栗ActionFormBean是和|页里面的Form表单一一对应的,Form里面有什么元素,Bean里面有什么属性。而PO和数据库表对应,因此如果数据库表不修改,那么PO也不会修改,如果面的流E和数据库表字段对应关系不一_那么你又如何能够使用ActionFormBean来取代PO呢?
比如说吧Q用h册页面要求注册用L基本信息Q因此HTML Form里面包含了基本信息属性,于是你需要一个ActionFormBean来一一对应(注意Q是一一对应)Q每个Bean属性对应一个文本框或者选择框什么的?
而用戯个持久对象呢Q他的属性和ActionFormBean有什么明显不同呢Q他会有一些ActionFormBean所没有的集合属性,比如说用L权限属性,用户的组属性,用户的帖子等{。另外还有可能的是在ActionFormBean里面?个属性,分别是用LFirst Name, Middle Name, Last NameQ而在我的Userq个持久对象中就是一?Name 对象属性?
假设我的注册面原来只要你提供First NameQ那么ActionFormBeanp一个属性,后来我要你提供全名,你要改ActionFormBeanQ加两个属性。但是这个时候PO是不应该修改_因ؓ数据库没有改?
那么在一个完整的J2EEpȝ中应该如何进行合理的设计呢?
JSP(View) ---> ActionFormBean(Module) ---> Action(Control)
ActionFormBean是Web层的数据表示Q它和HTML面Form对应Q只要Web面的操作流E发生改变,它就要相应的q行修改Q它不应该也不能被传递到业务层和持久层,否则一旦页面修改,会一直牵q到业务层和持久层的大面U的代码q行修改Q对于Y件的可维护性和可扩展性而言Q是一个灾难,Actiont是他的边界Q到此ؓ止!
Action(Web Control) ---> Business Bean ---> DAO ---> ORM --->DB
而PO则是业务层和持久层的数据表示Q它在业务层和持久层之间q行动Q他不应该也不能被传递到Web层的View中去Q而ActionServlet是他的边界Q到此ؓ止!
然后来看一看整个架构的程Q?
当用户通过览器访问网,提交了一个页面。于是Action拿到了这个FormBeanQ他会把FormBean属性读出来Q然后构造一个PO对象Q再调用业务层的Beanc,完成了注册操作,重定向到成功面。而业务层Bean收到q个PO对象之后Q调用DAO接口ҎQ进行持久对象的持久化操作?
当用h询某个会员的信息的时候,他用全名q行查询Q于是Action得到一个UserNameFormBean包括?个属性,分别是first name, middle name, last nameQ然后Action把UserNameFormBean?个属性读出来Q构造Name对象Q再调用业务BeanQ把Name对象传递给业务BeanQ进行查询?
业务Bean取得Name(注意: Name对象只是User的一个属?对象之后调用DAO接口Q返回一个User的PO对象Q注意这个User不同于在Web层用的UserFormBeanQ他有很多集合属性滴。然后业务Bean把User对象q回lAction?
Action拿到User之后Q把User的基本属性取?集合属性如果不需要就免了)Q构造UserFormBeanQ然后把UserFormBean request.setAttribute(...)Q然后重定向到查询结果页面?
查询面拿到request对象里面的ActionFormBeanQ自动调用tag昄之?
ȝQ?
FormBean是Web层的数据表示Q他不能被传递到业务层;PO是持久层的数据表C,在特定情况下Q例如Hibernate中,他可以取代VO出现在业务层Q但是不POq是VO都必限制在业务层内使用Q最多到达Web层的ControlQ绝不能被扩散到View厅R?
FormBean和PO之间的数据{化是在Action中进行滴?
BTW:
JDO1.xq不能像Hibernate功能q样强大QPO不能q持久层,所以必d业务层用VOQ因此必d业务层进行大量的VO和PO的{化操作,相对于Hibernate来说Q编E比较烦琐?
当然咯,理论是一回事Q实际操作也不一定非要这样干Q你可以自行取舍Q在实际目中灵zM点,增加一点bad smellQ提高开发效率。只不过在大型项目中最好还是严丝合~,不然的话Q改版的时候会痛苦的很滴?/P>