锘??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久青草青青国产亚洲免观,亚洲成人福利在线观看,亚洲精品无码国产片http://www.tkk7.com/RR00/category/2561.html涓嶈鍩嬪ご鑻﹀共錛岃瀛︿範錛屽涔狅紝鍐嶅涔犮傘傘傘傘? <br> powered by <font color='orange'>R.Zeus</font>zh-cnTue, 27 Feb 2007 22:35:02 GMTTue, 27 Feb 2007 22:35:02 GMT60timestamp and date in hibernatehttp://www.tkk7.com/RR00/articles/83984.htmlR.ZeusR.ZeusTue, 28 Nov 2006 02:32:00 GMThttp://www.tkk7.com/RR00/articles/83984.htmlhttp://www.tkk7.com/RR00/comments/83984.htmlhttp://www.tkk7.com/RR00/articles/83984.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/83984.htmlhttp://www.tkk7.com/RR00/services/trackbacks/83984.html聽* timestamp support the hh:mm:ss and date will ignore that or make missstake.see the
聽* hibernate reference.
so save the same java.util.date,but different in the database.

R.Zeus 2006-11-28 10:32 鍙戣〃璇勮
]]>
simple Database Connection Pool in hibernate http://www.tkk7.com/RR00/articles/79816.htmlR.ZeusR.ZeusWed, 08 Nov 2006 04:23:00 GMThttp://www.tkk7.com/RR00/articles/79816.htmlhttp://www.tkk7.com/RR00/comments/79816.htmlhttp://www.tkk7.com/RR00/articles/79816.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/79816.htmlhttp://www.tkk7.com/RR00/services/trackbacks/79816.html

聽public void closeConnection(Connection conn) throws SQLException {

聽聽if ( log.isDebugEnabled() ) checkedOut--;

//synchronized聽pool to avoid concurrence error.聽聽
synchronized (pool) {
聽聽聽int currentSize = pool.size();
聽聽聽if ( currentSize < poolSize ) {
聽聽聽聽if ( log.isTraceEnabled() ) log.trace("returning connection to pool, pool size: " + (currentSize + 1) );

//add to pool
聽聽
聽聽聽聽pool.add(conn);
聽聽聽聽return;
聽聽聽}
聽聽}

聽聽log.debug("closing JDBC connection");

聽聽conn.close();

聽}


聽public Connection getConnection() throws SQLException {

聽聽if ( log.isTraceEnabled() ) log.trace( "total checked-out connections: " + checkedOut );

//synchronized聽pool to avoid concurrence error 聽聽
聽synchronized (pool) {
聽聽聽if ( !pool.isEmpty() ) {

//if the pool is not empty,return connection from the pool聽聽

聽聽聽聽
聽聽聽聽int last = pool.size() - 1;
聽聽聽聽if ( log.isTraceEnabled() ) {
聽聽聽聽聽log.trace("using pooled JDBC connection, pool size: " + last);
聽聽聽聽聽checkedOut++;
聽聽聽聽}
聽聽聽聽Connection pooled = (Connection) pool.remove(last);
聽聽聽聽if (isolation!=null) pooled.setTransactionIsolation( isolation.intValue() );
聽聽聽聽if ( pooled.getAutoCommit()!=autocommit ) pooled.setAutoCommit(autocommit);
聽聽聽聽return pooled;
聽聽聽}
聽聽}

聽聽log.debug("opening new JDBC connection");
//create new connection.
聽聽Connection conn = DriverManager.getConnection(url, connectionProps);
聽聽if (isolation!=null) conn.setTransactionIsolation( isolation.intValue() );
聽聽if ( conn.getAutoCommit()!=autocommit ) conn.setAutoCommit(autocommit);

聽聽if ( log.isDebugEnabled() ) {
聽聽聽log.debug( "created connection to: " + url + ", Isolation Level: " + conn.getTransactionIsolation() );
聽聽}
聽聽if ( log.isTraceEnabled() ) checkedOut++;

聽聽return conn;
聽}


so you can see that when the connection will close,it actually not close and add to the pool if the pool size is not full.

in other way , we can聽firstly create a number of connection in the pool and when the pool is used out then create new connection to the call.

I will see the C3P0ConnectionProvider next.

A connection provider that uses java.sql.DriverManager. This provider
聽also implements a very rudimentary connection pool.

Note that you have to copy the required library into your classpath and use different connection pooling settings if you want to use a production-quality third party JDBC pooling software.




R.Zeus 2006-11-08 12:23 鍙戣〃璇勮
]]>
Hibernate support PlaceHolder '${}'http://www.tkk7.com/RR00/articles/79652.htmlR.ZeusR.ZeusTue, 07 Nov 2006 09:25:00 GMThttp://www.tkk7.com/RR00/articles/79652.htmlhttp://www.tkk7.com/RR00/comments/79652.htmlhttp://www.tkk7.com/RR00/articles/79652.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/79652.htmlhttp://www.tkk7.com/RR00/services/trackbacks/79652.html
public static String resolvePlaceHolder(String property) {
聽聽if ( property.indexOf( PLACEHOLDER_START ) < 0 ) {
聽聽聽return property;
聽聽}
聽聽StringBuffer buff = new StringBuffer();
聽聽char[] chars = property.toCharArray();
聽聽for ( int pos = 0; pos < chars.length; pos++ ) {
聽聽聽if ( chars[pos] == '$' ) {
聽聽聽聽// peek ahead
聽聽聽聽if ( chars[pos+1] == '{' ) {
聽聽聽聽聽// we have a placeholder, spin forward till we find the end
聽聽聽聽聽String systemPropertyName = "";
聽聽聽聽聽int x = pos + 2;
聽聽聽聽聽for (聽 ; x < chars.length && chars[x] != '}'; x++ ) {
聽聽聽聽聽聽systemPropertyName += chars[x];
聽聽聽聽聽聽// if we reach the end of the string w/o finding the
聽聽聽聽聽聽// matching end, that is an exception
聽聽聽聽聽聽if ( x == chars.length - 1 ) {
聽聽聽聽聽聽聽throw new IllegalArgumentException( "unmatched placeholder start [" + property + "]" );
聽聽聽聽聽聽}
聽聽聽聽聽}
聽聽聽聽聽String systemProperty = extractFromSystem( systemPropertyName );
聽聽聽聽聽buff.append( systemProperty == null ? "" : systemProperty );
聽聽聽聽聽pos = x + 1;
聽聽聽聽聽// make sure spinning forward did not put us past the end of the buffer...
聽聽聽聽聽if ( pos >= chars.length ) {
聽聽聽聽聽聽break;
聽聽聽聽聽}
聽聽聽聽}
聽聽聽}
聽聽聽buff.append( chars[pos] );
聽聽}
聽聽String rtn = buff.toString();
聽聽return StringHelper.isEmpty( rtn ) ? null : rtn;

extractFromSystem( systemPropertyName )

private static String extractFromSystem(String systemPropertyName) {
聽聽try {
聽聽聽return System.getProperty( systemPropertyName );
聽聽}
聽聽catch( Throwable t ) {
聽聽聽return null;
聽聽}
聽}


this properties can use in hibernate.cfg.xml

R.Zeus 2006-11-07 17:25 鍙戣〃璇勮
]]>
An JoinedIterator is an Iterator that wraps a number of Iterators.http://www.tkk7.com/RR00/articles/79643.htmlR.ZeusR.ZeusTue, 07 Nov 2006 09:00:00 GMThttp://www.tkk7.com/RR00/articles/79643.htmlhttp://www.tkk7.com/RR00/comments/79643.htmlhttp://www.tkk7.com/RR00/articles/79643.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/79643.htmlhttp://www.tkk7.com/RR00/services/trackbacks/79643.html
聽*This class makes multiple iterators look like one to the caller.
聽* When any method from the Iterator interface is called, the JoinedIterator
聽* will delegate to a single underlying Iterator. The JoinedIterator will
聽* invoke the Iterators in sequence until all Iterators are exhausted.

R.Zeus 2006-11-07 17:00 鍙戣〃璇勮
]]>
Performance: Hibernate startup timehttp://www.tkk7.com/RR00/articles/78093.htmlR.ZeusR.ZeusMon, 30 Oct 2006 09:22:00 GMThttp://www.tkk7.com/RR00/articles/78093.htmlhttp://www.tkk7.com/RR00/comments/78093.htmlhttp://www.tkk7.com/RR00/articles/78093.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/78093.htmlhttp://www.tkk7.com/RR00/services/trackbacks/78093.htmlFrom: Performance: Hibernate startup time

The following tips hints how to make Hibernate startup faster.

Only add the mapping files you need!

If you are running some few JUnit tests for a 400++ classes project you probably don't hit every class in those tests and thus do not need to add all those hbm.xml's to the Configuration. Go look at Hibernate's test suite on how you could let your TestCase decide what classes should be defined in the mapping.

Use serialized XML documents when configuring Configuration

When building the configuration 40-60% of the time is used by the XML parsers and Dom4j to read up the XML document. Significant performance increases can be done by serializing the Document object's to disc once, and afterwards just add them to the configuration by deserializing them first.

In the current cvs we have an experimental Configuration.addCachableFile() method that can be used as inspiration for previous Hibernate versions.

public Configuration addCachableFile(String xmlFile) throws MappingException {        
        try {
            File file = new File(xmlFile);
            File lazyfile = new File(xmlFile + ".bin");
            org.dom4j.Document doc = null; 
            List errors = new ArrayList();
            if(file.exists() && lazyfile.exists() && file.lastModified()<lazyfile.lastModified()) {
                log.info("Mapping lazy file: " + lazyfile.getPath());
                ObjectInputStream oip = null;
                oip = new ObjectInputStream(new FileInputStream(lazyfile));
                doc = (org.dom4j.Document) oip.readObject();
                oip.close(); 
            } else {
                doc = xmlHelper.createSAXReader(xmlFile, errors, entityResolver).read( file );
                log.info("Writing lazy file to " + lazyfile);
                ObjectOutputStream oup = new ObjectOutputStream(new FileOutputStream(lazyfile));
                oup.writeObject(doc);
                oup.flush();
                oup.close();
            }
            
            if ( errors.size()!=0 ) throw new MappingException( "invalid mapping", (Throwable) errors.get(0) );
            add(doc);
            return this;
        }
        catch (Exception e) {
            log.error("Could not configure datastore from file: " + xmlFile, e);
            throw new MappingException(e);
        }
    }

Disable Hibernates usage of cglib reflection optimizer

Put the following line in hibernate.properties:

hibernate.cglib.use_reflection_optimizer=false

It will make Hibernate start faster since it does not try to build cglib-enhanced objects to access getter/setters.

Note: It will have in impact on overall runtime performance since Hibernate will be forced to use standard JDK reflection for access. So it is most useful during development. (You will also get better error messages in some situations when the optimizer is disabled ;)


NEW聽COMMENT

Serializing the Configuration object
04 May 2004, 12:37
luish
Another approach would be to serialize the whole Configuration 
object. What do you think about this? I have submitted a patch to  
the Jira to make the Configuration Serializable (see bugs 492 and 
147).
addLazyFile() not there.
06 Jul 2004, 11:50
gstamp
I can't fine addLazyFile() in CVS.  Is it still supposed to be there?
Hibernate3 feature
31 Aug 2004, 11:13
gavin
Try the Hibernate3 module (or just the alpha release)
Information update?
30 Mar 2005, 07:54
gruberc
The information on this page does not seem to be correct any
more. With Hibernate 3.0rc1, there is no Configuration.addLazyFile()
any more, but addCacheableFile(). How should it be used?
lazy
06 Mar 2006, 05:09
steckemetz
If you have terrible problems with startup time and
do NOT need certain features like:

* proxy objects
* lazy loading

or if you are using the stateless session,
then you can disable lazyness on class level like:

<class name="myClass" table="myTable" lazy="false">

The default is true and forces byte code generation of
some proxy class which takes a lot of time.
Perhaps some hibernate guru can tell us, which other
features will be disabled by this.
I solve it.
02 Aug 2006, 00:12
cm4ever
The Hibernate Configuration module implement is very bad.
I write a module to realize the dynamic loading mapping files.
But other function I can't resolve...

Hibernate Dynamic Module
This project is only a module of Hibernate http://www.hibernate.org Read
mapping file until insert/update/delete/select the persistent class in
Hibernate.
http://sourceforge.net/projects/hbn-dyn-mod/


R.Zeus 2006-10-30 17:22 鍙戣〃璇勮
]]>
an easy example for Serializable from webhttp://www.tkk7.com/RR00/articles/78083.htmlR.ZeusR.ZeusMon, 30 Oct 2006 08:40:00 GMThttp://www.tkk7.com/RR00/articles/78083.htmlhttp://www.tkk7.com/RR00/comments/78083.htmlhttp://www.tkk7.com/RR00/articles/78083.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/78083.htmlhttp://www.tkk7.com/RR00/services/trackbacks/78083.html 聽聽聽聽聽聽聽 Configuration configuration=null;
聽聽聽聽聽聽聽 try {
聽聽聽聽聽聽聽聽聽聽聽 Configuration configurationSerializable = new Configuration();
聽聽聽聽聽聽聽聽聽聽聽 FileOutputStream fos = new FileOutputStream("serial");
聽聽聽聽聽聽聽聽聽聽聽 ObjectOutputStream oos = new ObjectOutputStream(fos);
聽聽聽聽聽聽聽聽聽聽聽 oos.writeObject(configurationSerializable);
聽聽聽聽聽聽聽聽聽聽聽 oos.flush();
聽聽聽聽聽聽聽聽聽聽聽 oos.close();
聽聽聽聽聽聽聽 } catch (FileNotFoundException e) {
聽聽聽聽聽聽聽聽聽聽聽 e.printStackTrace();聽 //To change body of catch statement use File | Settings | File Templates.
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 catch (IOException e) {
聽聽聽聽聽聽聽聽聽聽聽 e.printStackTrace();聽 //To change body of catch statement use File | Settings | File Templates.
聽聽聽聽聽聽聽 }

聽聽聽聽聽聽聽 try {
聽聽聽聽聽聽聽聽聽聽聽 FileInputStream fis = new FileInputStream("serial");
聽聽聽聽聽聽聽聽聽聽聽 ObjectInputStream ois = new ObjectInputStream(fis);
聽聽聽聽聽聽聽聽聽聽聽 configuration = (Configuration) ois.readObject();
聽聽聽聽聽聽聽聽聽聽聽 ois.close();
聽聽聽聽聽聽聽 } catch (FileNotFoundException e) {
聽聽聽聽聽聽聽聽聽聽聽 e.printStackTrace();聽 //To change body of catch statement use File | Settings | File Templates.
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 catch (IOException e) {
聽聽聽聽聽聽聽聽聽聽聽 e.printStackTrace();聽 //To change body of catch statement use File | Settings | File Templates.
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 catch (ClassNotFoundException e) {
聽聽聽聽聽聽聽聽聽聽聽 e.printStackTrace();聽 //To change body of catch statement use File | Settings | File Templates.
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 if(configuration!=null)
聽聽聽聽聽聽聽 {
聽聽聽聽聽聽聽 SessionFactory sessionFactory = configuration.configure().buildSessionFactory();
聽聽聽聽聽聽聽 Session session = sessionFactory.openSession();
聽聽聽聽聽聽聽 Transaction transaction = session.beginTransaction();
聽聽聽聽聽聽聽 callBack.doing(session);
聽聽聽聽聽聽聽 transaction.commit();
聽聽聽聽聽聽聽 }
聽聽聽 }
when will Configuration serialize and why it's some field seted transient?the example will be error because some field transient is null after serialize.



R.Zeus 2006-10-30 16:40 鍙戣〃璇勮
]]>
inverse in one-to-many mappinghttp://www.tkk7.com/RR00/articles/77190.htmlR.ZeusR.ZeusWed, 25 Oct 2006 06:23:00 GMThttp://www.tkk7.com/RR00/articles/77190.htmlhttp://www.tkk7.com/RR00/comments/77190.htmlhttp://www.tkk7.com/RR00/articles/77190.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/77190.htmlhttp://www.tkk7.com/RR00/services/trackbacks/77190.htmlwhen store or delete聽an 'one-to-many' object to database,it aways update the 'set' defined part.
It is wait time in store process and will be error in delete.
it is to avoid by set the "inverse = true" .

I will test affect in 'find' and 'update' process.

'find' and 'update' don't have any infection with or without 'inverse=true'.

the 'inverse' default 聽set to 'false';



R.Zeus 2006-10-25 14:23 鍙戣〃璇勮
]]>
more server run applicatin on the same database will be error!http://www.tkk7.com/RR00/articles/76370.htmlR.ZeusR.ZeusFri, 20 Oct 2006 05:35:00 GMThttp://www.tkk7.com/RR00/articles/76370.htmlhttp://www.tkk7.com/RR00/comments/76370.htmlhttp://www.tkk7.com/RR00/articles/76370.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/76370.htmlhttp://www.tkk7.com/RR00/services/trackbacks/76370.html聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽if there are more than two server run with the same system code
聽聽聽聽聽聽聽聽聽聽聽 and call the save method at the same time ,it will be result of hibernate
聽聽聽聽聽聽聽聽聽聽聽 error!because hibernate get the max id for ganerator and store it in
聽聽聽聽聽聽聽聽聽聽聽 cache for next time using.so one server will get the expired id if another
聽聽聽聽聽聽聽聽聽聽聽 server change the database following.
聽聽聽聽聽聽聽聽聽聽聽 befroe save object,hibernate will excute this sql after the server start up once:
聽聽聽聽聽聽聽聽聽聽聽聽 Hibernate: select max(ID) from TB_LOG
聽聽聽聽聽聽聽聽聽聽聽 TB_LOG is my log table.



R.Zeus 2006-10-20 13:35 鍙戣〃璇勮
]]>
Hibernate: Understand FlushMode.NEVERhttp://www.tkk7.com/RR00/articles/73976.htmlR.ZeusR.ZeusMon, 09 Oct 2006 02:08:00 GMThttp://www.tkk7.com/RR00/articles/73976.htmlhttp://www.tkk7.com/RR00/comments/73976.htmlhttp://www.tkk7.com/RR00/articles/73976.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/73976.htmlhttp://www.tkk7.com/RR00/services/trackbacks/73976.html

Hibernate: Understand FlushMode.NEVER

Posted by tfenne under Java


I've complained before about how the Hibernate documentation doesn't provide much help for those of us dealing with large data sets. The established point of view seems to be that "large amounts of data == batch processing" and "hibernate/java is not the best place for batch processing." Seeing as the system I'm working on currently (a DNAresequencingLIMS) has a complex data model and very large amounts of OLTP data, I'm at odds with the first piece of accepted knowledge. We deal with large (thousands of objects) complex object webs in memory to implement use cases driven from a user interface in human-time (i.e. non-batch).

One of the more useful pieces of advice I've seen meted out on the hibernate forums was a trite statement from Gavin to some poor user to "understand FlushMode.NEVER". Well, I've recently had occasion to understand it, and I thought I'd share. To use FlushMode.NEVER you might write something like:

session.setFlushMode(FlushMode.NEVER);

This tells the hibernate session that it is not to flush any state changes to the database at all, ever - unless told to do so by the application programmer calling session.flush() directly. That's fairly logical, and is useful in it's own right, but why does it have a big impact on performance in some scenarios?

To explain, let's take a look at a fairly typical use case of mine (if you don't understand the science, don't worry). It involves automatically picking the "best" available PCR primers for the genes/exons being resequenced in an experiment, and goes something like this:

  1. Find all the exons/targets in the experiment (ranges up to 5000)
  2. Find all the PCR primers that have already been ordered by the experiment, and worked
  3. Find all the PCR primers that are in queue to be ordered by the experiment
  4. Net out the primers against the targets to find what isn't covered
  5. For each un-covered area query for all possible PCR primers in the system
  6. Examine each matching primer and pick the best one for each target
  7. Save the picked PCR primers to the experiment

Because our domain model is fairly rich, by step 4 we've probably got on the order of 20-30,000 objects in the session! And then each query (it's actually two queries, but that's not so important) in steps 5/6 brings in anywhere from 0 to 20 additional objects. What's interesting though is that while we're pulling in a lot of objects, none of the objects we're loading are getting modified. Only new objects are getting created and saved at the end.

Back to FlushMode.NEVER then. You might assume that since we're not persisting or changing anything until the last step, changing the flush mode would have little consequence. You'd be wrong of course. In actuality setting flush mode to NEVER at the start of this flow and then flushing manually at the end caused the run time to drop by over half!

The reason for this is the way hibernate implements dirty checking. Every time you load an object into memory (and don't evict it) the session keeps track of it in case it changes. (Of course, you could evict it - but then any lazy loaded relationships won't be able to load.) So, any time you perform a query, the session iterates over all objects in the session checking dirtiness and flushes any dirty objects to the database. It does this to ensure that all state changes that might affect the query are present in the database before issuing the query to it. That's fine when you have only a few objects in session, but when you have thousands and are performing thousands of queries, it becomes a real drain on performance.

What I'm yet to understand is exactly why hibernate does it this way. Perhaps it's the developers' belief that improving performance for large data sets isn't worth the additional complexity? What am I talking about? Well, a lot (the vast majority) of the objects that get loaded into memory are proxied by hibernate anyway. These don't need to be dirty checked when queries are made because they could actively be flagged as dirty when changes are made through the proxy, and added directly to a dirty list. It would seem to me that if hibnerate always returned proxied instances - even on non-lazy loads - this problem could practically disappear. There's still the case when someone persists a new object and then tries to modify it without replacing their reference with a newly proxified reference- but even if those instances were tracked the old way, it would hardly affect performance in most use cases like this.

Anyway, the moral of the story is this: in use cases with lots of reading/querying and lots of objects in session you should use FlushMode.NEVER as long as you're not modifying data that will affact your queries. Example psuedo-code is below:

FlushMode previous = session.getFlushMode();
session.flush(); // who know's what been done till now
session.setFlushMode(FlushMode.NEVER);
// Do some querying
// Do some more querying
// Really load up that session
// Execute a few more queries
// Write back to some tables
session.flush();
session.setFlushMode(previous);
Comments:

session.setReadOnly() and instrumentation of classes will help you get close to what you want.

a simple dirty flag/setting is not enough to guarantee consistency.

Posted by Max Rydahl Andersen on August 17, 2006 at 04:12 AM EDT #



R.Zeus 2006-10-09 10:08 鍙戣〃璇勮
]]>
mappings.setDefaultLazy(dlNode == null || dlNode.getValue().equals("true"));http://www.tkk7.com/RR00/articles/73081.htmlR.ZeusR.ZeusSat, 30 Sep 2006 10:07:00 GMThttp://www.tkk7.com/RR00/articles/73081.htmlhttp://www.tkk7.com/RR00/comments/73081.htmlhttp://www.tkk7.com/RR00/articles/73081.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/73081.htmlhttp://www.tkk7.com/RR00/services/trackbacks/73081.html1st:聽聽 mappings.setDefaultLazy(dlNode == null || dlNode.getValue().equals("true"));
2ed: mappings.setAutoImport((aiNode == null) ? true : "true".equals(aiNode.getValue()));

the first is seems a bit more effective than the second but less readable ,hence we choose the second!
bad聽programmer write code readed by machine and by contraries good programmer write code readed by human!

R.Zeus 2006-09-30 18:07 鍙戣〃璇勮
]]>
New in Hibernate 3: Criteria API enhancementshttp://www.tkk7.com/RR00/articles/72800.htmlR.ZeusR.ZeusFri, 29 Sep 2006 06:30:00 GMThttp://www.tkk7.com/RR00/articles/72800.htmlhttp://www.tkk7.com/RR00/comments/72800.htmlhttp://www.tkk7.com/RR00/articles/72800.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/72800.htmlhttp://www.tkk7.com/RR00/services/trackbacks/72800.html

聽 Projection, aggregation, subselects, detatched criterias - its all there in the Hibernate 3 Criteria API. Let me show you some examples, starting with the new projection API. Suppose we have a User class and only want to query for its username:

session.createCriteria(User.class)
    . setProjection(Projection.property(\"username\"))
    .list();

would do exactly what we want. Of course we can also use projection for multiple properties, and combine it with all the other existing features of the Criteria API. For example

session.createCriteria(User.class).setProjection(
    Projections.propertyList()
        .add(Projection.property(\"firstname\"))
        .add(Projection.property(\"lastname\"))
    )
    .add(Restriction.gt(\"age\", 25))
    .list();

would give us the firstnames and lastnames of all users with an age larger than 25. We can also use aggregation - if we want to count the number of users with lastname 鈥淏lack鈥? we can use

session.createCriteria(User.class)
    .setProjection(Projections.rowCount())
    .add(Restriction.eq(\"lastname\", \"Black\"))
    .list();

we can even use grouping and projection on associated objects:

session.createCriteria(User.class)
    .createAlias(\"roles\", \"r\")
    .setProjection( Projections.projectionList()
        .add(Projection.groupProperty(\"r.name\"))
        .add(Projection.rowCount())
    )
    .list();

This criteria query gives us the number of users, grouped by role names. With the new Criteria API extensions, you can also construct 鈥渄etatched criteria鈥?instances, which you can build outside of the session scope, and later use for querying. For example

DetatchedCriteria dc = DetatchedCriteria.forClass(User.class)
    .add(Property.forName(\"firstname\").eq(\"John\")
    .setProjection(Property.forName(\"age\").min());
	
Session session = sessionFactory.openSession();
	
dc.getExecutableCriteria(session).list();

would give use the age of the youngest user named John. You can even use the detatched criteria for building subqueries. For example

DetatchedCriteria dc = DetatchedCriteria.forClass(User.class)
    .add(Property.forName(\"firstname\").eq(\"John\")
    .setProjection(Property.forName(\"age\").min());
	
session.createCriteria(User.class)
    .add(Subqueries.propertyEq(\"age\", dc))
    .list();

would give us all Users which have the same age as the youngest User named John.

Alltogether the new H3 criteria API now is featurewise just as powerful as the HQL query language. If you want to try and experiment with it, download the newest Hibernate 3 beta from the Hibernate website



R.Zeus 2006-09-29 14:30 鍙戣〃璇勮
]]>
refill of if-else or switchhttp://www.tkk7.com/RR00/articles/72633.htmlR.ZeusR.ZeusThu, 28 Sep 2006 09:30:00 GMThttp://www.tkk7.com/RR00/articles/72633.htmlhttp://www.tkk7.com/RR00/comments/72633.htmlhttp://www.tkk7.com/RR00/articles/72633.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/72633.htmlhttp://www.tkk7.com/RR00/services/trackbacks/72633.html

R.Zeus 2006-09-28 17:30 鍙戣〃璇勮
]]>
Mappings for many propertieshttp://www.tkk7.com/RR00/articles/71802.htmlR.ZeusR.ZeusMon, 25 Sep 2006 09:39:00 GMThttp://www.tkk7.com/RR00/articles/71802.htmlhttp://www.tkk7.com/RR00/comments/71802.htmlhttp://www.tkk7.com/RR00/articles/71802.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/71802.htmlhttp://www.tkk7.com/RR00/services/trackbacks/71802.htmlSessionFactory.How Configuration get the properties analyzed in HbmBinder .The bridge is the Mappings .Configuration
had many private property fields,e.g.聽 classes,collections,tables,imports and so on.when call HbmBinder to work,Configuration first createMappings with its property fields then pass the Mappings聽 to the HbmBinder .In HbmBinder ,what Mappings聽聽 had done is聽also the聽聽Configuration 's field done.

e.g. Configuration聽 has a field "imports" ,it gone with the Mappings as a parameter in Mappings constructor to HbmBinder .
in HbmBinder class ,HbmBinder use Mappings .addImport() to operate it and at the same time point to the Configuration's "imports".This is correlative to java's clone mechanism.

this gives us a exquisite way to deal with more properties among several class.





R.Zeus 2006-09-25 17:39 鍙戣〃璇勮
]]>
about "entity-name"http://www.tkk7.com/RR00/articles/71680.htmlR.ZeusR.ZeusMon, 25 Sep 2006 03:12:00 GMThttp://www.tkk7.com/RR00/articles/71680.htmlhttp://www.tkk7.com/RR00/comments/71680.htmlhttp://www.tkk7.com/RR00/articles/71680.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/71680.htmlhttp://www.tkk7.com/RR00/services/trackbacks/71680.htmlin聽POJO model,PersistentClass use "entity-name" or "name" to set the EntityName.it seems redundant because "name" is content util I find theDynamic models. in the mapping file, an entity-name has to be declared instead of (or in addition to) a class name. so the two name strategy is for two case.



R.Zeus 2006-09-25 11:12 鍙戣〃璇勮
]]>
ListIterator in hibernatehttp://www.tkk7.com/RR00/articles/69392.htmlR.ZeusR.ZeusWed, 13 Sep 2006 08:01:00 GMThttp://www.tkk7.com/RR00/articles/69392.htmlhttp://www.tkk7.com/RR00/comments/69392.htmlhttp://www.tkk7.com/RR00/articles/69392.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/69392.htmlhttp://www.tkk7.com/RR00/services/trackbacks/69392.html聽聽ListIterator liter = fromClause.getFromElements().listIterator( fromClause.getFromElements().size() );
聽聽while ( liter.hasPrevious() ) {
聽聽聽聽聽聽聽聽聽聽聽 log.debug("add previous");
聽聽聽聽聽聽聽聽聽聽聽 orderedFromElements.add( liter.previous() );
聽聽}

R.Zeus 2006-09-13 16:01 鍙戣〃璇勮
]]>
Tips & Trickshttp://www.tkk7.com/RR00/articles/68961.htmlR.ZeusR.ZeusMon, 11 Sep 2006 07:01:00 GMThttp://www.tkk7.com/RR00/articles/68961.htmlhttp://www.tkk7.com/RR00/comments/68961.htmlhttp://www.tkk7.com/RR00/articles/68961.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/68961.htmlhttp://www.tkk7.com/RR00/services/trackbacks/68961.html

You can count the number of query results without actually returning them:

( (Integer) session.iterate("select count(*) from ....").next() ).intValue()

To order a result by the size of a collection, use the following query:

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)

If your database supports subselects, you can place a condition upon selection size in the where clause of your query:

from User usr where size(usr.messages) >= 1

If your database doesn't support subselects, use the following query:

select usr.id, usr.name
from User usr.name
    join usr.messages msg
group by usr.id, usr.name
having count(msg) >= 1

As this solution can't return a User with zero messages because of the inner join, the following form is also useful:

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

Properties of a JavaBean can be bound to named query parameters:

Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size");
q.setProperties(fooBean); // fooBean has getName() and getSize()
List foos = q.list();

Collections are pageable by using the Query interface with a filter:

Query q = s.createFilter( collection, "" ); // the trivial filter
q.setMaxResults(PAGE_SIZE);
q.setFirstResult(PAGE_SIZE * pageNumber);
List page = q.list();

Collection elements may be ordered or grouped using a query filter:

Collection orderedCollection = s.filter( collection, "order by this.amount" );
Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" );

You can find the size of a collection without initializing it:

( (Integer) session.iterate("select count(*) from ....").next() ).intValue();


R.Zeus 2006-09-11 15:01 鍙戣〃璇勮
]]>
get query list's sizehttp://www.tkk7.com/RR00/articles/68960.htmlR.ZeusR.ZeusMon, 11 Sep 2006 07:00:00 GMThttp://www.tkk7.com/RR00/articles/68960.htmlhttp://www.tkk7.com/RR00/comments/68960.htmlhttp://www.tkk7.com/RR00/articles/68960.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/68960.htmlhttp://www.tkk7.com/RR00/services/trackbacks/68960.html There are several approaches to get the size of a list.
1. select cout(*) is ok, but forces you to a new select statement
2. try using a filter
3. use scrollable resultsets:
ScrollableResult scroll = query.scroll();
scroll.afterLast();
int size = scroll.rowNumber();
scroll.beforeFirst();


Which approach ist best, depends on your select.


R.Zeus 2006-09-11 15:00 鍙戣〃璇勮
]]>
hibernate3.1.3:polymorphism="explicit"http://www.tkk7.com/RR00/articles/66879.htmlR.ZeusR.ZeusThu, 31 Aug 2006 07:31:00 GMThttp://www.tkk7.com/RR00/articles/66879.htmlhttp://www.tkk7.com/RR00/comments/66879.htmlhttp://www.tkk7.com/RR00/articles/66879.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/66879.htmlhttp://www.tkk7.com/RR00/services/trackbacks/66879.htmlTable Per Concrete Class,if a class set polymorphism="implicit",when select from his child class or parent class,the clall can be selected.this is the default value of the 'polymorphism'.else if the class set polymorphism="explicit",only select from it's name then it can be select ,selecting 聽from his child class or parent class don't return it.

R.Zeus 2006-08-31 15:31 鍙戣〃璇勮
]]>
Herbiernate3.1.3:Sethttp://www.tkk7.com/RR00/articles/66874.htmlR.ZeusR.ZeusThu, 31 Aug 2006 07:26:00 GMThttp://www.tkk7.com/RR00/articles/66874.htmlhttp://www.tkk7.com/RR00/comments/66874.htmlhttp://www.tkk7.com/RR00/articles/66874.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/66874.htmlhttp://www.tkk7.com/RR00/services/trackbacks/66874.htmlSet in hibernate sort all elements by cast the field set to org.hibernate.type.SortedSetType,which wrap the聽聽java.util.SortedSet when persite In the SortedSetType.wrap(SessionImplementor session, Object collection).
it聽
return new PersistentSortedSet( session, (java.util.SortedSet) collection ); so if you wanted the set sortable,
must use the class that implements the
java.util.SortedSet ,and in java.util package,TreeSet聽 is 聽validated.
if use HashSet ,you聽will get error report always in insert time.



R.Zeus 2006-08-31 15:26 鍙戣〃璇勮
]]>
Query Cachehttp://www.tkk7.com/RR00/articles/66716.htmlR.ZeusR.ZeusWed, 30 Aug 2006 12:16:00 GMThttp://www.tkk7.com/RR00/articles/66716.htmlhttp://www.tkk7.com/RR00/comments/66716.htmlhttp://www.tkk7.com/RR00/articles/66716.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/66716.htmlhttp://www.tkk7.com/RR00/services/trackbacks/66716.htmlquery.setCacheable(); This cache's scope like Second-level cache,live among SessionFaction聽lifecycle( work in all sessionFactory lifecycle).it means聽even聽open聽a new session after another close,it also validate.The cache will be evict when the object changed.if the聽 associated object changed,the Query cache will not work.

if the first queryed obejct update ,second query object also use query cache and get the updated value,just like
Second-Level cache.


R.Zeus 2006-08-30 20:16 鍙戣〃璇勮
]]>
cache usagehttp://www.tkk7.com/RR00/articles/66711.htmlR.ZeusR.ZeusWed, 30 Aug 2006 10:28:00 GMThttp://www.tkk7.com/RR00/articles/66711.htmlhttp://www.tkk7.com/RR00/comments/66711.htmlhttp://www.tkk7.com/RR00/articles/66711.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/66711.htmlhttp://www.tkk7.com/RR00/services/trackbacks/66711.html<cache usage="read-write"/> in class after put the eccache.xml in the classpath,else the session-level cache don't work !

Hibernate Version:3.1.3

R.Zeus 2006-08-30 18:28 鍙戣〃璇勮
]]>
Object in sessionhttp://www.tkk7.com/RR00/articles/66709.htmlR.ZeusR.ZeusWed, 30 Aug 2006 10:18:00 GMThttp://www.tkk7.com/RR00/articles/66709.htmlhttp://www.tkk7.com/RR00/comments/66709.htmlhttp://www.tkk7.com/RR00/articles/66709.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/66709.htmlhttp://www.tkk7.com/RR00/services/trackbacks/66709.html聽聽 an object first loaded by session(eg,session.load(...,..)),if session don't close,the following load will return the same object.this means that if the first loaded object change,the following loaded object also聽== the first object ,not the refresh object from database!

compositeIdUser = (CompositeIdUser) session.load(CompositeIdUser.class, compositeIdUser);
compositeIdUser.setAge(new Integer(1133883)); //change the age
聽compositeIdUser = (CompositeIdUser) session.load(CompositeIdUser.class, compositeIdUser);
compositeIdUser.getAge will equals 1133883; //the second loaded聽object聽== the first!聽聽聽聽聽

in two session with session-level cache ,if the first object change and saveOrUpdate ,the second object don't select from database and still use cache.because when the first object change and saveOrUpdate ,the cache also update to the latest version.



R.Zeus 2006-08-30 18:18 鍙戣〃璇勮
]]>
Composite-Idhttp://www.tkk7.com/RR00/articles/66671.htmlR.ZeusR.ZeusWed, 30 Aug 2006 07:36:00 GMThttp://www.tkk7.com/RR00/articles/66671.htmlhttp://www.tkk7.com/RR00/comments/66671.htmlhttp://www.tkk7.com/RR00/articles/66671.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/66671.htmlhttp://www.tkk7.com/RR00/services/trackbacks/66671.htmlHibernate Version: 3.1.3

R.Zeus 2006-08-30 15:36 鍙戣〃璇勮
]]>
many-to-many deletehttp://www.tkk7.com/RR00/articles/66413.htmlR.ZeusR.ZeusTue, 29 Aug 2006 06:02:00 GMThttp://www.tkk7.com/RR00/articles/66413.htmlhttp://www.tkk7.com/RR00/comments/66413.htmlhttp://www.tkk7.com/RR00/articles/66413.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/66413.htmlhttp://www.tkk7.com/RR00/services/trackbacks/66413.html some person say:

When using a many-to-many association cascade="all", cascade="delete", and cascade="all-delete-orphans" aren't meaningful. That's because you might delete an instance that can have other parents pointing to it.

If you want to delete rows from the association table (rel_houses_owners) then I would suggest using two one-to-many relationships instead of many-to-many.

You would need one-to-many from owners to house_owners and many-to-one from house_owners to owners. This will allow you to cascade deletes in owner to house_owners without deleting the owner.

Use of many-to-many often leads to the solution described above and is hence discouraged.


R.Zeus 2006-08-29 14:02 鍙戣〃璇勮
]]>
one-to-mayhttp://www.tkk7.com/RR00/articles/66191.htmlR.ZeusR.ZeusMon, 28 Aug 2006 07:18:00 GMThttp://www.tkk7.com/RR00/articles/66191.htmlhttp://www.tkk7.com/RR00/comments/66191.htmlhttp://www.tkk7.com/RR00/articles/66191.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/66191.htmlhttp://www.tkk7.com/RR00/services/trackbacks/66191.html聽聽聽聽聽聽聽聽聽聽聽 id INTEGER NOT NULL IDENTITY PRIMARY KEY
聽聽聽聽聽聽聽聽聽聽聽 ,name varchar(50)
聽聽聽聽聽聽聽聽聽聽聽 , specialty_id INTEGER
聽聽聽聽聽聽聽聽聽聽聽 <!--if is not null,on one-to-many saveing object will encounter error -->
聽聽聽聽聽聽聽聽聽聽聽 );

why ?see the following debug report:

...
DEBUG - AbstractBatcher.log(366) | getSQL(sql) = insert into more_specialties (name, id) values (?, null)
...
DEBUG - AbstractBatcher.log(366) | getSQL(sql) = update more_specialties set specialty_id=? where id=?
...

it is clearly that it first insert null values to the specialty_id聽聽the update it.and in business logic, specialty_id should be null

it use the

聽<set name="moreSpecialties" table="more_specialties" cascade="all">
聽聽聽聽聽聽聽聽聽聽聽 <key column="specialty_id"聽 />
聽聽聽聽聽聽聽聽聽聽聽 <one-to-many class="MoreSpecialty" />
聽聽聽聽聽聽聽 </set>

and in the one-class Specialty of one-to-many聽聽,initl the聽Set,else聽it will be an error of java.lang.NullPointerException!
private Set moreSpecialties=new HashSet();



R.Zeus 2006-08-28 15:18 鍙戣〃璇勮
]]>
one-to-onehttp://www.tkk7.com/RR00/articles/66162.htmlR.ZeusR.ZeusMon, 28 Aug 2006 05:45:00 GMThttp://www.tkk7.com/RR00/articles/66162.htmlhttp://www.tkk7.com/RR00/comments/66162.htmlhttp://www.tkk7.com/RR00/articles/66162.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/66162.htmlhttp://www.tkk7.com/RR00/services/trackbacks/66162.htmlfor example


CREATE TABLE user (
聽 聽 id INT(11) NOT NULL auto_increment PRIMARY KEY,
聽 聽 name VARCHAR(100) NOT NULL default ''
);

CREATE TABLE room (
聽 聽 id INT(11) NOT NULL auto_increment PRIMARY KEY,
聽 聽 address VARCHAR(100) NOT NULL default ''
);


User.hbm.xml

  • 										<?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

    <hibernate-mapping>

    <class name="onlyfun.caterpillar.User" table="user">
    <id name="id" column="id" type="java.lang.Integer">
    <generator class="native"/>
    </id>

    <property name="name" column="name" type="java.lang.String"/>

    <one-to-one name="room"
    class="onlyfun.caterpillar.Room"
    cascade="all"/>
    </class>

    </hibernate-mapping>

    • Room.hbm.xml
    										<?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

    <hibernate-mapping>

    <class name="onlyfun.caterpillar.Room" table="room">
    <id name="id" column="id">
    <generator class="foreign">
    <param name="property">user</param>
    </generator>
    </id>

    <property name="address"
    column="address"
    type="java.lang.String"/>

    <one-to-one name="user"
    class="onlyfun.caterpillar.User"
    constrained="true"/>
    </class>

    </hibernate-mapping>
				
						java:
						










User user1 = new User();

user1.setName("bush");
Room room1 = new Room();
room1.setAddress("NTU-M8-419");
聽聽聽聽聽聽聽
user1.setRoom(room1);
room1.setUser(user1);
聽聽聽聽聽聽聽
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

session.save(user1);

聽聽聽聽聽聽聽
tx.commit();
session.close();






the above is run right,but if the following :


User user1 = new User();
user1.setName("bush");

Room room1 = new Room();
room1.setAddress("NTU-M8-419");
聽聽聽聽聽聽聽
user1.setRoom(room1);
room1.setUser(user1);



User user2 = new User();
user2.setName("bush");


//the new column point to the same room1 and no errors

user2.setRoom(room1);
聽聽聽聽聽聽聽
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

session.save(user1);
//save



聽聽session.save(user2);
聽聽聽聽聽

tx.commit();
session.close();



is "one-to-one" in hibernate just for creating 聽a foreign key for another table?
did it聽make any restriction between the two tables.


R.Zeus 2006-08-28 13:45 鍙戣〃璇勮
]]>
Hibernate3 : org.hibernate.cfg.Configuration瑙f瀽http://www.tkk7.com/RR00/articles/64886.htmlR.ZeusR.ZeusMon, 21 Aug 2006 13:08:00 GMThttp://www.tkk7.com/RR00/articles/64886.htmlhttp://www.tkk7.com/RR00/comments/64886.htmlhttp://www.tkk7.com/RR00/articles/64886.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/64886.htmlhttp://www.tkk7.com/RR00/services/trackbacks/64886.html 絎竴嬈″啓鏂囩珷錛屼笉濂界殑鍦版柟錛岃鍙d笅鐣欐儏鍝堛?/span>

org.hibernate.cfg.Configurations 鏍規嵁 xml 鏂囦歡閰嶇疆鏁翠釜宸ヤ綔榪囩▼涓墍闇瑕佺殑鍙傛暟銆備竴鑸?/span>

鎴戜滑浼氱敤 Configuration cfg = new Configuration().configure(); 鍒涘緩涓涓厤緗被銆傞偅涔堬紝榪欏彞璇濆埌搴曞仛浜嗕粈涔堝憿錛?/span>

棣栧厛錛?/span> new Configuration() 浼氬仛浜涗粈涔堝憿錛熸垜浠潵鐪嬩粬鐨勬簮鐮侊細

聽聽

protected Configuration(SettingsFactory settingsFactory) {

聽聽聽聽聽聽聽 System.out.println("Configuration(SettingsFactory settingsFactory)");

聽聽聽聽聽聽聽 this.settingsFactory = settingsFactory;

聽聽聽聽聽聽聽 reset();

聽聽聽 }

// 榛樿鏋勯犲嚱鏁幫紝鍏?/span> new SettingsFactory() 錛?/span> 鐒跺悗璋冪敤

//protected Configuration(SettingsFactory settingsFactory)

聽聽聽

public Configuration() {

聽聽聽聽聽聽聽 this(new SettingsFactory());

}

reset() 鍒濆鍖栦簡寰堝鍙橀噺錛屾劅鍏磋叮鐨勫彲浠ュ幓鐪嬫簮浠g爜錛屾病鏈変粈涔堢壒鍒殑鍦版柟銆?/span>

鎺ョ潃錛岃皟鐢?/span> configure() 鏂規硶錛?/span>

public Configuration configure() throws HibernateException {

聽聽聽聽聽聽聽 configure("/hibernate.cfg.xml");

聽聽聽聽聽聽聽 return this;

}

鍙互鐪嬪嚭錛岄粯璁や嬌鐢?/span> hibernate.cfg.xml 鏂囦歡錛屽鏋滄兂鐢ㄨ嚜瀹氫箟鐨勬枃浠訛紝鍙互璋冪敤

configure(鈥溾?xml鈥? 鏂規硶銆?/span>

public Configuration configure(String resource) throws HibernateException {

聽聽聽聽聽聽聽 log.debug("configuring from resource: " + resource);

聽聽聽聽聽聽聽 InputStream stream = getConfigurationInputStream(resource);

聽聽聽聽聽聽聽 return doConfigure(stream, resource);

}

鏍規嵁 getConfigurationInputStream(resource) 寰楀埌鏂囦歡嫻侊紝 getConfigurationInputStream(resource) 璋冪敤 ConfigHelper.getResourceAsStream(resource) 銆?/span>

public static InputStream getResourceAsStream(String resource) {

聽聽聽聽聽聽聽聽聽聽聽聽聽 String stripped = resource.startsWith("/") ?

聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 resource.substring(1) : resource;

聽聽聽聽聽聽聽聽聽聽聽聽聽 InputStream stream = null;

聽聽聽聽聽聽聽聽聽聽聽聽聽 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

聽聽聽聽聽聽聽聽聽聽聽聽聽 if (classLoader!=null) {

聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 stream = classLoader.getResourceAsStream( stripped );

聽聽聽聽聽聽聽聽聽聽聽聽聽 }

// 榪欓噷鐨勪唬鐮佸彲鑳藉簲璇ユ槸 stream = Environment.class.getResourceAsStream( resource );

聽聽聽聽聽聽聽聽聽聽聽聽聽 if ( stream == null ) {

聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Environment.class.getResourceAsStream( resource );

聽聽聽聽聽聽聽聽聽聽聽聽聽 }

聽聽聽聽聽聽聽聽聽聽聽聽聽 if ( stream == null ) {

聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 stream = Environment.class.getClassLoader().getResourceAsStream( stripped );

聽聽聽聽聽聽聽聽聽聽聽聽聽 }

聽聽聽聽聽聽聽聽聽聽聽聽聽 if ( stream == null ) {

聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 throw new HibernateException( resource + " not found" );

聽聽聽聽聽聽聽聽聽聽聽聽聽 }

聽聽聽聽聽聽聽聽聽聽聽聽聽 return stream;

聽聽聽聽聽聽 }

鐒跺悗 doConfigure(stream, resource) 銆?/span>

protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException {

org.dom4j.Document doc;

聽聽聽聽聽聽聽 try {

聽聽聽聽聽聽聽聽聽聽聽 List errors = new ArrayList();

聽聽聽聽聽聽聽聽聽聽聽 SAXReader saxReader = xmlHelper.createSAXReader(resourceName, errors, entityResolver);

聽聽聽聽聽聽聽聽聽聽聽 doc = saxReader.read(new InputSource(stream));

聽聽聽聽聽聽聽聽聽聽聽 if (errors.size() != 0) {

聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 throw new MappingException(

聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 "invalid configuration",

聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 (Throwable) errors.get(0)

聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 );

聽聽聽聽聽聽聽聽聽聽聽 }

聽聽聽聽聽聽聽 }

entityResolver 鍦ㄥ垵濮嬪間負 entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER ; 鍦?/span> reset() 鐨勬椂鍊欒緗殑銆?/span> XMLHelper.DEFAULT_DTD_RESOLVE 鍦?/span> XMLHelper 榛樿鏄?/span> XMLHelper.DEFAULT_DTD_RESOLVER= new DTDEntityResolver() 錛?/span> DTDEntityResolver 鏄敤鏉ュ姞杞?/span> dtd 鏂囦歡鐨勩傚埆璺熸垜璇翠綘涓嶇煡閬?/span> dtd 鏄粈涔堜笢瑗匡紵瀹冩湁 3 縐嶅姞杞芥柟寮忥細

1錛?span style="FONT: 7pt 'Times New Roman'">聽 鏂囦歡璺緞浠?/span> http://hibernate.sourceforge.net/ 寮澶寸殑鏂囦歡錛屽

http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd 錛?/span>

瀹冧細鎶?/span> http://hibernate.sourceforge.net 鍘繪帀錛屽姞涓?/span> org/hibernate/ 錛屾枃浠惰礬寰勪負

org/hibernate/hibernate-configuration-3.0.dtd 錛岀劧鍚庡姞杞借繖涓枃浠躲?/span>

2.聽聽聽聽聽聽 鏂囦歡璺緞浠?/span> file:// 寮澶寸殑鏂囦歡錛屽

file://hibernate-configuration-3.0.dtd 錛?/span>

瀹冧細鎶?/span> file:// 鍘繪帀錛岃礬寰勪負 hibernate-configuration-3.0.dtd 錛岀劧鍚庡姞杞借繖涓枃浠躲?/span>

3. 濡傛灉娌℃湁浠ヤ笂 2 縐嶆儏鍐碉紝鍒欑洿鎺ュ姞杞姐傚氨鏄礬寰勫悕娌℃湁淇敼榪囥?/span>

鏁翠釜榪囩▼鍦?/span> public InputSource resolveEntity(String publicId, String systemId) 涓疄鐜般?/span>

systemId 灝辨槸 dtd 鐨勮礬寰勩傚ぇ瀹跺彲浠ュ幓鐪嬬湅 SAXReader 綾昏嚜甯︾殑

protected static class SAXEntityResolver 錛屾瘮杈冩瘮杈冦?/span>

鍦ㄥ緱鍒?/span> doc 鐨勫?/span>

聽聽聽聽聽聽聽聽聽聽聽 doc = saxReader.read(new InputSource(stream));

鍚庯紝璋冪敤 protected Configuration doConfigure(org.dom4j.Document doc) 錛岃繖涓嚱鏁頒富瑕佹槸鏍規嵁 doc 鐨勫埌閰嶇疆鍙傛暟錛岀劧鍚庡瓨鍒?/span> properties 涓?/span>

鍏堟槸璁劇疆 session-factory 鐨勫悕瀛楋細

Element sfNode = doc.getRootElement().element("session-factory");

聽聽聽聽聽聽聽 String name = sfNode.attributeValue("name");

聽聽聽聽聽聽聽 if (name != null) {

聽聽聽聽聽聽聽聽聽聽聽聽 // 淇濆瓨鍒?/span> properties 涓紒

聽聽聽聽聽聽聽聽聽聽聽 properties.setProperty(Environment.SESSION_FACTORY_NAME, name);

聽聽聽聽聽聽聽 }

鐒跺悗鏄?/span> addProperties(sfNode) 錛屾妸 <property name=" "> </property> 淇濆瓨鍒?/span> properties 涓?/span>

// 榪欏彞璇濅及璁″張鏄浣欑殑

properties.setProperty(name, value);

聽聽聽聽聽聽聽聽聽聽 if (!name.startsWith("hibernate")) {

聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 properties.setProperty("hibernate." + name, value);

聽聽聽聽聽聽聽聽聽聽聽 }

鎺ョ潃璋冪敤浜?/span> parseSessionFactory(sfNode, name) 錛屾妸 mapping 錛?/span> class-cache 錛?/span> collection-cache 錛?/span> listener 錛?/span> event 絳夐厤緗繚瀛樸傚埌搴曞畠淇濆瓨鍒板摢錛屾垜涔熶笉鍏ㄧ煡閬擄紝鍙湅浜?/span>

protected void parseMappingElement(Element subelement, String name), 鏍規嵁閰嶇疆鍔犺澆浜?/span> mapping 鐨勬枃浠訛紝鏈鍚庝嬌鐢?/span> HbmBinder : public static void bindRoot(Document doc, Mappings mappings, java.util.Map inheritedMetas) 淇濆瓨銆?/span> bindRoot 鏄 mapping 涓殑 xml 鏂囦歡榪涜瑙f瀽銆?/span>

HbmBinder 鍜?/span> Configuration 閮芥湁 2000 琛屼互涓婄殑浠g爜錛屽湪 Hibernate 涓湁寰堥噸瑕佺殑鍦頒綅銆?/span> Configuration 浣跨敤 .cfg.xml 錛岃?/span> HbmBinder 鍒欎嬌鐢ㄤ簡 .hbm.xml 銆?/span>

聽聽聽聽聽聽聽聽聽聽聽聽聽 extractRootAttributes( hmNode, mappings ) 鏍規嵁 <hibernate-mapping> 鐨勯厤緗紝鎶婂垎鏋愮殑緇撴灉瀛樺叆 mapping 銆?/span>



R.Zeus 2006-08-21 21:08 鍙戣〃璇勮
]]>
java.sql.SQLException: Connection is brokenhttp://www.tkk7.com/RR00/articles/63243.htmlR.ZeusR.ZeusSat, 12 Aug 2006 12:11:00 GMThttp://www.tkk7.com/RR00/articles/63243.htmlhttp://www.tkk7.com/RR00/comments/63243.htmlhttp://www.tkk7.com/RR00/articles/63243.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/63243.htmlhttp://www.tkk7.com/RR00/services/trackbacks/63243.html WARN - SettingsFactory.buildSettings(103) | Could not obtain connection metadata

java.sql.SQLException: Connection is broken
聽聽聽聽聽聽聽 at org.hsqldb.jdbc.jdbcUtil.sqlException(Unknown Source)
聽聽聽聽聽聽聽 at org.hsqldb.jdbc.jdbcStatement.fetchResult(Unknown Source)
聽聽聽聽聽聽聽 at org.hsqldb.jdbc.jdbcStatement.executeQuery(Unknown Source)
聽聽聽聽聽聽聽 at org.hsqldb.jdbc.jdbcDatabaseMetaData.execute(Unknown Source)
聽聽聽聽聽聽聽 at org.hsqldb.jdbc.jdbcDatabaseMetaData.getDatabaseProductName(Unknown S
ource)
聽聽聽聽聽聽聽 at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:
75)
聽聽聽聽聽聽聽 at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:1881
)
聽聽聽聽聽聽聽 at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.jav
a:1174)
聽聽聽聽聽聽聽 at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSession
Factory(LocalSessionFactoryBean.java:825)


鍥犱負鎴戝湪lib涓斁浜唄sqldb-1.7.3.0.jar鎵浠ュ鑷翠簡閿欒錛?br />



R.Zeus 2006-08-12 20:11 鍙戣〃璇勮
]]>
Struts Recipes: Hibernate and Strutshttp://www.tkk7.com/RR00/articles/13308.htmlR.ZeusR.ZeusSun, 18 Sep 2005 06:11:00 GMThttp://www.tkk7.com/RR00/articles/13308.htmlhttp://www.tkk7.com/RR00/comments/13308.htmlhttp://www.tkk7.com/RR00/articles/13308.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/13308.htmlhttp://www.tkk7.com/RR00/services/trackbacks/13308.html

Struts Recipes: Hibernate and Struts

Add the power of Hibernate to your Struts application

Summary
In this excerpt from Struts Recipes, (Manning Publications, December 2004) authors George Franciscus and Danilo Gurovich illustrate how to use Hibernate in a Struts application. They also show how to create a Struts plug-in to improve performance. (2,200 words; January 24, 2005)
By George Franciscus and Danilo Gurovich

Persistence is a fundamental piece of an application. Obviously, without persistence all work would be lost. However, persistence means different things to different people. The length of time something must be persisted is a fundamental qualifier in choosing a persistence storage medium. For example, the HTTP session may be suitable when the life of a piece of data is limited to the user's session. In contrast, persistence over several sessions, or several users, requires a database. The volume of data is another important qualifier. For example, best practices suggest large amounts of data should not be stored in an HTTP session. In those circumstances, you need to consider a database. In this recipe we target persistence in a database.

The type of database you choose has an important influence on your architecture and design. As object-oriented developers, we tend to represent data as an interconnected web of objects as a means to describe the business problem at hand鈥攖his is often called a domain model. However, the most common storage medium is based on a relational paradigm. Unless our object model mirrors a relational structure, the in-memory representation of our data is at odds with the means to persist it. This problem is called the mismatch paradigm. One of the most popular tools to address the mismatch problem is a category of tools called object-relational mappers. An object-relational mapper is software used to transform an object view of the data into a relational one, and provide persistence services, such as create, read, update, and delete (CRUD). Many good papers have been written on object-relational mappers, but in essence, they all speak to the Data Mapper pattern. One of the most popular object-relational mappers is the open source Hibernate project.

In this recipe, we show you how to employ Hibernate in a Struts application. In addition, we will show you how to create a Struts plug-in to give your Hibernate-powered Struts applications a performance boost.

Recipe
In this recipe, we use an example to illustrate everything you need to do to use Hibernate in a Struts application. We create an application to retrieve and display elements from the chemical periodic table. The application offers the user a search page to look for an element by element symbol. The application responds by searching the database for an element matching the symbol name and returns information about the element.

We'll start by showing you how to get the Hypersonic database server up and running. With the database server started, we create the table and data required to exercise the application. Once the database is ready to go, we'll create all the Hibernate artifacts required to execute this application by using the Hypersonic database server. The next step is to respond to search requests by calling upon Hibernate to handle database access from inside our Action. Because creating Hibernate factory objects is expensive, we'll create a Struts plug-in to create the factory and store it in context.

Let's start by bringing up the Hypersonic database server. You need to download Hypersonic from http://hsqldb.sourceforge.net/. Place hsqldb.jar in your classpath and launch Hypersonic by entering the following command in your DOS prompt:

java org.hsqldb.Server

Although the server's response varies from one version of Hypersonic to another, the following response is a typical indication that Hypersonic is ready to serve database requests.

Server 1.6 is running
Press [Ctrl]+{c} to abort

With the database server up and running, we are ready to create the elements table and populate it with data, as shown in Listing 1.

Listing 1. Create and populate elements tables

create table elements (id integer(3) IDENTITY,
                 name char(30),
                 number char(30),
                 mass char(30),
                 symbol char(2));

CREATE UNIQUE INDEX ui_elements_pk ON elements (symbol)

insert into elements ( name, number, mass, symbol) values ('Manganese','25','55','Mn');
insert into elements ( name, number, mass, symbol) values ('Zinc','30','65','Zn');
insert into elements ( name, number, mass, symbol) values ('Thulium','69','169','Tm');
insert into elements ( name, number, mass, symbol) values ('Californium','98','251','Cf');
insert into elements ( name, number, mass, symbol) values ('Gold','79','197','Au');
insert into elements ( name, number, mass, symbol) values ('Ytterbium','70','173','Yb');
insert into elements ( name, number, mass, symbol) values ('Molybdenum','42','96','Mo');
insert into elements ( name, number, mass, symbol) values ('Palladium','46','106','Pd');

Listing 1 presents the SQL commands necessary to create the elements table, create a unique index on symbol, and insert data We have only presented a few of the periodic elements. We'll leave it to you to dust off your high school chemistry textbook to create data for the remaining elements.

Listing 2 presents the Element JavaBean used to store data retrieved from the database.

Listing 2. Element JavaBean

package com.strutsrecipes.hibernate.beans;

public class Element {
   private String name;
   private String symbol;
   private String number;
   private String mass;
   private int id;

   public Element() {
      super();
   }

   public Element(String name, String symbol, String number, String mass) {
      this.name = name;
      this.symbol = symbol;
      this.number = number;
      this.mass = mass;

   }

   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public String getMass() {
      return mass;
   }

   public String getName() {
      return name;
   }

   public String getNumber() {
      return number;
   }

   public String getSymbol() {
      return symbol;
   }

   public void setMass(String mass) {
      this.mass = mass;

   }

   public void setName(String name) {
      this.name = name;
   }

   public void setNumber(String number) {
      this.number = number;
   }

   public void setSymbol(String symbol) {
      this.symbol = symbol;
   }
}

Hibernate is an object-relational mapping tool. Its job is to map objects to relational tables and vice versa. Therefore, we must tell Hibernate how to map the columns in the "elements" table to the properties of the Elements JavaBean. This is done using the Element.hbm.xml file. The information embodied in this file is required to empower Hibernate to copy data from the table to the Elements JavaBean. If we were using Hibernate to update data, the information in the Element.hbm.xml file would be used to extract data from the Elements JavaBean to generate SQL update statements. Listing 3 presents Element.hbm.xml.

Listing 3. Element.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sf.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
   <class name="com.strutsrecipes.hibernate.beans.Element" table="elements">

      <id name="id" column="id">
         <generator class="native"/>
      </id>

      <property name="name" column="name"/>
      <property name="number" column="number"/>
      <property name="mass" column="mass"/>
      <property name="symbol" column="symbol"/>
   </class>
</hibernate-mapping>

Let's step through Listing 3

We declare the full package name of the class to be associated with the "elements" table. We then declare the name of the table associated with that class. Next, we declare the mapping from the id JavaBean property to the id column. Because the property and column names have the same value, we could have omitted the column attribute, but we have explicitly declared the column for clarity purposes. The <id> tag is a special tag. It is used to declare the primary key for the table. The enclosing <generator> tag instructs Hibernate to generate the key in whichever way is most appropriate for the database implementation. You should consult Hibernate documentation for more information on the <id> tag. Finally, we declare mapping for the remaining JavaBean properties. Once again the column attribute is declared for clarification purposes.

Once the mapping file has been broken down in detail, it's all rather straightforward. It simply describes which table maps to which class and which JavaBean properties map to which column names. Later on we will tell you where to place this file.

Next, we configure Hibernate by declaring environmental information. In Listing 4, we present the hibernate.cfg.xml file.

Listing 4. hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">

<hibernate-configuration>
   <session-factory>
   <property name="dialect">net.sf.hibernate.dialect.HSQLDialect</property>
   <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
   <property name="connection.username">sa</property>
   <property name="connection.password"></property>
   <property name="connection.url">jdbc:hsqldb:hsql://127.0.0.1</property>
   <property name="show_sql"> </property>
   <property name="">true</property>

   <mapping resource="/com/strutscookbook/hibernate/beans/Element.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Let's step through Listing 4.

We start by specifying the database implementation dialect that allows Hibernate to take advantage of implementation-specific features. We declare the Hypersonic dialect. You should consult the Hibernate documentation to choose the appropriate dialect for your database. We then declare the database driver. You must ensure this driver is in your application's classpath. We then declare the database username, the database password, and the database connection URL. Next, we instruct Hibernate to display the SQL generated at runtime in the log.

The hibernate.cfg.xml file must be placed in your classpath.

The procedure to use Hibernate within your application requires the following steps:

  1. Create a Hibernate configuration object

  2. Use the Hibernate configuration object to create a Hibernate factory object

  3. Use the Hibernate factory object to create a Hibernate session object

  4. Use the Hibernate session object to start a transaction (optional)

  5. Employ the Hibernate session object to create, read, update, and delete data on the database

  6. Commit the transaction (optional)

  7. Close the session

A Hibernate best practice is to create and cache the Hibernate factory to enhance performance. Therefore, we will create a Struts plug-in to perform Steps 1 and 2 and cache the Hibernate factory in the servlet context, as shown in Listing 5.

Listing 5. HibernatePlugin.java

package com.strutsrecipes.hibernate.plugin;

import java.net.URL;
import javax.servlet.ServletException;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.MappingException;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.cfg.Configuration;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;

public class HibernatePlugin implements PlugIn {
   private Configuration config;
   private SessionFactory factory;
   private String path = "/hibernate.cfg.xml";
   private static Class clazz = HibernatePlugin.class;

      public static final String KEY_NAME = clazz.getName();

      private static Log log = LogFactory.getLog(clazz);

   public void setPath(String path) {
      this.path = path;
   }

   public void init(ActionServlet servlet, ModuleConfig modConfig)
      throws ServletException {

      try {
         URL url = HibernatePlugin.class.getResource(path);
         config = new Configuration().configure(url);
         factory = config.buildSessionFactory();
         servlet.getServletContext().setAttribute(KEY_NAME, factory);

      } catch (MappingException e) {
         log.error("mapping error", e);
         throw new ServletException();

      } catch (HibernateException e) {
         log.error("hibernate error", e);
         throw new ServletException();
      }

   }

   public void destroy() {
      try {
         factory.close();
      } catch (HibernateException e) {
         log.error("unable to close factory", e);
      }
   }
}

Creating a Struts plug-in requires only two steps. First, create a class implementing org.apache.struts.action.PlugIn (Listing 5). Second, define a <plug-in> tag in the struts-config.xml file (Listing 6).

Let's step through Listing 5.

We create a constant to hold the name of the servlet context attribute key. We have chosen to use the HibernatePlugin class name. Notice the constant is static public final. We use the HibernatePlugin class to access the key name in the Action (Listing 7). We define the path property. By default, the Hibernate-Plugin looks for the Hibernate configuration file at /hibernate.cfg.xml. You can use this property to load the Hibernate configuration file from another filename and directory anywhere on the classpath. Next, we use the classloader to find the Hibernate configuration file and then we create the Hibernate configuration object. We use the Hibernate configuration object to create a Hibernate factory object and then we store the Hibernate factory object in the servlet context. The factory is now available to any code with a reference to the servlet.

As a good practice, we close the factory in the destroy method.

Listing 6 presents the application struts-config. The only thing out of the ordinary here is the <plug-in> tag. This is where we declare the Hibernate plug-in, which creates and caches the Hibernate factory object.

Listing 6. struts-config.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
   "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>
   <form-beans>
      <form-bean name="searchForm"type="com.strutsrecipes.hibernate.forms.SearchForm"/>
   </form-beans>

   <global-forwards>
      <forward name="search" path="/search.jsp"/>
      <forward name="searchsubmit" path="/searchsubmit.do"/>
   </global-forwards>

   <action-mappings>
      <action path="/searchsubmit"
            type="com.strutsrecipes.hibernate.actions.SearchAction"
            name="searchForm"
            scope="request"
            input="/search.jsp">
            <forward name="success" path="/element.jsp"/>
      </action>
   </action-mappings>

   <plug-in className="com.strutsrecipes.hibernate.plugin.HibernatePlugin">
      <set-property property="path" value="/hibernate.cfg.xml"/>
   </plug-in>
</struts-config>

Listing 7 presents the SearchForm used to search for an element. It's very simple because the user can only search by element symbol.

Listing 7. SearchForm.java

package com.strutsrecipes.hibernate.forms;

import org.apache.struts.action.ActionForm;
public class SearchForm extends ActionForm {
   String symbol;

   public String getSymbol() {
      return symbol;
   }

   public void setSymbol(String symbol) {
      this.symbol = symbol;
   }
}

Let's have a look at the SearchAction in Listing 8. Although you may decide to employ Hibernate in other areas of your application architecture, we have chosen to use it in the Action. We'll defer the discussion of the other alternatives to the discussion section.

Listing 8. SearchAction.java

package com.strutsrecipes.hibernate.actions;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.strutsrecipes.hibernate.beans.Element;
import com.strutsrecipes.hibernate.forms.SearchForm;
import com.strutsrecipes.hibernate.plugin.HibernatePlugin;

public class SearchAction extends Action {
   private static Log log = LogFactory.getLog(SearchAction.class);

   final public static String HQL_FIND_ELEMENT =
      "from com.strutsrecipes.hibernate.beans.Element as e where e.symbol = ?";

   public ActionForward execute(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

      SearchForm searchForm = (SearchForm) form;
      Element element = null;
      List elements = null;
      SessionFactory factory = null;
      Session session = null;

      try {

         factory =
                (SessionFactory) servlet.getServletContext()
               .getAttribute(HibernatePlugin.KEY_NAME);

         session = factory.openSession();

         elements =
            session.find(
            HQL_FIND_ELEMENT,
            searchForm.getSymbol(),
            Hibernate.STRING);

         if (!elements.isEmpty()) {
            element = (Element) elements.get(0);
         }

      } catch (HibernateException e) {
         log.error("Hibernate error", e);
         } finally {
            log.error("Hibernate exception encountered");
         session.close();
      }

      if (element != null) {
            request.setAttribute("element", element);
            return mapping.findForward("success");
      }

      ActionErrors errors = new ActionErrors();

      errors.add(ActionErrors.GLOBAL_ERROR,
         new ActionError("error.notfound"));
      saveErrors(request, errors);
      return mapping.getInputForward();
   }
}

Let's take a quick overview of what happens in the SearchAction. The SearchAction uses the SearchForm.getSymbol() method to obtain the element symbol entered by the user on the search page. Hibernate is used to search the database and convert the data stored in the database to an Element object. The Element object is placed in request context for the JavaServer Pages (JSP) page. Let's step through Listing 8 line by line to see how it's done in detail.

First, we declare a constant to search the database. We next cast the form to SearchForm and then we obtain the Hibernate factory. Recall the Hibernate plug-in has already created the factory and cached it in the servlet context. Next, we obtain a session. The session obtains a connection to the database. Hibernate uses the configuration information we created in Listing 4 to connect to the database. We then search the database.

There are other ways to employ Hibernate to search the database, but the find method is appropriate whenever a search doesn't use the primary key. Notice, we have the HQL_FIND_ELEMENT constant declared. The SQL defined in HQL_FIND_ELEMENT looks somewhat like standard SQL, but not quite. The SQL used by Hibernate is proprietary to Hibernate and reflects an object-oriented version of SQL, rather than the relational SQL to which you are accustomed.

Let's delve into the Hibernate SQL (HQL) code snippet.

from com.strutsrecipes.hibernate.beans.Element as e where e.symbol = ?

This statement tells Hibernate to select all Element objects residing in the com.strutsrecipes.hibernate.beans package. The where clause filters the list to only those elements whose symbols match a runtime parameter. The as e indicates that e may be used as an alias elsewhere in the HQL, as we have done in the where clause. You can see that we are selecting objects, not rows, in the database. Hibernate uses the information in Listing 4 to map the class we are interested in to its associated table. In this example, the relationship between the table and the object are very close, but that does not necessarily need to be the case.

The second and third arguments to the find method are the value and data type of the HQL replacement parameter. The Hibernate reference material describes other ways to replace runtime parameters.

The find method always returns a List. In this case, we obtain a list of Element objects. We are confident that a maximum of one instance is returned because the "elements" table has a unique key constraint on the symbol column (see Listing 1).

Returning to Listing 8, we copy the element reference in the first position in the list to the element variable. To deal with any Hibernate exceptions, we have chosen to log the exception and present the user a "not found" message, but you may decide to present a different message or use declarative exception handling. Next, we close the session. Closing the session in the finally clause guarantees it is attempted even when exceptions are thrown. We store the Element object in the request context and finally we build the ActionError when the symbol can't be found. For the sake of completeness, we have presented the search.jsp (Listing 9) and the element.jsp (Listing 10).

Listing 9. Search.jsp

<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<html:html>
<body>
   <h1>Search for an Element</h1>

   <html:form action="/searchsubmit.do">
      symbol <form:text property="symbol"/>
   <html:submit value="Search"/>
   </html:form>

   <html:errors/>

</body>
</html:html>

Listing 10. Element.jsp

<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<html:html>
   <h1>Periodic Element</h1>
   Name: <bean:write name="element" property="name"/><br>
   Symbol: <bean:write name="element" property="symbol"/><br>
   Number: <bean:write name="element" property="number"/><br>
   Mass: <bean:write name="element" property="mass"/><br>

   <html:link forward="search">Search</html:link><p>
</html:html>

Before putting Hibernate to work, consult the Hibernate documentation to ensure you have all the required Hibernate jar files in your classpath.

Discussion
Persistence of data is a tedious and laborious job. To make matters worse, a considerable effort must be spent transforming an object-oriented representation of the data to a relational one, and vice versa. Fortunately, several good object-relational mappers exist to ease this burden. In this recipe, we explored Hibernate鈥攐ne of the most popular open source object-relational mappers available to Java programmers.

Hibernate is a very rich product with many unexplored features left for you to discover. Our simple example is limited to read behavior, but the rest of the CRUD family is just as easy. Update functionality is as simple as accessing the desired element, calling the desired JavaBean setter, and calling the session commit method. Hibernate takes care of generating the SQL and updating the table. A delete is also rather simple鈥?CODE>session.delete(element) is all it takes! Finally, create only requires instantiating the object, calling the setters, and calling session.save(element).

Hibernate best practices recommend caching the Hibernate factory object. We chose to create and cache the factory using a Struts plug-in. Alternatively, you could have chosen to cache using any other means in your arsenal.

Although this recipe can serve you well, there are some drawbacks. First, we have exposed Hibernate to the Struts Action. Migrating to another persistence layer framework requires us to change every Action employing Hibernate. Second, our persistence is tightly coupled to the presentation layer. This coupling denies us the opportunity to reuse the persistence logic in some other presentation mechanism, such as a batch program.

Although there is room for improvement, this recipe is suitable when you do not expect to reuse your persistence logic. You may find yourself in this situation developing prototypes or small throwaway applications.

About the author
George Franciscus is a J2EE consultant and Struts authority. He is a coauthor of Manning's Struts in Action.

Danilo Gurovich is a manager of Web engineering at an e-commerce company. He has designed e-commerce and ERP/EAI Struts applications, and has led teams who have built them.



R.Zeus 2005-09-18 14:11 鍙戣〃璇勮
]]>
絎?4 绔? 閰嶇疆 http://www.tkk7.com/RR00/articles/9559.htmlR.ZeusR.ZeusMon, 08 Aug 2005 04:55:00 GMThttp://www.tkk7.com/RR00/articles/9559.htmlhttp://www.tkk7.com/RR00/comments/9559.htmlhttp://www.tkk7.com/RR00/articles/9559.html#Feedback0http://www.tkk7.com/RR00/comments/commentRss/9559.htmlhttp://www.tkk7.com/RR00/services/trackbacks/9559.html

 

鐢變簬Hibernate鏄負浜嗚兘鍦ㄥ悇縐嶄笉鍚岀幆澧冧笅宸ヤ綔鑰岃璁$殑, 鍥犳瀛樺湪鐫澶ч噺鐨勯厤緗弬鏁? 騫歌繍鐨勬槸澶氭暟閰嶇疆鍙傛暟閮?鏈夋瘮杈冪洿瑙傜殑榛樿鍊? 騫舵湁闅廐ibernate涓鍚屽垎鍙戠殑閰嶇疆鏍蜂緥hibernate.properties (浣嶄簬etc/)鏉ュ睍紺哄悇縐嶉厤緗夐」. 鎵闇鍋氱殑浠呬粎鏄皢榪欎釜鏍蜂緥鏂囦歡澶嶅埗鍒扮被璺緞 (classpath)涓嬪仛涓浜涜嚜瀹氫箟鐨勪慨鏀?

4.1.  鍙紪紼嬬殑閰嶇疆鏂瑰紡

涓涓?TT class=literal>org.hibernate.cfg.Configuration瀹炰緥浠h〃浜嗕竴涓簲鐢ㄧ▼搴忎腑Java綾誨瀷 鍒癝QL鏁版嵁搴撴槧灝勭殑瀹屾暣闆嗗悎. Configuration琚敤鏉ユ瀯寤轟竴涓?涓嶅彲鍙樼殑 (immutable))SessionFactory. 鏄犲皠瀹氫箟鍒欑敱涓嶅悓鐨刋ML鏄犲皠瀹氫箟鏂囦歡緙栬瘧鑰屾潵.

浣犲彲浠ョ洿鎺ュ疄渚嬪寲Configuration鏉ヨ幏鍙栦竴涓疄渚嬶紝騫朵負瀹冩寚瀹歑ML鏄犲皠瀹氫箟 鏂囦歡. 濡傛灉鏄犲皠瀹?涔夋枃浠跺湪綾昏礬寰?classpath)涓? 璇蜂嬌鐢?TT class=literal>addResource():

Configuration cfg = new Configuration()
    .addResource("Item.hbm.xml")
    .addResource("Bid.hbm.xml");

涓涓浛浠f柟娉曪紙鏈夋椂鏄洿濂界殑閫夋嫨錛夋槸錛屾寚瀹氳鏄犲皠鐨勭被錛岃Hibernate甯綘瀵繪壘鏄犲皠瀹氫箟鏂囦歡:

Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class);

Hibernate灝嗕細鍦ㄧ被璺緞(classpath)涓鎵懼悕瀛椾負 /org/hibernate/auction/Item.hbm.xml鍜?/org/hibernate/auction/Bid.hbm.xml鏄犲皠瀹氫箟鏂囦歡. 榪欑鏂瑰紡娑堥櫎浜嗕換浣曞鏂囦歡鍚嶇殑紜紪鐮?hardcoded).

Configuration涔熷厑璁鎬綘鎸囧畾閰嶇疆灞炴?

Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class)
    .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
    .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
    .setProperty("hibernate.order_updates", "true");

褰撶劧榪欎笉鏄敮涓鐨勪紶閫扝ibernate閰嶇疆灞炴х殑鏂瑰紡, 鍏朵粬鍙夋柟寮忚繕鍖呮嫭:

  1. 浼犱竴涓?TT class=literal>java.util.Properties瀹炰緥緇?Configuration.setProperties().

  2. 灝?TT class=literal>hibernate.properties鏀劇疆鍦ㄧ被璺緞(classpath)鐨勬牴鐩綍涓?(root directory).

  3. 閫氳繃java -Dproperty=value鏉ヨ緗郴緇?(System)灞炴?

  4. 鍦?TT class=literal>hibernate.cfg.xml涓姞鍏ュ厓绱?<property> (紼嶅悗璁ㄨ).

濡傛灉鎯沖敖蹇綋楠孒bernate, hibernate.properties鏄渶綆鍗曠殑鏂瑰紡.

Configuration瀹炰緥鏄竴涓惎鍔ㄦ湡闂達紙startup-time錛夌殑瀵硅薄, 涓鏃?TT class=literal>SessionFactory鍒涘緩瀹屾垚瀹冨氨琚涪寮冧簡.

4.2.  鑾峰緱SessionFactory

褰撴墍鏈夋槧灝勫畾涔夎Configuration瑙f瀽鍚? 搴旂敤紼嬪簭蹇呴』鑾峰緱涓涓敤浜庢瀯閫?TT class=literal>Session瀹炰緥鐨勫伐鍘? 榪欎釜宸ュ巶灝嗚搴旂敤紼嬪簭鐨勬墍鏈夌嚎紼嬪叡浜?

SessionFactory sessions = cfg.buildSessionFactory();

Hibernate鍏佽浣犵殑搴旂敤紼嬪簭鍒涘緩澶氫釜SessionFactory瀹炰緥. 榪欏 浣跨敤澶氫釜鏁版嵁搴撶殑搴旂敤鏉ヨ寰堟湁鐢?

4.3.  JDBC榪炴帴

閫氬父浣犲笇鏈?TT class=literal>SessionFactory鏉ヤ負浣犲垱寤哄拰緙撳瓨(pool)JDBC榪炴帴. 濡傛灉浣犻噰鐢ㄨ繖縐嶆柟寮? 鍙渶瑕佸涓嬩緥鎵紺洪偅鏍鳳紝鎵撳紑涓涓?TT class=literal>Session:

Session session = sessions.openSession(); // open a new Session

涓鏃︿綘闇瑕佽繘琛屾暟鎹闂椂, 灝變細浠庤繛鎺ユ睜(connection pool)鑾峰緱涓涓狫DBC榪炴帴.

涓轟簡浣胯繖縐嶆柟寮忓伐浣滆搗鏉? 鎴戜滑闇瑕佸悜Hibernate浼犻掍竴浜汮DBC榪炴帴鐨勫睘鎬? 鎵鏈塇ibernate灞炴х殑鍚嶅瓧鍜岃涔夐兘鍦?TT class=literal>org.hibernate.cfg.Environment涓畾涔? 鎴戜滑鐜板湪灝嗘弿榪癑DBC榪炴帴閰嶇疆涓渶閲嶈鐨勮緗?

濡傛灉浣犺緗涓嬪睘鎬э紝Hibernate灝嗕嬌鐢?TT class=literal>java.sql.DriverManager鏉ヨ幏寰?鍜岀紦瀛?JDBC榪炴帴 :

琛?nbsp;4.1.  Hibernate JDBC灞炴?

灞炴у悕 鐢ㄩ?
hibernate.connection.driver_class jdbc椹卞姩綾?/EM>
hibernate.connection.url jdbc URL
hibernate.connection.username 鏁版嵁搴撶敤鎴?/EM>
hibernate.connection.password 鏁版嵁搴撶敤鎴峰瘑鐮?/EM>
hibernate.connection.pool_size 榪炴帴姹犲閲忎笂闄愭暟鐩?/EM>

浣咹ibernate鑷甫鐨勮繛鎺ユ睜綆楁硶鐩稿綋涓嶆垚鐔? 瀹冨彧鏄負浜嗚浣犲揩浜涗笂鎵?SPAN class=emphasis>錛屼笉閫傚悎鐢ㄤ簬浜у搧緋葷粺鎴栨ц兘嫻嬭瘯涓?鍑轟簬鏈浣蟲ц兘鍜岀ǔ瀹氭ц冭檻浣犲簲璇ヤ嬌鐢ㄧ涓夋柟鐨勮繛鎺ユ睜銆傚彧闇瑕佽繛鎺ユ睜鐨勭壒瀹氳緗浛鎹?hibernate.connection.pool_size銆傝繖灝嗗叧闂璈ibernate鑷甫鐨勮繛鎺ユ睜. 渚嬪, 浣犲彲鑳戒細鎯崇敤C3P0.

C3P0鏄竴涓殢Hibernate涓鍚屽垎鍙戠殑寮婧愮殑JDBC榪炴帴姹? 瀹冧綅浜?TT class=literal>lib鐩綍涓嬨?濡傛灉浣犺緗簡hibernate.c3p0.*鐩稿叧鐨勫睘鎬? Hibernate灝嗕嬌鐢?C3P0ConnectionProvider鏉ョ紦瀛楯DBC榪炴帴. 濡傛灉浣犳洿鍘熸剰浣跨敤Proxool, 璇峰弬鑰冨彂 琛屽寘涓殑hibernate.properties騫跺埌Hibernate緗戠珯鑾峰彇鏇村鐨勪俊鎭?

榪欐槸涓涓嬌鐢–3P0鐨?TT class=literal>hibernate.properties鏍蜂緥鏂囦歡:

hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
hibernate.connection.username = myuser
hibernate.connection.password = secret
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

涓轟簡鑳藉湪搴旂敤紼嬪簭鏈嶅姟鍣?application server)涓嬌鐢℉ibernate, 浣犲簲褰撴繪槸灝咹ibernate 閰嶇疆鎴愭敞鍐屽湪JNDI涓殑Datasource澶勮幏寰楄繛鎺ワ紝浣犺嚦灝戦渶瑕佽緗笅鍒楀睘鎬т腑鐨勪竴涓?

琛?nbsp;4.2.  Hibernate鏁版嵁婧愬睘鎬?

灞炴у悕 鐢ㄩ?
hibernate.connection.datasource 鏁版嵁婧怞NDI鍚嶅瓧
hibernate.jndi.url JNDI鎻愪緵鑰呯殑URL (鍙?
hibernate.jndi.class JNDI InitialContextFactory綾?/EM> (鍙?
hibernate.connection.username 鏁版嵁搴撶敤鎴?/EM> (鍙?
hibernate.connection.password 鏁版嵁搴撶敤鎴峰瘑鐮?/EM> (鍙?

榪欓噷鏈変竴涓嬌鐢ㄥ簲鐢ㄧ▼搴忔湇鍔″櫒JNDI鏁版嵁婧愮殑hibernate.properties鏍蜂緥鏂囦歡:

hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
    org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
    org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

浠嶫NDI鏁版嵁婧愯幏寰楃殑JDBC榪炴帴灝嗚嚜鍔ㄥ弬涓庡簲鐢ㄧ▼搴忔湇鍔″櫒涓鍣ㄧ鐞嗙殑浜嬪姟(container-managed transactions)涓幓.

浠諱綍榪炴帴(connection)閰嶇疆灞炴х殑灞炴у悕瑕佷互"hibernate.connnection"鍓嶇紑寮澶? 渚嬪, 浣犲彲鑳戒細浣跨敤hibernate.connection.charSet鏉ユ寚瀹?TT class=literal>charSet.

閫氳繃瀹炵幇org.hibernate.connection.ConnectionProvider鎺ュ彛錛屼綘鍙互瀹氫箟灞炰簬 浣犺嚜宸辯殑鑾峰緱JDBC榪炴帴鐨勬彃浠剁瓥鐣ャ傞氳繃璁劇疆hibernate.connection.provider_class錛?浣犲彲浠ラ夋嫨涓涓嚜瀹氫箟鐨勫疄鐜?

4.4.  鍙夌殑閰嶇疆灞炴?

鏈夊ぇ閲忓睘鎬ц兘鐢ㄦ潵鎺у埗Hibernate鍦ㄨ繍琛屾湡鐨勮涓? 瀹冧滑閮芥槸鍙夌殑, 騫舵嫢鏈夐傚綋鐨勯粯璁ゅ?

璀﹀憡: 鍏朵腑涓浜涘睘鎬ф槸"緋葷粺綰?system-level)鐨?. 緋葷粺綰у睘鎬у彲浠ラ氳繃java -Dproperty=value鎴?hibernate.properties鏉ヨ緗? 鑰?SPAN class=emphasis>涓嶈兘鐢ㄤ笂闈㈡弿榪扮殑鍏朵粬鏂規硶鏉ヨ緗?

琛?nbsp;4.3.  Hibernate閰嶇疆灞炴?

灞炴у悕 鐢ㄩ?
hibernate.dialect 涓涓狧ibernate Dialect綾誨悕鍏佽Hibernate閽堝鐗瑰畾鐨勫叧緋繪暟鎹簱鐢熸垚浼樺寲鐨凷QL.

鍙栧?/SPAN> full.classname.of.Dialect

hibernate.show_sql 杈撳嚭鎵鏈塖QL璇彞鍒版帶鍒跺彴.

鍙栧?/SPAN> true | false

hibernate.default_schema 鍦ㄧ敓鎴愮殑SQL涓? 灝嗙粰瀹氱殑schema/tablespace闄勫姞浜庨潪鍏ㄩ檺瀹氬悕鐨勮〃鍚嶄笂.

鍙栧?/SPAN> SCHEMA_NAME

hibernate.default_catalog 鍦ㄧ敓鎴愮殑SQL涓? 灝嗙粰瀹氱殑catalog闄勫姞浜庢病鍏ㄩ檺瀹氬悕鐨勮〃鍚嶄笂.

鍙栧?/SPAN> CATALOG_NAME

hibernate.session_factory_name SessionFactory鍒涘緩鍚庯紝灝嗚嚜鍔ㄤ嬌鐢ㄨ繖涓悕瀛楃粦瀹氬埌JNDI涓?

鍙栧?/SPAN> jndi/composite/name

hibernate.max_fetch_depth 涓哄崟鍚戝叧鑱?涓瀵逛竴, 澶氬涓)鐨勫榪炴帴鎶撳彇錛坥uter join fetch錛夋爲璁劇疆鏈澶ф繁搴? 鍊間負0鎰忓懗鐫灝嗗叧闂粯璁ょ殑澶栬繛鎺ユ姄鍙?

鍙栧?/SPAN> 寤鴻鍦?TT class=literal>0鍒?TT class=literal>3涔嬮棿鍙栧?

hibernate.default_batch_fetch_size 涓篐ibernate鍏寵仈鐨勬壒閲忔姄鍙栬緗粯璁ゆ暟閲?

鍙栧?/SPAN> 寤鴻鐨勫彇鍊間負4, 8, 鍜?TT class=literal>16

hibernate.default_entity_mode 涓虹敱榪欎釜SessionFactory鎵撳紑鐨勬墍鏈塖ession鎸囧畾榛樿鐨勫疄浣撹〃鐜版ā寮?

鍙栧?/SPAN> dynamic-map, dom4j, pojo

hibernate.order_updates 寮哄埗Hibernate鎸夌収琚洿鏂版暟鎹殑涓婚敭錛屼負SQL鏇存柊鎺掑簭銆傝繖涔堝仛灝嗗噺灝戝湪楂樺茍鍙戠郴緇熶腑浜嬪姟鐨勬閿併?

鍙栧?/SPAN> true | false

hibernate.generate_statistics 濡傛灉寮鍚? Hibernate灝嗘敹闆嗘湁鍔╀簬鎬ц兘璋冭妭鐨勭粺璁℃暟鎹?

鍙栧?/SPAN> true | false

hibernate.use_identifer_rollback 濡傛灉寮鍚? 鍦ㄥ璞¤鍒犻櫎鏃剁敓鎴愮殑鏍囪瘑灞炴у皢琚噸璁句負榛樿鍊?

鍙栧?/SPAN> true | false

hibernate.use_sql_comments 濡傛灉寮鍚? Hibernate灝嗗湪SQL涓敓鎴愭湁鍔╀簬璋冭瘯鐨勬敞閲婁俊鎭? 榛樿鍊間負false.

鍙栧?/SPAN> true | false

琛?nbsp;4.4.  Hibernate JDBC鍜岃繛鎺?connection)灞炴?

灞炴у悕 鐢ㄩ?
hibernate.jdbc.fetch_size 闈為浂鍊鹼紝鎸囧畾JDBC鎶撳彇鏁伴噺鐨勫ぇ灝?(璋冪敤Statement.setFetchSize()).
hibernate.jdbc.batch_size 闈為浂鍊鹼紝鍏佽Hibernate浣跨敤JDBC2鐨勬壒閲忔洿鏂?

鍙栧?/SPAN> 寤鴻鍙?TT class=literal>5鍒?TT class=literal>30涔嬮棿鐨勫?

hibernate.jdbc.batch_versioned_data 濡傛灉浣犳兂璁╀綘鐨凧DBC椹卞姩浠?TT class=literal>executeBatch()榪斿洖姝g‘鐨勮璁℃暟 , 閭d箞灝嗘灞炴ц涓?TT class=literal>true(寮鍚繖涓夐」閫氬父鏄畨鍏ㄧ殑). 鍚屾椂錛孒ibernate灝嗕負鑷姩鐗堟湰鍖栫殑鏁版嵁浣跨敤鎵歸噺DML. 榛樿鍊間負false.

eg. true | false

hibernate.jdbc.factory_class 閫夋嫨涓涓嚜瀹氫箟鐨?TT class=literal>Batcher. 澶氭暟搴旂敤紼嬪簭涓嶉渶瑕佽繖涓厤緗睘鎬?

eg. classname.of.Batcher

hibernate.jdbc.use_scrollable_resultset 鍏佽Hibernate浣跨敤JDBC2鐨勫彲婊氬姩緇撴灉闆? 鍙湁鍦ㄤ嬌鐢ㄧ敤鎴鋒彁渚涚殑JDBC榪炴帴鏃訛紝榪欎釜閫夐」鎵嶆槸蹇呰鐨? 鍚﹀垯Hibernate浼氫嬌鐢ㄨ繛鎺ョ殑鍏冩暟鎹?

鍙栧?/SPAN> true | false

hibernate.jdbc.use_streams_for_binary 鍦↗DBC璇誨啓binary (浜岃繘鍒?鎴?TT class=literal>serializable (鍙簭鍒楀寲) 鐨勭被鍨嬫椂浣跨敤嫻?stream)(緋葷粺綰у睘鎬?.

鍙栧?/SPAN> true | false

hibernate.jdbc.use_get_generated_keys 鍦ㄦ暟鎹彃鍏ユ暟鎹簱涔嬪悗錛屽厑璁鎬嬌鐢↗DBC3 PreparedStatement.getGeneratedKeys() 鏉ヨ幏鍙栨暟鎹簱鐢熸垚鐨刱ey(閿?銆傞渶瑕丣DBC3+椹卞姩鍜孞RE1.4+, 濡傛灉浣犵殑鏁版嵁搴撻┍鍔ㄥ湪浣跨敤Hibernate鐨勬爣 璇嗙敓鎴愬櫒鏃墮亣鍒伴棶棰橈紝璇峰皢姝ゅ艱涓篺alse. 榛樿鎯呭喌涓嬪皢浣跨敤榪炴帴鐨勫厓鏁版嵁鏉ュ垽瀹氶┍鍔ㄧ殑鑳藉姏.

鍙栧?/SPAN> true|false

hibernate.connection.provider_class 鑷畾涔?TT class=literal>ConnectionProvider鐨勭被鍚? 姝ょ被鐢ㄦ潵鍚慔ibernate鎻愪緵JDBC榪炴帴.

鍙栧?/SPAN> classname.of.ConnectionProvider

hibernate.connection.isolation 璁劇疆JDBC浜嬪姟闅旂綰у埆. 鏌ョ湅java.sql.Connection鏉ヤ簡瑙e悇涓肩殑鍏蜂綋鎰忎箟, 浣嗚娉ㄦ剰澶氭暟鏁版嵁搴撻兘涓嶆敮鎸佹墍鏈夌殑闅旂綰у埆.

鍙栧?/SPAN> 1, 2, 4, 8

hibernate.connection.autocommit 鍏佽琚紦瀛樼殑JDBC榪炴帴寮鍚嚜鍔ㄦ彁浜?autocommit) (涓嶅緩璁?.

鍙栧?/SPAN> true | false

hibernate.connection.release_mode 鎸囧畾Hibernate鍦ㄤ綍鏃墮噴鏀綣DBC榪炴帴. 榛樿鎯呭喌涓?鐩村埌Session琚樉寮忓叧闂垨琚柇寮榪炴帴鏃?鎵嶄細閲婃斁JDBC榪炴帴. 瀵逛簬搴旂敤紼嬪簭鏈嶅姟鍣ㄧ殑JTA鏁版嵁婧? 浣犲簲褰撲嬌鐢?TT class=literal>after_statement, 榪欐牱鍦ㄦ瘡嬈DBC璋冪敤鍚庯紝閮戒細涓誨姩鐨勯噴鏀捐繛鎺? 瀵逛簬闈濲TA鐨勮繛鎺? 浣跨敤after_transaction鍦ㄦ瘡涓簨鍔$粨鏉熸椂閲婃斁榪炴帴鏄悎鐞嗙殑. auto灝嗕負JTA鍜孋MT浜嬪姟絳栫暐閫夋嫨after_statement, 涓篔DBC浜嬪姟絳栫暐閫夋嫨after_transaction.

鍙栧?/SPAN> on_close | after_transaction | after_statement | auto

hibernate.connection.<propertyName> 灝咼DBC灞炴?TT class=literal>propertyName浼犻掑埌DriverManager.getConnection()涓幓.
hibernate.jndi.<propertyName> 灝嗗睘鎬?TT class=literal>propertyName浼犻掑埌JNDI InitialContextFactory涓幓.

琛?nbsp;4.5.  Hibernate緙撳瓨灞炴?

灞炴у悕 鐢ㄩ?
hibernate.cache.provider_class 鑷畾涔夌殑CacheProvider鐨勭被鍚?

鍙栧?/SPAN> classname.of.CacheProvider

hibernate.cache.use_minimal_puts 浠ラ綣佺殑璇繪搷浣滀負浠d環, 浼樺寲浜岀駭緙撳瓨鏉ユ渶灝忓寲鍐欐搷浣? 鍦℉ibernate3涓紝榪欎釜璁劇疆瀵圭殑闆嗙兢緙撳瓨闈炲父鏈夌敤, 瀵歸泦緹ょ紦瀛樼殑瀹炵幇鑰岃█錛岄粯璁ゆ槸寮鍚殑.

鍙栧?/SPAN> true|false

hibernate.cache.use_query_cache 鍏佽鏌ヨ緙撳瓨, 涓埆鏌ヨ浠嶇劧闇瑕佽璁劇疆涓哄彲緙撳瓨鐨?

鍙栧?/SPAN> true|false

hibernate.cache.use_second_level_cache 鑳界敤鏉ュ畬鍏ㄧ姝嬌鐢ㄤ簩綰х紦瀛? 瀵歸偅浜涘湪綾葷殑鏄犲皠瀹氫箟涓寚瀹?TT class=literal><cache>鐨勭被錛屼細榛樿寮鍚簩綰х紦瀛?

鍙栧?/SPAN> true|false

hibernate.cache.query_cache_factory 鑷畾涔夌殑瀹炵幇QueryCache鎺ュ彛鐨勭被鍚? 榛樿涓哄唴寤虹殑StandardQueryCache.

鍙栧?/SPAN> classname.of.QueryCache

hibernate.cache.region_prefix 浜岀駭緙撳瓨鍖哄煙鍚嶇殑鍓嶇紑.

鍙栧?/SPAN> prefix

hibernate.cache.use_structured_entries 寮哄埗Hibernate浠ユ洿浜烘у寲鐨勬牸寮忓皢鏁版嵁瀛樺叆浜岀駭緙撳瓨.

鍙栧?/SPAN> true|false

琛?nbsp;4.6.  Hibernate浜嬪姟灞炴?

灞炴у悕 鐢ㄩ?
hibernate.transaction.factory_class 涓涓?TT class=literal>TransactionFactory鐨勭被鍚? 鐢ㄤ簬Hibernate Transaction API (榛樿涓?TT class=literal>JDBCTransactionFactory).

鍙栧?/SPAN> classname.of.TransactionFactory

jta.UserTransaction 涓涓狫NDI鍚嶅瓧錛岃JTATransactionFactory鐢ㄦ潵浠庡簲鐢ㄦ湇鍔″櫒鑾峰彇JTA UserTransaction.

鍙栧?/SPAN> jndi/composite/name

hibernate.transaction.manager_lookup_class 涓涓?TT class=literal>TransactionManagerLookup鐨勭被鍚?- 褰撲嬌鐢↗VM綰х紦瀛橈紝鎴栧湪JTA鐜涓嬌鐢╤ilo鐢熸垚鍣ㄧ殑鏃跺欓渶瑕佽綾?

鍙栧?/SPAN> classname.of.TransactionManagerLookup

hibernate.transaction.flush_before_completion 濡傛灉寮鍚? session鍦ㄤ簨鍔″畬鎴愬悗灝嗚鑷姩娓呮礂(flush). (鍦℉ibernate鍜孋MT涓璧蜂嬌鐢ㄦ椂寰堟湁鐢?)

鍙栧?/SPAN> true | false

hibernate.transaction.auto_close_session 濡傛灉寮鍚? session鍦ㄤ簨鍔″畬鎴愬悗灝嗚鑷姩鍏抽棴. (鍦℉ibernate鍜孋MT涓璧蜂嬌鐢ㄦ椂寰堟湁鐢?)

鍙栧?/SPAN> true | false

琛?nbsp;4.7.  鍏朵粬灞炴?

灞炴у悕 鐢ㄩ?
hibernate.query.factory_class 閫夋嫨HQL瑙f瀽鍣ㄧ殑瀹炵幇.

鍙栧?/SPAN> org.hibernate.hql.ast.ASTQueryTranslatorFactory or org.hibernate.hql.classic.ClassicQueryTranslatorFactory

hibernate.query.substitutions 灝咹ibernate鏌ヨ涓殑絎﹀彿鏄犲皠鍒癝QL鏌ヨ涓殑絎﹀彿 (絎﹀彿鍙兘鏄嚱鏁板悕鎴栧父閲忓悕瀛?.

鍙栧?/SPAN> hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC

hibernate.hbm2ddl.auto 鍦?TT class=literal>SessionFactory鍒涘緩鏃訛紝鑷姩灝嗘暟鎹簱schema鐨凞DL瀵煎嚭鍒版暟鎹簱. 浣跨敤 create-drop鏃?鍦ㄦ樉寮忓叧闂?TT class=literal>SessionFactory鏃訛紝灝哾rop鎺夋暟鎹簱schema.

鍙栧?/SPAN> update | create | create-drop

hibernate.cglib.use_reflection_optimizer 寮鍚疌GLIB鏉ユ浛浠h繍琛屾椂鍙嶅皠鏈哄埗(緋葷粺綰у睘鎬?. 鍙嶅皠鏈哄埗鏈夋椂鍦ㄩ櫎閿欐椂姣旇緝鏈夌敤. 娉ㄦ剰鍗充嬌鍏抽棴榪欎釜浼樺寲, Hibernate榪樻槸闇瑕丆GLIB. 浣犱笉鑳藉湪hibernate.cfg.xml涓緗灞炴?

鍙栧?/SPAN> true | false

4.4.1.  SQL鏂硅█

浣犲簲褰撴繪槸涓轟綘鐨勬暟鎹簱灞炴?TT class=literal>hibernate.dialect璁劇疆姝g‘鐨?org.hibernate.dialect.Dialect瀛愮被. 濡傛灉浣犳寚瀹氫竴縐嶆柟璦, Hibernate灝嗕負涓婇潰鍒楀嚭鐨勪竴浜涘睘鎬т嬌鐢ㄥ悎鐞嗙殑榛樿鍊? 涓轟綘鐪佸幓浜嗘墜宸ユ寚瀹氬畠浠殑鍔熷か.

琛?nbsp;4.8.  Hibernate SQL鏂硅█ (hibernate.dialect)

RDBMS 鏂硅█
DB2 org.hibernate.dialect.DB2Dialect
DB2 AS/400 org.hibernate.dialect.DB2400Dialect
DB2 OS390 org.hibernate.dialect.DB2390Dialect
PostgreSQL org.hibernate.dialect.PostgreSQLDialect
MySQL org.hibernate.dialect.MySQLDialect
MySQL with InnoDB org.hibernate.dialect.MySQLInnoDBDialect
MySQL with MyISAM org.hibernate.dialect.MySQLMyISAMDialect
Oracle (any version) org.hibernate.dialect.OracleDialect
Oracle 9i/10g org.hibernate.dialect.Oracle9Dialect
Sybase org.hibernate.dialect.SybaseDialect
Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect
Microsoft SQL Server org.hibernate.dialect.SQLServerDialect
SAP DB org.hibernate.dialect.SAPDBDialect
Informix org.hibernate.dialect.InformixDialect
HypersonicSQL org.hibernate.dialect.HSQLDialect
Ingres org.hibernate.dialect.IngresDialect
Progress org.hibernate.dialect.ProgressDialect
Mckoi SQL org.hibernate.dialect.MckoiDialect
Interbase org.hibernate.dialect.InterbaseDialect
Pointbase org.hibernate.dialect.PointbaseDialect
FrontBase org.hibernate.dialect.FrontbaseDialect
Firebird org.hibernate.dialect.FirebirdDialect

4.4.2.  澶栬繛鎺ユ姄鍙?Outer Join Fetching)

濡傛灉浣犵殑鏁版嵁搴撴敮鎸丄NSI, Oracle鎴朣ybase椋庢牸鐨勫榪炴帴, 澶栬繛鎺ユ姄鍙?/EM>甯歌兘閫氳繃闄愬埗寰榪旀暟鎹簱嬈℃暟 (鏇村鐨勫伐浣滀氦鐢辨暟鎹簱鑷繁鏉ュ畬鎴?鏉ユ彁楂樻晥鐜? 澶栬繛鎺ュ厑璁稿湪鍗曚釜SELECTSQL璇彞涓紝 閫氳繃many-to-one, one-to-many, many-to-many鍜宱ne-to-one鍏寵仈鑾峰彇榪炴帴瀵硅薄鐨勬暣涓璞″浘.

灝?TT class=literal>hibernate.max_fetch_depth璁句負0鑳藉湪鍏ㄥ眬 鑼冨洿鍐呯姝㈠榪炴帴鎶撳彇. 璁句負1鎴栨洿楂樺艱兘鍚敤one-to-one鍜宮any-to-oneouter鍏寵仈鐨勫榪炴帴鎶撳彇, 瀹冧滑閫氳繃 fetch="join"鏉ユ槧灝?

鍙傝絎?nbsp;20.1 鑺?鈥?鎶撳彇絳栫暐(Fetching strategies) 鈥?/A>鑾峰緱鏇村淇℃伅.

4.4.3.  浜岃繘鍒舵祦 (Binary Streams)

Oracle闄愬埗閭d簺閫氳繃JDBC椹卞姩浼犺緭鐨?TT class=literal>瀛楄妭鏁扮粍鐨勬暟鐩? 濡傛灉浣犲笇鏈涗嬌鐢?TT class=literal>浜岃繘鍊?(binary)鎴?鍙簭鍒楀寲鐨?(serializable)綾誨瀷鐨勫ぇ瀵硅薄, 浣犲簲璇ュ紑鍚?hibernate.jdbc.use_streams_for_binary灞炴? 榪欐槸緋葷粺綰у睘鎬?

4.4.4.  浜岀駭緙撳瓨涓庢煡璇㈢紦瀛?

浠?TT class=literal>hibernate.cache涓哄墠緙鐨勫睘鎬у厑璁鎬綘鍦℉ibernate涓紝浣跨敤榪涚▼鎴栫兢闆嗚寖鍥村唴鐨勪簩綰х紦瀛樼郴緇? 鍙傝絎?nbsp;20.2 鑺?鈥滀簩綰х紦瀛橈紙The Second Level Cache錛?鈥?/A>鑾峰彇鏇村鐨勮鎯?

4.4.5.  鏌ヨ璇█涓殑鏇挎崲

浣犲彲浠ヤ嬌鐢?TT class=literal>hibernate.query.substitutions鍦℉ibernate涓畾涔夋柊鐨勬煡璇㈢鍙? 渚嬪:

hibernate.query.substitutions true=1, false=0

灝嗗鑷寸鍙?TT class=literal>true鍜?TT class=literal>false鍦ㄧ敓鎴愮殑SQL涓緲昏瘧鎴愭暣鏁板父閲?

hibernate.query.substitutions toLowercase=LOWER

灝嗗厑璁鎬綘閲嶅懡鍚峉QL涓殑LOWER鍑芥暟.

4.4.6.  Hibernate鐨勭粺璁?statistics)鏈哄埗

濡傛灉浣犲紑鍚?TT class=literal>hibernate.generate_statistics, 閭d箞褰撲綘閫氳繃 SessionFactory.getStatistics()璋冩暣姝e湪榪愯鐨勭郴緇熸椂錛孒ibernate灝嗗鍑哄ぇ閲忔湁鐢ㄧ殑鏁版嵁. Hibernate鐢氳嚦鑳借閰嶇疆鎴愰氳繃JMX瀵煎嚭榪欎簺緇熻淇℃伅. 鍙傝?TT class=literal>org.hibernate.stats涓帴鍙g殑Javadoc錛屼互鑾峰緱鏇村淇℃伅.

4.5.  鏃ュ織

Hibernate浣跨敤Apache commons-logging鏉ヤ負鍚勭浜嬩歡璁板綍鏃ュ織.

commons-logging灝嗙洿鎺ヨ緭鍑哄埌Apache Log4j(濡傛灉鍦ㄧ被璺緞涓寘鎷?TT class=literal>log4j.jar)鎴?JDK1.4 logging (濡傛灉榪愯鍦↗DK1.4鎴栦互涓婄殑鐜涓?. 浣犲彲浠ヤ粠http://jakarta.apache.org 涓嬭澆Log4j. 瑕佷嬌鐢↙og4j錛屼綘闇瑕佸皢log4j.properties鏂囦歡鏀劇疆鍦ㄧ被璺緞涓? 闅廐ibernate 涓鍚屽垎鍙戠殑鏍蜂緥灞炴ф枃浠跺湪src/鐩綍涓?

鎴戜滑寮虹儓寤鴻浣犵啛鎮変竴涓婬ibernate鐨勬棩蹇楁秷鎭? 鍦ㄤ笉澶卞彲璇繪х殑鍓嶆彁涓嬶紝 鎴戜滑鍋氫簡寰堝宸ヤ綔錛屼嬌Hibernate鐨勬棩蹇楀彲鑳藉湴璇︾粏. 榪欐槸蹇呰鐨勬煡閿欏埄鍣? 鏈浠や漢鎰熷叴瓚g殑鏃ュ織鍒嗙被鏈夊涓嬭繖浜?

琛?nbsp;4.9.  Hibernate鏃ュ織綾誨埆

綾誨埆 鍔熻兘
org.hibernate.SQL 鍦ㄦ墍鏈塖QL DML璇彞琚墽琛屾椂涓哄畠浠褰曟棩蹇?
org.hibernate.type 涓烘墍鏈塉DBC鍙傛暟璁板綍鏃ュ織
org.hibernate.tool.hbm2ddl 鍦ㄦ墍鏈塖QL DDL璇彞鎵ц鏃朵負瀹冧滑璁板綍鏃ュ織
org.hibernate.pretty 鍦╯ession娓呮礂(flush)鏃訛紝涓烘墍鏈変笌鍏跺叧鑱旂殑瀹炰綋(鏈澶?0涓?鐨勭姸鎬佽褰曟棩蹇?
org.hibernate.cache 涓烘墍鏈変簩綰х紦瀛樼殑媧誨姩璁板綍鏃ュ織
org.hibernate.transaction 涓轟簨鍔$浉鍏崇殑媧誨姩璁板綍鏃ュ織
org.hibernate.jdbc 涓烘墍鏈塉DBC璧勬簮鐨勮幏鍙栬褰曟棩蹇?
org.hibernate.hql.ast 涓篐QL鍜孲QL鐨勮嚜鍔ㄧ姸鎬佽漿鎹㈠拰鍏朵粬鍏充簬鏌ヨ瑙f瀽鐨勪俊鎭褰曟棩蹇?
org.hibernate.secure 涓篔AAS璁よ瘉璇鋒眰鍋氭棩蹇?
org.hibernate 涓轟換浣旽ibernate鐩稿叧淇℃伅鍋氭棩蹇?(淇℃伅閲忚緝澶? 浣嗗鏌ラ敊闈炲父鏈夊府鍔?

鍦ㄤ嬌鐢℉ibernate寮鍙戝簲鐢ㄧ▼搴忔椂, 浣犲簲褰撴繪槸涓?TT class=literal>org.hibernate.SQL 寮鍚?TT class=literal>debug綰у埆鐨勬棩蹇楄褰?鎴栬呭紑鍚?TT class=literal>hibernate.show_sql灞炴ф潵浠f浛瀹冦?

4.6.  瀹炵幇NamingStrategy

org.hibernate.cfg.NamingStrategy鎺ュ彛鍏佽浣犱負鏁版嵁搴撲腑鐨勫璞″拰schema 鍏冪礌鎸囧畾涓涓滃懡鍚嶆爣鍑嗏?

浣犲彲鑳戒細鎻愪緵涓浜涢氳繃Java鏍囪瘑鐢熸垚鏁版嵁搴撴爣璇嗘垨灝嗘槧灝勫畾涔夋枃浠朵腑"閫昏緫"琛?鍒楀悕澶勭悊鎴?鐗╃悊"琛?鍒楀悕鐨勮鍒? 榪欎釜鐗規ф湁鍔╀簬鍑忓皯鍐楅暱鐨勬槧灝勫畾涔夋枃浠?

鍦ㄥ姞鍏ユ槧灝勫畾涔夊墠錛屼綘鍙互璋冪敤 Configuration.setNamingStrategy()鎸囧畾涓涓笉鍚岀殑鍛藉悕絳栫暐:

SessionFactory sf = new Configuration()
    .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
    .addFile("Item.hbm.xml")
    .addFile("Bid.hbm.xml")
    .buildSessionFactory();

org.hibernate.cfg.ImprovedNamingStrategy鏄竴涓唴寤虹殑鍛藉悕絳栫暐, 瀵?涓浜涘簲鐢ㄧ▼搴忚岃█錛屽彲鑳芥槸闈炲父鏈夌敤鐨勮搗鐐?

4.7.  XML閰嶇疆鏂囦歡

鍙︿竴涓厤緗柟娉曟槸鍦?TT class=literal>hibernate.cfg.xml鏂囦歡涓寚瀹氫竴濂楀畬鏁寸殑閰嶇疆. 榪欎釜鏂囦歡鍙互褰撴垚hibernate.properties鐨勬浛浠c?鑻ヤ袱涓枃浠跺悓鏃跺瓨鍦紝瀹冨皢閲嶈澆鍓嶈呯殑灞炴?

XML閰嶇疆鏂囦歡琚粯璁ゆ槸鏀懼湪CLASSPATH鐨勬牴鐩綍涓? 榪欐槸涓涓緥瀛?

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <!-- 浠?jndi/name緇戝畾鍒癑NDI鐨凷essionFactory瀹炰緥 -->
    <session-factory
        name="java:hibernate/SessionFactory">

        <!-- 灞炴?-->
        <property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="show_sql">false</property>
        <property name="transaction.factory_class">
            org.hibernate.transaction.JTATransactionFactory
        </property>
        <property name="jta.UserTransaction">java:comp/UserTransaction</property>

        <!-- 鏄犲皠瀹氫箟鏂囦歡 -->
        <mapping resource="org/hibernate/auction/Item.hbm.xml"/>
        <mapping resource="org/hibernate/auction/Bid.hbm.xml"/>

        <!-- 緙撳瓨璁劇疆 -->
        <class-cache class="org.hibernate.auction.Item" usage="read-write"/>
        <class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
        <collection-cache class="org.hibernate.auction.Item.bids" usage="read-write"/>

    </session-factory>

</hibernate-configuration>

濡備綘鎵瑙? 榪欎釜鏂規硶浼樺娍鍦ㄤ簬錛屽湪閰嶇疆鏂囦歡涓寚鍑轟簡鏄犲皠瀹氫箟鏂囦歡鐨勫悕瀛? 涓鏃︿綘闇瑕佽皟鏁碒ibernate鐨勭紦瀛橈紝 hibernate.cfg.xml涔熸槸鏇存柟渚? 娉ㄦ剰錛屼嬌鐢?TT class=literal>hibernate.properties榪樻槸 hibernate.cfg.xml瀹屽叏鏄敱浣犳潵鍐沖畾, 闄や簡涓婇潰鎻愬埌鐨刋ML璇硶鐨勪紭鍔夸箣澶? 涓よ呮槸絳変環鐨?

浣跨敤XML閰嶇疆錛屼嬌寰楀惎鍔℉ibernate鍙樼殑寮傚父綆鍗? 濡備笅鎵紺猴紝涓琛屼唬鐮佸氨鍙互鎼炲畾錛?

SessionFactory sf = new Configuration().configure().buildSessionFactory();

浣犲彲浠ヤ嬌鐢ㄥ涓嬩唬鐮佹潵娣誨姞涓涓笉鍚岀殑XML閰嶇疆鏂囦歡

SessionFactory sf = new Configuration()
    .configure("catdb.cfg.xml")
    .buildSessionFactory();

4.8.  J2EE搴旂敤紼嬪簭鏈嶅姟鍣ㄧ殑闆嗘垚

閽堝J2EE浣撶郴,Hibernate鏈夊涓嬪嚑涓泦鎴愮殑鏂歸潰:

  • 瀹瑰櫒綆$悊鐨勬暟鎹簮(Container-managed datasources): Hibernate鑳介氳繃瀹瑰櫒綆$悊鐢盝NDI鎻愪緵鐨凧DBC榪炴帴. 閫氬父, 鐗瑰埆鏄綋澶勭悊澶氫釜鏁版嵁婧愮殑鍒嗗竷寮忎簨鍔$殑鏃跺? 鐢變竴涓狫TA鍏煎鐨?TT class=literal>TransactionManager鍜屼竴涓?ResourceManager鏉ュ鐞嗕簨鍔$鐞?CMT, 瀹瑰櫒綆$悊鐨勪簨鍔?. 褰撶劧浣犲彲浠ラ氳繃 緙栫▼鏂瑰紡鏉ュ垝鍒嗕簨鍔¤竟鐣?BMT, Bean綆$悊鐨勪簨鍔?. 鎴栬呬負浜嗕唬鐮佺殑鍙Щ妞嶆э紝浣犱篃涔熻浼氭兂浣跨敤鍙夌殑 Hibernate Transaction API.

  • 鑷姩JNDI緇戝畾: Hibernate鍙互鍦ㄥ惎鍔ㄥ悗灝?SessionFactory緇戝畾鍒癑NDI.

  • JTA Session緇戝畾: 濡傛灉浣跨敤EJB, Hibernate Session 鍙互鑷姩緇戝畾鍒癑TA浜嬪姟浣滅敤鐨勮寖鍥? 鍙渶綆鍗曞湴浠嶫NDI鏌ユ壘SessionFactory騫惰幏寰楀綋鍓嶇殑 Session. 褰揓TA浜嬪姟瀹屾垚鏃? 璁〩ibernate鏉ュ鐞?Session鐨勬竻媧?flush)涓庡叧闂? 鍦‥JB鐨勯儴緗叉弿榪扮涓簨鍔¤竟鐣屾槸澹版槑寮忕殑.

  • JMX閮ㄧ講: 濡傛灉浣犱嬌鐢ㄦ敮鎸丣MX搴旂敤紼嬪簭鏈嶅姟鍣?濡? JBoss AS), 閭d箞浣犲彲浠ラ夋嫨灝咹ibernate閮ㄧ講鎴愭墭綆Bean. 榪欏皢涓轟綘鐪佸幓涓琛屼粠Configuration鏋勫緩SessionFactory鐨勫惎鍔ㄤ唬鐮? 瀹瑰櫒灝嗗惎鍔ㄤ綘鐨?TT class=literal>HibernateService, 騫跺畬緹庡湴澶勭悊濂芥湇鍔¢棿鐨勪緷璧栧叧緋?(鍦℉ibernate鍚姩鍓嶏紝鏁版嵁婧愬繀欏繪槸鍙敤鐨勭瓑絳?.

濡傛灉搴旂敤紼嬪簭鏈嶅姟鍣ㄦ姏鍑?connection containment"寮傚父, 鏍規嵁浣犵殑鐜錛屼篃璁歌灝嗛厤緗睘鎬?hibernate.connection.release_mode璁句負after_statement.

4.8.1.  浜嬪姟絳栫暐閰嶇疆

鍦ㄤ綘鐨勬灦鏋勪腑錛孒ibernate鐨?TT class=literal>Session API鏄嫭绔嬩簬浠諱綍浜嬪姟鍒嗙晫緋葷粺鐨? 濡傛灉浣犺Hibernate閫氳繃榪炴帴姹犵洿鎺ヤ嬌鐢↗DBC, 浣犻渶瑕佽皟鐢↗DBC API鏉ユ墦寮鍜屽叧闂綘鐨勪簨鍔? 濡傛灉浣犺繍琛屽湪J2EE搴旂敤紼嬪簭鏈嶅姟鍣ㄤ腑, 浣犱篃璁告兂鐢˙ean綆$悊鐨勪簨鍔″茍鍦ㄩ渶瑕佺殑鏃跺欒皟鐢↗TA API鍜?TT class=literal>UserTransaction.

涓轟簡璁╀綘鐨勪唬鐮佸湪涓ょ(鎴栧叾浠?鐜涓彲浠ョЩ妞嶏紝鎴戜滑寤鴻浣跨敤鍙夌殑Hibernate Transaction API, 瀹冨寘瑁呭茍闅愯棌浜嗗簳灞傜郴緇? 浣犲繀欏婚氳繃璁劇疆Hibernate閰嶇疆灞炴?TT class=literal>hibernate.transaction.factory_class鏉ユ寚瀹?涓涓?TT class=literal>Transaction瀹炰緥鐨勫伐鍘傜被.

瀛樺湪鐫涓変釜鏍囧噯(鍐呭緩)鐨勯夋嫨:

org.hibernate.transaction.JDBCTransactionFactory

濮旀墭緇欐暟鎹簱(JDBC)浜嬪姟錛堥粯璁わ級

org.hibernate.transaction.JTATransactionFactory

濡傛灉鍦ㄤ笂涓嬫枃鐜涓瓨鍦ㄨ繍琛岀潃鐨勪簨鍔?濡? EJB浼氳瘽Bean鐨勬柟娉?, 鍒欏鎵樼粰瀹瑰櫒綆?鐞嗙殑浜嬪姟, 鍚﹀垯錛屽皢鍚姩涓涓柊鐨勪簨鍔★紝騫朵嬌鐢˙ean綆$悊鐨勪簨鍔?

org.hibernate.transaction.CMTTransactionFactory

濮旀墭緇欏鍣ㄧ鐞嗙殑JTA浜嬪姟

浣犱篃鍙互瀹氫箟灞炰簬浣犺嚜宸辯殑浜嬪姟絳栫暐 (濡? 閽堝CORBA鐨勪簨鍔℃湇鍔?

Hibernate鐨勪竴浜涚壒鎬?(鍗充簩綰х紦瀛? JTA涓嶴ession鐨勮嚜鍔ㄧ粦瀹氱瓑絳?闇瑕佽闂湪鎵樼鐜涓殑JTA TransactionManager. 鐢變簬J2EE娌℃湁鏍囧噯鍖栦竴涓崟涓鐨勬満鍒?Hibernate鍦ㄥ簲鐢ㄧ▼搴忔湇鍔″櫒涓紝浣犲繀欏繪寚瀹欻ibernate濡備綍鑾峰緱TransactionManager鐨勫紩鐢?

琛?nbsp;4.10. JTA TransactionManagers

Transaction宸ュ巶綾? 搴旂敤紼嬪簭鏈嶅姟鍣?
org.hibernate.transaction.JBossTransactionManagerLookup JBoss
org.hibernate.transaction.WeblogicTransactionManagerLookup Weblogic
org.hibernate.transaction.WebSphereTransactionManagerLookup WebSphere
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup WebSphere 6
org.hibernate.transaction.OrionTransactionManagerLookup Orion
org.hibernate.transaction.ResinTransactionManagerLookup Resin
org.hibernate.transaction.JOTMTransactionManagerLookup JOTM
org.hibernate.transaction.JOnASTransactionManagerLookup JOnAS
org.hibernate.transaction.JRun4TransactionManagerLookup JRun4
org.hibernate.transaction.BESTransactionManagerLookup Borland ES

4.8.2.  JNDI緇戝畾鐨?TT class=literal>SessionFactory

涓嶫NDI緇戝畾鐨凥ibernate鐨?TT class=literal>SessionFactory鑳界畝鍖栧伐鍘傜殑鏌ヨ錛岀畝鍖栧垱寤烘柊鐨?TT class=literal>Session. 闇瑕佹敞鎰忕殑鏄繖涓嶫NDI緇戝畾Datasource娌℃湁鍏崇郴, 瀹冧滑鍙槸鎭板閥鐢ㄤ簡鐩稿悓鐨勬敞鍐岃〃!

濡傛灉浣犲笇鏈涘皢SessionFactory緇戝畾鍒頒竴涓狫NDI鐨勫悕瀛楃┖闂? 鐢ㄥ睘鎬?TT class=literal>hibernate.session_factory_name鎸囧畾涓涓悕瀛?濡? java:hibernate/SessionFactory). 濡傛灉涓嶈緗繖涓睘鎬? SessionFactory灝嗕笉浼氳緇戝畾鍒癑NDI涓? (鍦ㄤ互鍙JNDI涓洪粯璁ゅ疄鐜扮殑鐜涓紝榪欎釜璁劇疆灝ゅ叾鏈夌敤, 濡俆omcat.)

鍦ㄥ皢SessionFactory緇戝畾鑷矹NDI鏃? Hibernate灝嗕嬌鐢?TT class=literal>hibernate.jndi.url, 鍜?TT class=literal>hibernate.jndi.class鐨勫兼潵瀹炰緥鍖栧垵濮嬬幆澧?initial context). 濡傛灉瀹冧滑娌℃湁琚寚瀹? 灝嗕嬌鐢ㄩ粯璁ょ殑InitialContext.

鍦ㄤ綘璋冪敤cfg.buildSessionFactory()鍚? Hibernate浼氳嚜鍔ㄥ皢SessionFactory娉ㄥ唽鍒癑NDI. 榪欐剰鍛寵繖浣犺嚦灝戦渶瑕佸湪浣犲簲鐢ㄧ▼搴忕殑鍚姩浠g爜(鎴栧伐鍏風被)涓畬鎴愯繖涓皟鐢? 闄ら潪浣犱嬌鐢?TT class=literal>HibernateService鏉ュ仛JMX閮ㄧ講 (瑙佸悗闈㈣璁?.

濡傛灉浣犱嬌鐢ㄤ笌JNDI緇戝畾鐨?TT class=literal>SessionFactory, EJB鎴栦換浣曞叾浠栫被鍙互閫氳繃涓涓狫NDI鏌ヨ鏉ヨ幏寰楄繖涓?TT class=literal>SessionFactory. 璇鋒敞鎰? 濡傛灉浣犱嬌鐢ㄧ涓绔犱腑浠嬬粛鐨勫府鍔╃被HibernateUtil - 綾諱技Singleton(鍗曞疄渚?娉ㄥ唽琛? 閭d箞榪欓噷鐨勫惎鍔ㄤ唬鐮佷笉鏄繀瑕佺殑. 浣?TT class=literal>HibernateUtil鏇村琚嬌鐢ㄥ湪闈炴墭綆$幆澧冧腑.

4.8.3.  JTA鍜孲ession鐨勮嚜鍔ㄧ粦瀹?

鍦ㄩ潪鎵樼鐜涓紝鎴戜滑寤鴻錛?TT class=literal>HibernateUtil鍜岄潤鎬?TT class=literal>SessionFactory涓璧峰伐浣滐紝 鐢?TT class=literal>ThreadLocal綆$悊Hibernate Session銆?鐢變簬涓浜汦JB鍙兘浼氳繍琛屽湪鍚屼竴涓簨鍔′絾涓嶅悓綰跨▼鐨勭幆澧冧腑, 鎵浠ヨ繖涓柟娉曚笉鑳界収鎼埌EJB鐜涓? 鎴戜滑寤鴻鍦ㄦ墭綆$幆澧冧腑錛屽皢SessionFactory緇戝畾鍒癑NDI涓?

璇蜂嬌鐢?TT class=literal>SessionFactory鐨?TT class=literal>getCurrentSession()鏂規硶鏉ヤ唬鏇?鐩存帴浣跨敤ThreadLocal鍘昏幏寰桯ibernate Session. 濡傛灉鍦ㄥ綋鍓岼TA浜嬪姟涓病鏈塇ibernate Session, 灝嗕細鍚姩涓涓茍灝嗗畠鍏寵仈鍒頒簨鍔′腑. 瀵逛簬浣跨敤getCurrentSession()鑾峰緱鐨勬瘡涓?TT class=literal>Session鑰岃█錛?hibernate.transaction.flush_before_completion 鍜?TT class=literal>hibernate.transaction.auto_close_session榪欎袱涓厤緗夐」浼氳嚜鍔ㄨ緗? 鍥犳鍦ㄥ鍣ㄧ粨鏉烰TA浜嬪姟鏃訛紝榪欎簺Session浼氳鑷姩娓呮礂(flush)騫跺叧闂?

渚嬪錛屽鏋滀綘浣跨敤DAO妯″紡鏉ョ紪鍐欎綘鐨勬寔涔呭眰, 閭d箞鍦ㄩ渶瑕佹椂錛屾墍鏈塂AO灝嗘煡鎵?TT class=literal>SessionFactory騫舵墦寮"褰撳墠"Session. 娌℃湁蹇呰鍦ㄦ帶鍒朵唬鐮佸拰DAO浠g爜闂翠紶閫?TT class=literal>SessionFactory鎴?TT class=literal>Session鐨勫疄渚?

4.8.4.  JMX閮ㄧ講

涓轟簡灝?TT class=literal>SessionFactory娉ㄥ唽鍒癑NDI涓?TT class=literal>cfg.buildSessionFactory()榪欒浠g爜浠嶉渶鍦ㄦ煇澶勮鎵ц. 浣犲彲鍦ㄤ竴涓?TT class=literal>static鍒濆鍖栧潡(鍍?TT class=literal>HibernateUtil涓殑閭f牱)涓墽琛屽畠鎴栧皢Hibernate閮ㄧ講涓轟竴涓?SPAN class=emphasis>鎵樼鐨勬湇鍔?/EM>.

涓轟簡閮ㄧ講鍦ㄤ竴涓敮鎸丣MX鐨勫簲鐢ㄧ▼搴忔湇鍔″櫒涓婏紝Hibernate鍜?org.hibernate.jmx.HibernateService涓鍚屽垎鍙戯紝濡侸boss AS銆?瀹為檯鐨勯儴緗插拰閰嶇疆鏄敱搴旂敤紼嬪簭鏈嶅姟鍣ㄦ彁渚涜呮寚瀹氱殑. 榪欓噷鏄疛Boss 4.0.x鐨?TT class=literal>jboss-service.xml鏍蜂緥:

<?xml version="1.0"?>
<server>

<mbean code="org.hibernate.jmx.HibernateService"
    name="jboss.jca:service=HibernateFactory,name=HibernateFactory">

    <!-- 蹇呴』鐨勬湇鍔?-->
    <depends>jboss.jca:service=RARDeployer</depends>
    <depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>

    <!-- 灝咹ibernate鏈嶅姟緇戝畾鍒癑NDI -->
    <attribute name="JndiName">java:/hibernate/SessionFactory</attribute>

    <!-- 鏁版嵁婧愯緗?-->
    <attribute name="Datasource">java:HsqlDS</attribute>
    <attribute name="Dialect">org.hibernate.dialect.HSQLDialect</attribute>

    <!-- 浜嬪姟闆嗘垚 -->
    <attribute name="TransactionStrategy">
        org.hibernate.transaction.JTATransactionFactory</attribute>
    <attribute name="TransactionManagerLookupStrategy">
        org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
    <attribute name="FlushBeforeCompletionEnabled">true</attribute>
    <attribute name="AutoCloseSessionEnabled">true</attribute>

    <!-- 鎶撳彇閫夐」 -->
    <attribute name="MaximumFetchDepth">5</attribute>

    <!-- 浜岀駭緙撳瓨 -->
    <attribute name="SecondLevelCacheEnabled">true</attribute>
    <attribute name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
    <attribute name="QueryCacheEnabled">true</attribute>

    <!-- 鏃ュ織 -->
    <attribute name="ShowSqlEnabled">true</attribute>

    <!-- 鏄犲皠瀹氫箟鏂囦歡 -->
    <attribute name="MapResources">auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>

</mbean>

</server>

榪欎釜鏂囦歡鏄儴緗插湪META-INF鐩綍涓嬬殑, 騫朵細琚墦鍖呭埌浠?TT class=literal>.sar (service archive)涓烘墿灞曞悕鐨凧AR鏂囦歡涓? 鍚屾椂錛屼綘闇瑕佹墦鍖匟ibernate, 瀹冩墍闇瑕佺殑絎笁鏂瑰簱, 浣犵紪璇戝ソ鐨勬寔涔呭寲綾誨強浣犵殑鏄犲皠瀹氫箟鏂囦歡鎵撳寘榪涘悓涓涓枃妗? 浣犵殑浼佷笟Bean(涓鑸負浼氳瘽Bean)鍙兘浼氳鎵撳寘鎴愬畠浠嚜宸辯殑JAR鏂囦歡, 浣嗕綘涔熻浼氬皢EJB JAR鏂囦歡涓鍚屽寘鍚繘鑳界嫭绔?鐑?閮ㄧ講鐨勪富鏈嶅姟鏂囨。. 鍜ㄨJBoss AS鏂囨。浠ヤ簡瑙f洿澶氱殑JMX鏈嶅姟涓嶦JB閮ㄧ講鐨勪俊鎭?



R.Zeus 2005-08-08 12:55 鍙戣〃璇勮
]]>
主站蜘蛛池模板: 黄桃AV无码免费一区二区三区| 久久亚洲AV无码精品色午夜麻豆 | 国产产在线精品亚洲AAVV| 33333在线亚洲| 国产精品亚洲精品| 国产成人精品日本亚洲专区6| 亚洲欧洲精品国产区| 亚洲国产精品一区二区久| 亚洲乱码一二三四五六区| 亚洲午夜福利在线视频| 亚洲乱码日产精品一二三| 亚洲AV日韩综合一区| 特级毛片全部免费播放a一级| 特级做a爰片毛片免费看| 一出一进一爽一粗一大视频免费的 | 24小时免费直播在线观看| 最近免费中文字幕大全视频 | 女人让男人免费桶爽30分钟| 青草草在线视频永久免费| 精品国产一区二区三区免费看| 国产伦精品一区二区三区免费下载| 免费国产高清视频| 中文字幕亚洲综合久久男男| 亚洲国产精品国自产拍AV| 久久亚洲AV成人无码国产| 亚洲校园春色另类激情| 日韩色视频一区二区三区亚洲| 免费人成大片在线观看播放| 免费精品久久天干天干| 3344永久在线观看视频免费首页| 成人a视频片在线观看免费| 亚洲成网777777国产精品| 亚洲AV无码一区二区乱孑伦AS | 亚洲一区二区三区免费| 久久精品国产99精品国产亚洲性色| 久久久久亚洲精品日久生情| 国内精品久久久久影院亚洲 | 亚洲一区二区三区成人网站| 青青草97国产精品免费观看| 久久青草免费91观看| 在线免费观看a级片|