??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲高清专区日韩精品,jlzzjlzz亚洲乱熟在线播放,亚洲精品无码永久中文字幕http://www.tkk7.com/zhujiang001/category/10572.htmlzh-cnFri, 02 Mar 2007 07:44:04 GMTFri, 02 Mar 2007 07:44:04 GMT60使用J2SE APIdProperties文g的六U方?/title><link>http://www.tkk7.com/zhujiang001/articles/43787.html</link><dc:creator>孤酷伶仃</dc:creator><author>孤酷伶仃</author><pubDate>Fri, 28 Apr 2006 03:46:00 GMT</pubDate><guid>http://www.tkk7.com/zhujiang001/articles/43787.html</guid><wfw:comment>http://www.tkk7.com/zhujiang001/comments/43787.html</wfw:comment><comments>http://www.tkk7.com/zhujiang001/articles/43787.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/zhujiang001/comments/commentRss/43787.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/zhujiang001/services/trackbacks/43787.html</trackback:ping><description><![CDATA[1。用java.util.Propertiescȝload()Ҏ(gu)<br />CZQ?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)I(yng)nputStream in = lnew BufferedInputStream(new FileInputStream(name));<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Properties p = new Properties();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)p.load(in);<br /><p>2。用java.util.ResourceBundlecȝgetBundle()Ҏ(gu)<br />CZQ?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)ResourceBundle rb = ResourceBundle.getBundle(name, Locale.getDefault());</p><p>3。用java.util.PropertyResourceBundlecȝ构造函?br />CZQ?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)I(yng)nputStream in = new BufferedInputStream(new FileInputStream(name));<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)ResourceBundle rb = new PropertyResourceBundle(in);</p><p>4。用class变量的getResourceAsStream()Ҏ(gu)<br />CZQ?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)I(yng)nputStream in = JProperties.class.getResourceAsStream(name);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Properties p = new Properties();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)p.load(in);</p><p>5。用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()Ҏ(gu)<br />CZQ?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)I(yng)nputStream in = JProperties.class.getClassLoader().getResourceAsStream(name);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Properties p = new Properties();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)p.load(in);</p><p>6。用java.lang.ClassLoadercȝgetSystemResourceAsStream()?rn)态方?br />CZQ?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)I(yng)nputStream in = ClassLoader.getSystemResourceAsStream(name);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Properties p = new Properties();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)p.load(in);</p><p>补充</p><p>Servlet中可以用javax.servlet.ServletContext的getResourceAsStream()Ҏ(gu)<br />CZQ?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)I(yng)nputStream in = context.getResourceAsStream(path);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Properties p = new Properties();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)p.load(in);<br /><br /><font color="#0000ff">完整的示例,可以参考附件文?/font><br /><font color="#0000ff">JProperties.java文g<br /><font color="#008080">/**<br />** This program is free software.<br />** <br />** You may redistribute it and/or modify it under the terms of the GNU<br />** General Public License as published by the Free Software Foundation.<br />** Version 2 of the license should be included with this distribution in<br />** the file LICENSE, as well as License.html. If the license is not<br />** included with this distribution, you may find a copy at the FSF web<br />** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the<br />** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.<br />**<br />** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,<br />** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR<br />** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY<br />** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR<br />** REDISTRIBUTION OF THIS SOFTWARE. <br />**/</font></font></p><p>package com.kindani;</p><p>//import javax.servlet.ServletContext;<br />import java.util.*;<br />import java.io.InputStream;<br />import java.io.IOException;<br />import java.io.BufferedInputStream;<br />import java.io.FileInputStream;</p><p><font color="#008080">/**<br /> (tng)* 使用J2SE API読取Properties文g的六E方?br /> (tng)* User: SYNFORM<br /> (tng)* Date: 2005/07/12<br /> (tng)* Time: 18:40:55<br /> (tng)* To change this template use File | Settings | File Templates.<br /> (tng)*/</font><br />public class JProperties {</p><p> (tng) (tng) (tng) public final static int BY_PROPERTIES = 1;<br /> (tng) (tng) (tng) public final static int BY_RESOURCEBUNDLE = 2;<br /> (tng) (tng) (tng) public final static int BY_PROPERTYRESOURCEBUNDLE = 3;<br /> (tng) (tng) (tng) public final static int BY_CLASS = 4;<br /> (tng) (tng) (tng) public final static int BY_CLASSLOADER = 5;<br /> (tng) (tng) (tng) public final static int BY_SYSTEM_CLASSLOADER = 6;</p><p> (tng) (tng) (tng) public final static Properties loadProperties(final String name, final int type) throws IOException {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) Properties p = new Properties();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) InputStream in = null;<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) if (type == BY_PROPERTIES) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) in = new BufferedInputStream(new FileInputStream(name));<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) assert (in != null);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) p.load(in);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) } else if (type == BY_RESOURCEBUNDLE) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) ResourceBundle rb = ResourceBundle.getBundle(name, Locale.getDefault());<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) assert (rb != null);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) p = new ResourceBundleAdapter(rb);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) } else if (type == BY_PROPERTYRESOURCEBUNDLE) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) in = new BufferedInputStream(new FileInputStream(name));<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) assert (in != null);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) ResourceBundle rb = new PropertyResourceBundle(in);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) p = new ResourceBundleAdapter(rb);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) } else if (type == BY_CLASS) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) assert (JProperties.class.equals(new JProperties().getClass()));<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) in = JProperties.class.getResourceAsStream(name);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) assert (in != null);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) p.load(in);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) // (tng) (tng) (tng) (tng) (tng) (tng) (tng) return new JProperties().getClass().getResourceAsStream(name);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) } else if (type == BY_CLASSLOADER) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) assert (JProperties.class.getClassLoader().equals(new JProperties().getClass().getClassLoader()));<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) in = JProperties.class.getClassLoader().getResourceAsStream(name);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) assert (in != null);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) p.load(in);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) // (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) return new JProperties().getClass().getClassLoader().getResourceAsStream(name);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) } else if (type == BY_SYSTEM_CLASSLOADER) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) in = ClassLoader.getSystemResourceAsStream(name);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) assert (in != null);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) p.load(in);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) if (in != null) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) in.close();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) return p;</p><p> (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) // ---------------------------------------------- servlet used<br />/*<br /> (tng) (tng) (tng) public static Properties loadProperties(ServletContext context, String path) throws IOException {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) assert (context != null);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) InputStream in = context.getResourceAsStream(path);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) assert (in != null);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) Properties p = new Properties();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) p.load(in);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) in.close();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) return p;<br /> (tng) (tng) (tng) }<br />*/</p><p> (tng) (tng) (tng) // ---------------------------------------------- support class</p><p> (tng) (tng) (tng) /**<br /> (tng) (tng) (tng) (tng) * ResourceBundle Adapter class.<br /> (tng) (tng) (tng) (tng) */<br /> (tng) (tng) (tng) public static class ResourceBundleAdapter extends Properties {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) public ResourceBundleAdapter(ResourceBundle rb) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) assert (rb instanceof java.util.PropertyResourceBundle);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) this.rb = rb;<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) java.util.Enumeration e = rb.getKeys();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) while (e.hasMoreElements()) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Object o = e.nextElement();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) this.put(o, rb.getObject((String) o));<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) }<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) private ResourceBundle rb = null;</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) public ResourceBundle getBundle(String baseName) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) return ResourceBundle.getBundle(baseName);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) public ResourceBundle getBundle(String baseName, Locale locale) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) return ResourceBundle.getBundle(baseName, locale);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) public ResourceBundle getBundle(String baseName, Locale locale, ClassLoader loader) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) return ResourceBundle.getBundle(baseName, locale, loader);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) public Enumeration<String> getKeys() {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) return rb.getKeys();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) public Locale getLocale() {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) return rb.getLocale();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) public Object getObject(String key) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) return rb.getObject(key);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) public String getString(String key) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) return rb.getString(key);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) public String[] getStringArray(String key) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) return rb.getStringArray(key);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) protected Object handleGetObject(String key) {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) return ((PropertyResourceBundle) rb).handleGetObject(key);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }</p><p> (tng) (tng) (tng) }</p><p>}<br /><br /><br /><font color="#0000ff">JPropertiesTest.java文g</font><br /><br /><font color="#008080">/**<br />** This program is free software.<br />** <br />** You may redistribute it and/or modify it under the terms of the GNU<br />** General Public License as published by the Free Software Foundation.<br />** Version 2 of the license should be included with this distribution in<br />** the file LICENSE, as well as License.html. If the license is not<br />** included with this distribution, you may find a copy at the FSF web<br />** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the<br />** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.<br />**<br />** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,<br />** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR<br />** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY<br />** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR<br />** REDISTRIBUTION OF THIS SOFTWARE. <br />**/<br /></font>package com.kindani.test;</p><p>import junit.framework.*;<br />import com.kindani.JProperties;</p><p>//import javax.servlet.ServletContext;<br />import java.util.Properties;</p><p>public class JPropertiesTest extends TestCase {<br /> (tng) (tng) (tng) JProperties jProperties;<br /> (tng) (tng) (tng) String key = "helloworld.title";<br /> (tng) (tng) (tng) String value = "Hello World!";</p><p> (tng) (tng) (tng) public void testLoadProperties() throws Exception {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) String name = null;<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) Properties p = new Properties();</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) name = "C:\\IDEAP\\Properties4Methods\\src\\com\\kindani\\test\\LocalStrings.properties";<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) p = JProperties.loadProperties(name, JProperties.BY_PROPERTIES);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) assertEquals(value, p.getProperty(key));</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) name = "com.kindani.test.LocalStrings";<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) p = JProperties.loadProperties(name,JProperties.BY_RESOURCEBUNDLE);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) assertEquals(value, p.getProperty(key));<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) assertEquals(value,((JProperties.ResourceBundleAdapter)p).getString(key));</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) name = "C:\\IDEAP\\Properties4Methods\\src\\com\\kindani\\test\\LocalStrings.properties";<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) p = JProperties.loadProperties(name, JProperties.BY_PROPERTYRESOURCEBUNDLE);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) assertEquals(value, p.getProperty(key));<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) assertEquals(value,((JProperties.ResourceBundleAdapter)p).getString(key));</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) name = "<a href="file://com//kindani//test//LocalStrings.properties">\\com\\kindani\\test\\LocalStrings.properties</a>";<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) p = JProperties.loadProperties(name, JProperties.BY_SYSTEM_CLASSLOADER);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) assertEquals(value, p.getProperty(key));</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) name = "<a href="file://com//kindani//test//LocalStrings.properties">\\com\\kindani\\test\\LocalStrings.properties</a>";<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) p = JProperties.loadProperties(name, JProperties.BY_CLASSLOADER);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) assertEquals(value, p.getProperty(key));</p><p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) name = "test\\LocalStrings.properties";<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) p = JProperties.loadProperties(name, JProperties.BY_CLASS);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) assertEquals(value, p.getProperty(key));<br /> (tng) (tng) (tng) }</p><p>/*<br /> (tng) (tng) (tng) public void testLoadProperties2() throws Exception {<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) ServletContext context = null;<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) String path = null;<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) Properties p = null;<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) path = "/WEB-INF/classes/LocalStrings.properties";<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) p = JProperties.loadProperties(context, path);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) assertEquals(value, p.getProperty(key));<br /> (tng) (tng) (tng) }<br />*/<br />}<br /><br /><font color="#0000ff">properties文g与JPropertiesTest.java文g相同的目录下<br />LocalStrings.properties文g</font><br /># $Id: LocalStrings.properties,v 1.1 2000/08/17 00:57:52 horwat Exp $</p><p># Default localized resources for example servlets<br /># This locale is en_US</p><p>helloworld.title=Hello World!</p><p>requestinfo.title=Request Information Example<br />requestinfo.label.method=Method:<br />requestinfo.label.requesturi=Request URI:<br />requestinfo.label.protocol=Protocol:<br />requestinfo.label.pathinfo=Path Info:<br />requestinfo.label.remoteaddr=Remote Address:</p><p>requestheader.title=Request Header Example</p><p>requestparams.title=Request Parameters Example<br />requestparams.params-in-req=Parameters in this request:<br />requestparams.no-params=No Parameters, Please enter some<br />requestparams.firstname=First Name:<br />requestparams.lastname=Last Name:</p><p>cookies.title=Cookies Example<br />cookies.cookies=Your browser is sending the following cookies:<br />cookies.no-cookies=Your browser isn't sending any cookies<br />cookies.make-cookie=Create a cookie to send to your browser<br />cookies.name=Name:<br />cookies.value=Value:<br />cookies.set=You just sent the following cookie to your browser:</p><p>sessions.title=Sessions Example<br />sessions.id=Session ID:<br />sessions.created=Created:<br />sessions.lastaccessed=Last Accessed:<br />sessions.data=The following data is in your session:<br />sessions.adddata=Add data to your session<br />sessions.dataname=Name of Session Attribute:<br />sessions.datavalue=Value of Session Attribute:<br /></p><img src ="http://www.tkk7.com/zhujiang001/aggbug/43787.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/zhujiang001/" target="_blank">孤酷伶仃</a> 2006-04-28 11:46 <a href="http://www.tkk7.com/zhujiang001/articles/43787.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Eclipse中用Hibernatehttp://www.tkk7.com/zhujiang001/articles/43783.html孤酷伶仃孤酷伶仃Fri, 28 Apr 2006 03:44:00 GMThttp://www.tkk7.com/zhujiang001/articles/43783.htmlhttp://www.tkk7.com/zhujiang001/comments/43783.htmlhttp://www.tkk7.com/zhujiang001/articles/43783.html#Feedback0http://www.tkk7.com/zhujiang001/comments/commentRss/43783.htmlhttp://www.tkk7.com/zhujiang001/services/trackbacks/43783.html在Eclipse中用Hibernate

作者:(x) James Elliott
译?qiaoyu
原文地址: http://www.onjava.com/pub/a/onjava/2005/01/05/hibernate.html
中文地址:http://www.matrix.org.cn/resource/article/43/43907_在Eclipse_Hibernate.html
关键词:(x) Eclipse Hibernate

~者注Q我们的调查l果昄Hibernate引v?jin)广泛兴,因此我们军_q周再来谈谈q个话题。这ơ由O(jin)'Reilly出版的Hibernate一书的作者来介绍如何在Eclipse中用Hibernate. Eclipse在这ơ调查中也得C(jin)很高的票数?br />
译者注Q翻译中的一些处理:(x)涉及(qing)EclipseӞ提供?jin)中英文两种表述Q如新徏(New)Q对于涉?qing)Hibernate Synchronizer的英文都没有译Q以和实际Y件中的条目保持一致?br />
介绍
最q我开始用Eclipse作ؓ(f)我的开发环境,部分原因是因为在我进行开发的许多q_上都可以使用Eclipse来工作,q有部分原因是因为Eclipse是展CZh人皆可作?gu)A(ch)献的开放、可扩展环境的优势的一个极好的例子。我开始研I其他h提供的对Eclipse的扩展。例如,当用到xml文gӞ我用XMLBuddy插g。该插g对于我的工作很有助益。因为最q一直在写Developer's NotebookQ所以我很想知道是不是已l有人写?jin)关于Hibernate的插Ӟ事实上,有好几个q样的插件正在开发。在q篇文章中,我们探索其中之一QHibernate Synchronizer.

Hibernate Synchronizer
在我扄和Hibernate有关的插件中QHibernate Synchronizer最令我感兴,因ؓ(f)它ؓ(f)我在Developer's Notebook书中采用的以映射Z?j)的工作(mapping-centric workflowQ提供了(jin)最好的支持?可以用多U方法用HibernateQ你可能?x)试试其它一些插Ӟ它们提供的方法可能正是你自己特定环境所要求?。事实上Q当使用Hibernate SynchronizerӞ如果你改变(sh)(jin)映射文gQ你不需要ؓ(f)更新相应的java文g而劳?j)费。当你编辑映文件时Q和Eclipse采取的方法类|该插件自动更C的java代码。还?sh)止于此Q还提供?jin)比Hibernate内徏的代码生成工h多的功能Q它为每个映对象创Z对类( a pair of classes)Q其中一个是基础c,当你改变映射内容Ӟ它可以随意重写这个类Q另一个类作ؓ(f)该基cȝ子类Q在子类中,你可以添加具体的商业逻辑和另一些代码。用这个插件生成java代码Ӟ不用象用Hibernate内置的代码生成工具那P担心(j)其它代码(如商业逻辑的代??x)在你的眼皮底下消失?br />
对于以Hibernate影射文档为基的方法,q有一些其它的好处QHibernate Synchronizer有一个新~辑器,当编辑这cL件时Qؓ(f)Eclipsed?jin)智能辅助和自动完成功能。一个比较好的、以DTD驱动的XML~辑器,如以前提?qing)的XMLBuddy,也可以完成部分功能。与此相比,Hibernate Synchronizer利用对媄(jing)文语义的?jin)解Q提供了(jin)更进一步的功能。例如,提供?jin)对属性和影射关系的可视化昄Q创建新元素的向导界面,象以上提?qing)的一P~省讄情况下,当你~辑影射文Ӟ~辑器会(x)自动生成数据讉Kc?data-access class).

当然q有其它一些功能,在Eclipse的新?New)菜单中,提供?jin)一个向|可以用来创徏Hibernate配置文g和映文Ӟ在包资源览?package explorer)和其它一些合适的地方增加?jin)上下文菜单Q方便调用和Hibernate相关的功能?br />
好了(jin)Q在q些抽象的描qC后,C(jin)开始做实事的时候,当然Q这正是你兴所在,不然你就不会(x)读这文章。怎么安装和用呢Q下边一一解释?br />
安装
Hibernate Synchronizer可以用Eclipse内置的更新管理器QUpdate ManagerQ来安装。对Eclipse 2.1和即发布的Eclipse 3的用h供了(jin)不同的更新站炏V(因ؓ(f)用Eclipse作关键性的工作Q我仍用作Z品发行的2.1版。当我写q篇文章的时候,Eclipse 3已经q入?jin)“候选发布”阶Dc(din)我希望当我今夏晚些时候从JavaOne回来Ӟ我可以更新到版本3的品发行版。提?qing)这个的主要原因是因为我惛_调一下,q些指南是以Eclipse 2的角度的来讲解,毫无疑问Q一些命令和H口?x)在版?中发生变化,因此Q当你用Eclipse 3Ӟ你应当做一些相应的调整。我印象中Hibernate Synchronizer自己的install instructions是针对Eclipse 3Q也许这对你有所帮助?br />
启动EclipseQ顺ơ单d助(HelpQ?->软g更新(Software Updates) -> 更新理器(Update ManagerQ来打开更新理器,当安?更新(Install/Update)透视图打开之后Q在功能更新视图QF(tun)eature UpdatesQ中用右键单击(如果你用的单键,你需要control-clickQ。选择新徏QNewQ?-> 站点书签(Site Bookmark),如图1中所C?br />
?????
?1 在更新管理器中添加Hibernate Synchronizer插g的更新地址

在弹出对话框中,输入适合你的Eclipse版本的插件地址Q?br />·Eclipse 2.1: http://www.binamics.com/hibernatesync/eclipse2.1
·Eclipse 3: http://www.binamics.com/hibernatesync

q需要ؓ(f)新徏的书{֑名,"Hibernate Synchronizer"是个很贴切的名字。图2中显C的是在Eclipse 2.1.2中填完所有需要的信息后的对话框。填完之后,你可单击完成(Finish)按钮来完成增加书{?br />
?????
?2. Hibernate Synchronizer插g更新站点书签

单击完成(Finish)后,新徏的书{ְ?x)出现在功能更新QF(tun)eature UpdatesQ?视图中,如图3中所C?

?????
?3. Hibernate Synchronizer站点已经可以使用

Z(jin)实际安装该插Ӟ单击该书{ַ边的三角形符P然后再次单击在书{下边出现的条目左边的三角ŞW号Q(h)l这个过E,一直到书签下边出现的条目中出现该插件的图标。单击该条目Q就?x)出C个可以让你安装的界面Q如?所C?br />
image
?4. 准备开始安装插?br />
单击Install NowQ让Eclipse引导你完成安?如图5-10).

?????
?5. 安装Hibernate Synchronizer


?????
?6. 许可协议

你可以看看下边Trade-Offs部分对许可协议的一些讨论。当你打在实际的项目中使用该插件时Q想必你?x)仔l研I该协议。我认ؓ(f)也许好一点,不过该插件基于GPL协议Q而不是开放源代码Qo(h)惑?br />
?????
?7. 选择安装位置Q缺省的已经很好?br />
?????
?8. 安装没有{֐插g时的标准警告

?????
?9 正在q行安装

image
?10. 完成安装

现在已经完成安装Q你需要退出,然后重新启动Eclipse以所做的更改生效。看上边的对话框好像说能够自动重新启动Eclipse?以我的经验,Eclipse只会(x)退出,q是需要你自己手工重新启动。这可能是Max OS Xq_上Eclipse 2.1的一个局限。Eclipse 3已经许诺把对OS X的支持列入第一U别。无论如何,q只是个问题。如果你需要重新启动EclipseQ现在就可以q样做。安装完之后Q接着需要对其对其进行配|,以便在项目中使用?br />
配置
重新启动Eclipse后,关闭安装/更新透视图。打开一个用Hibernate的Java工程.如果你已l完成了(jin)Developer's Notebook,一书中的例子,那么有几个目录可供你选择,q里以书中第三章中的例子来说明。第三章是可?a target="_new">在线免费获得的样章,你还可以从该书的站点下蝲所有例子的源代码?br />
如果你打用其中的一个例子来新徏一个Eclipse工程Q选择文g(File) ->新徏( New )-> 工程QProjectQ,选定工程cdQ然后单M一?Next)Q填入该工程名(我填的是"Hibernate Ch3"Q如?1所C)(j)Q不要复选用缺省检查框(Use default)Q这样你可以告诉Eclipse从哪里找到已l存在的工程目录Q单?yn)L览按?Browse)来定位目录。选定工程目录后可以单d?Finish)来创建工E。不q,一般情况下我喜Ƣ单M一?Next)来复查Eclipse为此工程所作的讄Q当?dng)如果发现有些配置不对QL可以选择回退来修改这些设|。不q,我L发现Q如果有一个库文g丢失或是其它一些原因,?x)有非常多的错误和警告信息?j)?br />
?????
?11. 创徏一个需要用Hibernate的新工程

在当前情况下Q我的}慎有点多余。Eclipse准确的算Z(jin)目录是如何组l以?qing)是用来q什么的Q找到我Z用Hibernate?HSQLDB 数据库而下载的W三方库Q下载和安装的详l过E可以参看书中第一章)(j)。如此聪明的适应能力是Eclipse优点之一。图12昄新工E已l打开Q准备好可以用来做实验。从q个图中也可以推断Eclipse不喜Ƣ调整窗口大其小到Ş成合适的屏幕布局。从现在开始,昄的屏q截囑֏昄H口的一部分Q而不是完整的H口?br />
image
?12. 使用Chapter 3例子的工E?br />
下一个需要做的工作是创徏一个Hibernate配置文gQ提供给Hibernate Synchronizer使用。在src目录中已l有?jin)一个hibernate.properties文gQ这是书中例子用的配置。这里有个问题,坏消息是Hibernate Synchronizer只能使用XML样式的Hibernate配置文g。这P需要把hibernate.properties中的内容UL到XML样式的配|文件hibernate.cfg.xml中。好消息是,q正是Hibernate Synchronizer创徏配置文g向导W一ơ大显n手的时候。选择文gQF(tun)ileQ?->新徏QNewQ?-> 其它QOtherQ,然后在弹出对话框选取刚可用的Hibernatec,选取 Hibernate Configuration FileQ然后单M一步(NextQ?

?????
?3 打开Hibernate配置文g向导

打开向导Ӟ保存文g的位|和在Eclipse中现在选择的文件有兟뀂请保把该文g保存在src 目录中。添加其余一些向导需要的信息Q这些信息应该和配置文g的版本相一_(d)如图14中所C。值得注意的是Q和用Ant来控制Hibernate的运行(书中使用是q种Ҏ(gu)Q不同,q里你无法控制Hibernateq行时的当前工作目录Q因此你需要在URL文g中用\径的全称。我自己的添加的URL|有点隄Qؓ(f)
jdbc:hsqldb:/Users/jim/Documents/Work/OReilly/Hibernate/Examples/ch03/data/music.

(如果有h知道怎么让Eclipse或是Hibernate Synchronizer使用一个工E特定的目录Q你可以告诉我,我很想知道。因为我才开始用EclipseQ是个新手。如果有人告诉我q是可能的,只是因ؓ(f)我不知道怎么做而已Q我一点也不会(x)感到吃惊)

?????
?4 d配置文g信息

dDriver Class 的方法有点奇怪,你需要单击Browse按钮Q然后开始输入driver的类名(译者注Q你需要确定该drivercd该工E的c\径中Q。如果你输入"jdbcD"Q窗口就?x)出现这个选择Q很Ҏ(gu)可以从中选取一个。具体如?5所C?br />
?????
?5 指定HSQLDB的driverc?br />
只要d如图14中那些属性值就可以。完成后单击Finish来完成创建配|文件。Hibernate Synchronizer 现在已经可以开始用了(jin)。完成创建文件后Q配|文件会(x)打开Q这时候你可以看看Hibernate XML格式的配|文件的l构和细节?br />
image
?6 生成的配|文?br />
要想试配置文g是否可用Q有一个又快又单的Ҏ(gu)Q用向导来创徏一个媄(jing)文件。选择文gQF(tun)ileQ?-> 新徏QNewQ?-> 其它QOtherQ,选取HibernatecdQ然后再选Hibernate 影射文gQ单M一?Next)。向导出现的时候,其中有些属性已l自动填入了(jin)在配|文件中相应属性的|单击Refresh(保可以通过q些信息和你的数据库相连)。和数据库连接后Q会(x)昄库中的表Q这里只有一个TRACK表。第一ơ用的时候,不知什么原因,需要你指定包含HSQLDB驱动?jar文g的\径。好在你只需要指定一ơ。只要你认ؓ(f)工作正常Q译者注Q显CZ(jin)数据库中有权限访问的表)(j)Q单击Cancel。试验中使用已有的媄(jing)文Ӟ不需要实际创Z个?br />
生成代码
q可能是你一直在{待的部分。我们能用这个插件来做什么?好,马上开始。ؓ(f)Hibernate影射文档提供一个新的菜单条目?br />
叛_Q如果是单键鼠标Q在按住Control键的同时炚w标键)一个媄(jing)文,菜单条目中会(x)昄几个和Hibernate相关的选择Q如?7所C)(j)Q其中有一个和synchronize有关Q这是一个手工方法,可以让Hibernate Synchronizer产生和该影射文相对应的数据讉K对象?br />
image
?7 Synchronizer插g为媄(jing)文档提供的几个菜单?br />
Add Mapping Reference 选项也很有用Q当你单击该Ҏ(gu)Q会(x)把相应的影射文g增加到Hibernate配置文g中,表明该文件是影射文Q因此你不需要在源代码中增加M信息要求相应的媄(jing)文件进行设|。现在让我们看看选取Synchronize Files后的l果?br />
事情开始变得有,出现?jin)两个子包,一个是“base”的DAOQHibernate Synchronizer所有,可以在Q何时候重写,一个是l承那些DAOcȝ商业对象Q不?x)被覆盖Q也q?jin)我们一个机?x),可以在其中加入商业逻辑Q具体如?8中所C)(j)?br />
image
?8 同步后的DAOQ图中显C的是我们可以编辑的子类

 (tng) (tng)和Hibernate的代码生成工L(fng)比,用该插g生成?jin)更多的cR这是优点,也可能是一些潜在的~点Q将在Trade-Offs 部分q行讨论。你可以在工E配|文件中选取要生成的cd它们所在的包的l构。我可以证明q点Q但现在的发行版有个bug ,Q无法访问Mac OS X上的配置界面。针对该bug的一个补丁已l做好了(jin)Q但仍没有发布?br />
ZHibernate Synchronizer|页上的例子Q和以下q个cMP用那些新的数据访问对象来试着把一些数据放入数据库中。看h和标准的Hibernate代码生成工具生成的版本(在Hibernate: A Developer's Notebook一书的39-40)(j)很相|甚至更简单一些。因为Hibernate Synchronizer生成的类Z的每个数据库操作都创建和提交一个新事务Q因此在与此cM的简单情况下Q你不需要自己来讄事务Q当?dng)如果你需要把一l操作作Z个单独事务,有很多方法可以做到这点)(j)q里是新版本的代码?br />
package com.oreilly.hh;

import java.sql.Time;
import java.util.Date;
import net.sf.hibernate.HibernateException;
import com.oreilly.hh.dao.TrackDAO;
import com.oreilly.hh.dao._RootDAO;

/**
* Try creating some data using the Hibernate Synchronizer approach.
*/
public class CreateTest2 {

 (tng) (tng) (tng) (tng)public static void main(String[] args) throws HibernateException {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// Load the configuration file
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)_RootDAO.initialize();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// Create some sample data
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)TrackDAO dao = new TrackDAO();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Track track = new Track("Russian Trance", "vol2/album610/track02.mp3",
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Time.valueOf("00:03:30"), new Date(), (short)0);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)dao.save(track);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)track = new Track("Video Killed the Radio Star",
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)"vol2/album611/track12.mp3", Time.valueOf("00:03:49"), new Date(),
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)(short)0);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)dao.save(track);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// We don't even need a track variable, of course:
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)dao.save(new Track("Gravity's Angel", "/vol2/album175/track03.mp3",
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Time.valueOf("00:06:06"), new Date(), (short)0));
 (tng) (tng) (tng) (tng)}
}


当我写这个的时候,有Eclipse在手边真是太好了(jin) Q我已经忘(sh)(jin)当写书中例子的时候多么想忉|能代码完成功能,有另外几件事情JDT也发挥了(jin)作用?br />
 (tng) (tng)Z(jin)在Eclipse中运行这个简单的E序Q需要设|一个新的运行配|。用CreateTest2.java作ؓ(f)当前文gQ选择q行QRun Q?> q行...QRun...Q。然后单?yn)L?New)Q因cL一个main() Ҏ(gu)QEclipse推断?gu)q行该工E的当前cREclipse为新的运行配|取的名字,CreateTest2Q很合适。屏q窗口看h如图19中所C,单击q行来在数据库中创徏一些数据?br />
image
?9 准备在Eclipse中运行创建数据的试E序

如果你确实按照上边说的来做,你会(x)发现W一ơ的试q行p|。Hibernate抱怨配|文件中q一个映文仉没有参考,Z(jin)q行E序Q至需要一个这L(fng)文g。这也是Z么XMLBuddy在图16底部用黄色下划线发出警告。可以很Ҏ(gu)修改该错误,你只要在包资源浏览器QPackage ExplorerQ中的Track.hbm.xmlq个影射文上单d键,在Hibernate Synchronizer子菜单中选取Add Mapping Reference(如图17中所C?Q这样XMLBuddy׃?x)再抱怨XML文g有错误,E序也可以(h)l向前。不q的是,没有向前推进我们所愿的那样q,下一个问题又出来?jin)。Eclipse中显C的下一个错误是“不能在JNDI中找到JTA UserTransaction initial context”。不止我一个h犯这U错误,因ؓ(f)在a forum thread中有q样的讨论,而且到目前ؓ(f)止仍然没有找C个解x(chng)法?br />
既然我知道不需要用JTAQ我倒是很想知道Z么Hibernate竟然?x)用JTAQ打开Hibernate配置文gQ如?6所C,看看是不是Hibernate Synchronizer在其中加入了(jin)可疑的内宏V看?jin)配|文件后Q可以确定,有一些行看v来是|魁RQ?br />
 <property name="hibernate.transaction.factory_class"> 
 (tng) (tng) (tng) (tng) (tng) (tng) net.sf.hibernate.transaction.JTATransactionFactory
</property>
<property name="jta.UserTransaction">
 (tng) (tng) (tng) (tng) (tng) (tng) java:comp/UserTransaction
</property>


一旦把那些行变成注释后Q再ơ运行程序。这ơ,也就是第三次q行成功。我在自p机上运行没有一炚w误,数据已经保存到数据库中。运?ant db q个targetQ在Developer's Notebook一书的W一章有相应的解释)(j)可以把表中所有的数据昄出来Q不可否认,q也许有点简单)(j)Q如?0中所C。如果你跟着q篇文章中顺序来做的Q而不是跟着书中步骤一步一步来的,你需要先q行ant schema来创建数据库中的表,或是删除以前试验留下的数据?br />
image
?0 在Eclipse中运行Ant

你可以在Eclipse内运行Ant的targetQ方法是用右键单d资源览器(Package ExplorerQ中的build.xml 文gQ选择菜单中的q行Ant(Run Ant)Q然后在弹出对话框中选择你要q行的targetQ如?1所C。这个功能很cool?br />
image
?1 在Eclipse中运行Ant

查询数据相当单、直白,即Hibernate Synchronizer产生?jin)很多辅助方法来使用指定查询Q我认ؓ(f)q些没有什么用处,都是q行查询Q然后返回包含结果的列表Q而不是返回一个Query对象Q让你直接用该对象。这使你不能使用MQuery提供的、方便的、类型安全(type-safeQ的参数讄Ҏ(gu)Q因个,我打让_RootDAO对象提供一个Session对象Q可以用“老式”的Ҏ(gu)来用Hibernate。公qx(chng)_(d)我认为如果编辑Hibernate Synchronizer 用来生成代码所使用的模板,可以生成想要的MҎ(gu)Q如果有一个项目,要用到该插gQ可以肯定我?x)试着q么做?br />
实际上,q一步考虑Q当你得C个活动的SessionӞ你只能用QueryQ而这些DAO对象已经提供为相应功能最佳的实现。如果你和我在例子中使用查询的方法一P那就需要你自己来实现session理。你能够把session理内嵌于你自己所写的那一半DAO中,q样可以l你提供两方面的好处?译者注Q和有base的java POJO对象一P对于DAOQ该插g也生成一对类Q一个base DAOl该插g用,一个是l承该base DAO的自定义DAOQ你可以在其中添加商业逻辑)。这也是Hibernate Synchronizer把类分隔开来如此有用的另一个原因。对该插件的q见在下边做?jin)一点研I?br />
不管怎么_(d)下边是我W一ơ用的代码Q和书中48-49上的代码功能基本一?
package com.oreilly.hh;

import java.sql.Time;
import java.util.ListIterator;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;

import com.oreilly.hh.dao.TrackDAO;
import com.oreilly.hh.dao._RootDAO;

/**
* Use Hibernate Synchronizer's DAOs to run a query
*/
public class QueryTest3 {

 (tng) (tng) (tng) (tng)public static void main(String[] args) throws HibernateException {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// Load the configuration file and get a session
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)_RootDAO.initialize();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Session session = _RootDAO.createSession();

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)try {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// Print the tracks that will fit in five minutes
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Query query = session.getNamedQuery(
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)TrackDAO.QUERY_COM_OREILLY_HH_TRACKS_NO_LONGER_THAN);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)query.setTime("length", Time.valueOf("00:05:00"));
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)for (ListIterator iter = query.list().listIterator() ;
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) iter.hasNext() ; ) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Track aTrack = (Track)iter.next();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)System.out.println("Track: \"" + aTrack.getTitle() +
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) "\", " + aTrack.getPlayTime());
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)} finally {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// No matter what, close the session
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)session.close();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
 (tng) (tng) (tng) (tng)}
}


TrackDAO为我们提供了(jin)一个很好的功能Q静(rn)态常敎ͼ使用q个功能Q可以用来进行指定查询(named queryQ,q就消除?jin)由于输入问题而导致运行时错误的Q何机?x)。我ƣ赏q个功能。ؓ(f)该测试类讑֮q行配置Q然后运行,输出l果正和我想的一P如图22所C?br />
image
?2 Eclipse控制台窗口显C的查询l果

如上所qͼq个c运行后Q借助于Hibernate Synchronizer提供的模型,我想到有一个更好的Ҏ(gu)可以实现q个功能。把查询攑ֈTrackDAO中去Q这里才是查询方法真正属于的地方Q指定查询(named queryQ是和该DAO兌的映文件的一个功能?br />
package com.oreilly.hh.dao;

import java.sql.Time;
import java.util.List;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;

import com.oreilly.hh.base.BaseTrackDAO;

/**
* This class has been automatically generated by Hibernate Synchronizer.
* For more information or documentation, visit The Hibernate Synchronizer page
* at http://www.binamics.com/hibernatesync or contact Joe Hudson at joe@binamics.com.
*
* This is the object class that relates to the TRACK table.
* Any customizations belong here.
*/
public class TrackDAO extends BaseTrackDAO {

 (tng) (tng) (tng) (tng)// Return the tracks that fit within a particular length of time
 (tng) (tng) (tng) (tng)public static List getTracksNoLongerThan(Time time)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)throws HibernateException
 (tng) (tng) (tng) (tng){
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Session session = _RootDAO.createSession();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)try {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// Print the tracks that will fit in five minutes
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Query query = session.getNamedQuery(
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)QUERY_COM_OREILLY_HH_TRACKS_NO_LONGER_THAN);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)query.setTime("length", time);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)return query.list();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)} finally {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// No matter what, close the session
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)session.close();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
 (tng) (tng) (tng) (tng)}
}


以上代码Q看h更好(nice)、更为清?clean)QQueryTest3中的main()Ҏ(gu)更是得到?jin)大大简?br />
 (tng) (tng) (tng) (tng)public static void main(String[] args) throws HibernateException {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// Load the configuration file and get a session
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)_RootDAO.initialize();

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// Print the tracks that fit in five minutes
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)List tracks = TrackDAO.getTracksNoLongerThan(Time.valueOf("00:05:00"));
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)for (ListIterator iter = tracks.listIterator() ;
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) iter.hasNext() ; ) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Track aTrack = (Track)iter.next();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)System.out.println("Track: \"" + aTrack.getTitle() +
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) "\", " + aTrack.getPlayTime());
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
 (tng) (tng) (tng) (tng)}


很清楚,q是在Hibernate Synchronizer中用到指定查询(named queryQ时所应采取的Ҏ(gu)。很快测试一下就可以证实以上的代码输出同L(fng)l果Q而且q里的代码更好?

~辑映射文g
Hibernate Synchronizer一个主?引h之处是ؓ(f)映射文g提供的有专业水^的编辑器Q你可以配置该编辑器Q这样当你保存文件的时候,可以自动重新生成相应的数据对象,.q只是你最后才?x)用到的功能。即使不使用该插件的代码生成器,可能你还是会(x)用这个编辑器。当你编辑媄(jing)文时Q它可以为映文中的元素提供智能完成功能,q有一个你可以操作的映文档的大纲视图?br />
如果你从Developer's Notebook下蝲的源代码Q然后想用该插g的映文编辑器来编辑该文gQ需要耍一个小花招。在下蝲文g中,影射文的扩展名?.hbm.xml"Q而该插g仅仅对以"hbm"为扩展名的文件才调用影射文~辑器。理ZQ你可以在Eclipse中配|扩展名映射Q以便两个扩展名都可以用该插件的~辑器,不过Q我没有成功q,我在支持论坛上看到别人有同样的问题。因此,暂时来看Q最好的办法是重命名文Ӟ如果用Ant来生成代码,保修改build.xml文g的codegenq个targetQ其也使用新扩展名Q?br />
当我把Track.hbm.xml改名为Track.hbmӞ包资源浏览器中该文g的图标更Cؓ(f)象Hibernate的logo。该文g的默认编辑器变(sh)ؓ(f)该插件的影射文~辑器,如图23中所C。不知道什么原因,对这两个扩展名的文gQ其它的Hibernate Synchronizer选项都可用,令h奇怪的是,只有“hbm”结文g可以用其~辑器?br />
image
?3 Hibernate影射文Q扩展名?.hbm"Q的上下文菜?br />
~辑器对于你要在影射文中增加的所有元素提供了(jin)上下文敏感的自动完成功能Q图24举了(jin)两个例子。虽然如此,没有一个屏q抓图能够真正显C如此功能的l节和有用之处。我鼓励你自己安装该插gQ然后自己来试试q个~辑?你很快就?x)发现当使用影射文档的时候,q个~辑器是多么有帮助?br />
image
image
?4Q?5 影射文~辑器中的自动完成功?br />
大纲视图Q象?6中所C,可以用图形的方式昄cȝl构Q被影射的元素,指定查询和其它一些出现在影射文中内容,同时也提供了(jin)几个向导Q帮助你创徏新项

image
image
?6Q?7 影射~辑器的大纲视图以及(qing)“Add property”向?br />
~辑器内的上下文菜单中有一Ҏ(gu)Format Source CodeQ你可以用来Ҏ(gu)档进行清z和改变文l构。编辑器内也有很多灵巧和有用的功能,看看它如何“成镎(k)是一件有的事情。对我来_(d)唯一的不满是当你完成XML属性的时候,该编辑器用非怸同于JDT在java代码中用的Ҏ(gu)来帮助你理引号Q在它们之间切换有时令hq失QJDT采用的方法可能只适于它自己,但一旦你信Q它,q个Ҏ(gu)看v来就有点力Q?br />
产生数据库中的表
和我的第一印象-一切都可以通过影射文得到-不同QHibernate Synchronizer现在没有为创建或更新数据库提供Q何支持。支持论坛上已经张脓(chung)?jin)一个这L(fng)功能要求Q如果我们将来看到这些功能,我不?x)感到惊奇。这U功能应该不是很难。暂Ӟ你不得不采用其他Ҏ(gu)Q如果你想从影射文生成数据库,你可以象Hibernate: A Developer's Notebook 一书中使用Ant一h做到。下Ҏ(gu)q的Hibernator插g支持在Eclipse中更新数据库。或许,我应该研I一下是否能够同时安装这两个插g?br />
好了(jin)Q我当然希望q个单介l的指南能够让你对这个插件的功能有一个大致的?jin)解Q当?dng)我没有提及(qing)它的所有功能。如果文中有些内Ҏ(gu)起了(jin)你的兴趣Q那׃载,安装Q自p试?br />
Trade-Offs
很清楚,你可以用Hibernate Synchronizer来做灵y的事情。我?x)在我自qHibernate目中用该插g吗?q个x(chng)有其它一些优~点需要考虑Q可能现在还?sh)是做决定的时候,直到需要用Hibernate来取代自安(当然非常?的、已l在工作的轻量O/R工具时才能做出决定。这是个_重要的改变,我们一直推q做出决定,直到有其它原因出现。下边的因素在我的决定中占有重要分量?br />
在安装部分已l提?qing),有几个涉及(qing)到许可证的问题Q该插g的论坛对q个也有些讨论。现在所采用的许可证是作?jin)适合自己的修改后的GNU GPLQ删除了(jin)关于源代码共享的规定Q保留了(jin)"copyleft"保护的其它方面。关于这个的合法性有些问题,作者正在找另外一个可用来替代的许可证。它的确切意图是保护该插Ӟ不妨用该插g生成代码的其它一些项目。不q还是值得仔细M下现在的许可证,看看你是否相信该许可证已l达到其本来意图。否则,对你来说Q会(x)有很多风?br />
同样的讨论显C,作者本来想把该插g作ؓ(f)开源YӞ但(f)时改变(sh)(jin)LQ因Z觉得该插件还没有“琢”到_l其他h以作Z个优U的开源Y件的E度。此后,他通过?sh)子邮g和一些性急的行了(jin)交流Q这些h的电(sh)子邮仉常讨厌,最l他没有兴再分n整个源代码,真是令h感到(zhn)哀。当?dng)和我们分享什么是他的权力。对于世界来_(d)q个插g是个C物Q作者不Ơ我们什么。但我希望其它用L(fng)U极影响或许可以帮助说服他重新实行原来的计划-分n源代码。我真正重视可以得到源代码的工具Q不仅是因ؓ(f)q是个很好的学习(fn)Z(x)Q而且意味着有了(jin)源代码,如果有需要,?或其他h)可以马上修改出现的一些小问题。到目前为止Q该插g的作者一直非常积极的回应用户的问题,但是没有够一个h做的象一个团队一样好Q我们有些时候很忙,{疲力尽Q或是心(j)情烦(ch)?br />
Hibernate Synchronizer用它自己的模版和一套机制来生成你的数据讉Kc,q个事情有好的一面,也有坏的一面。好的一面在于它Z提供?jin)比标准的Hibernate代码生成工具更多的功能。在自动产生的你所定义的数据对象的子类中嵌入商业逻辑Q而不用害怕重新生成代码的时候有兛_业逻辑的代码被覆盖Q这是一个很大的额外好处。该插g生成的、许多单的cL单的cL供了(jin)其它一些优U的功能?br />
另一斚wQ这q不意味着当这个^台添加新功能或是有其它一些变化的时候,Hibernate Synchronizer生成的代码会(x)滞后。这个插件的代码也很有可能在支持Hibernate很少用到的方式方面存在一些bugQ因Z用该插g的用L(fng)很小Q仅有一个h对其q行更新Q你可以从论坛中看到q种现象的证据?br />
和许多事情一P׃军_是否潜在好处胜过风险。即使你没有使用代码生成器,或许你会(x)发现影射文~辑器极端有用。如果你只是使用~辑器的自动完成和协助功能,你可以关闭automatic synchronization?br />
如果你真的采用了(jin)q个插gQ而且发现它很有用Q毫无疑问,我鼓׃和作者联p,表达你的谢意Q如果可能,可以考虑捐些׃支持该插件(h)l开发?br />
其它一些插?/span>
在我搜寻插g的过E中Q我发现?jin)其它两个插Ӟ可以为在Eclipse中用Hibernate提供支持Q如果你知道其它一些插Ӟ或是在将来的某一天偶遇其它的插gQ我很有兴趣?jin)解q些插gQ。也许将来我?x)写一些关于这些插件的文章?br />
HiberClipse
HiberClipse看v来是另一个非常有用的工具Q该插g采取的是数据库驱动的工作方法:(x)你已l有?jin)数据库Q想用该插g构造Hibernate映射文g和JavacL件。这U事很常见,如果你面对这L(fng)dQ我肯定?x)推荐你使用该插件。该插g提供?jin)一个很cool的功?Q在Eclipse中提供给你一个正在用的数据库的囑Ş化显C的“关p视䏀(应该指出Q当你从一个现存的数据库开始工作时候,Hibernate Synchronizer也没有你处于孤立无援的境地QNew Mapping File Wizard 可以q接数据库,然后Ҏ(gu)它找到的内容生成映射文gQ如?8所C)(j)

image
?8 Hibernate Synchronizer的创建映文件向?br />
Hibernator
最后,Hibernator看v来向另一个方向倾斜Q从你的Java代码来生简单的Hibernate映射文Q然后可以由此创建(或是更新Q数据库。另外,q提供了(jin)在Eclipse中进行数据库查询的能力。在q三个插件中Q它处于开发的最早期Q但是已l值得你时常关注,特别是该插g援引Hibernate开发小l的成员?sh)?f)贡献者?

?jin)解更?/b>
如果q篇文章Ȁ起了(jin)你的兴趣Q有很多资源可以让你深入?jin)解那些主题Q除?jin)文中所q接的站点以外,有一些也怽?x)感兴趣。当?dng)包括我自q书Hibernate: A Developer's Notebook。对于更有深度的参考资料,在线文档非常有帮助,特别是其中的参考手册,q有一本Hibernate开发h员自己写的Hibernate in Action卛_发行Q我自己也很期待读这本书?br />
对于EclipseQ我现在正在看Steve Holzner的Eclipse一书,正在盼望能够阅读本月末将发行的Eclipse Cookbook一书。如果你有好奇心(j)Q或是你自己正在边缘y跚前行Q,你可以看看我的blogQ在那里更详l的讨论?jin)我向Eclipse的{变。如果你只是刚开始用EclipseQ请保你研I过Eclipse自带的工作台和Java开发用h南(Workbench and Java Development user guidesQ的入门QGetting StartedQ部分。这些用h南讲解了(jin)Eclipse应该怎么用,提供?jin)一些好的徏议,q且引领你用你自己或许不能很快发现的过E和功能。可以选择 帮助QHelpQ?- > 帮助内容QHelp ContentsQ找到该手册?br />
资源:
·Eclipse讨论?http://www.matrix.org.cn/topic.shtml?forumId=25
·Hibernate讨论?http://www.matrix.org.cn/topic.shtml?forumId=23


孤酷伶仃 2006-04-28 11:44 发表评论
]]>
վ֩ģ壺 gayվ| 99þѹƷ| 벻޳?Ƭ| XXX2߹ۿƵ| ޴Ƭ߹ۿ| Ѹ弤Ƶ| һŮȫƬѿ| ޳˸߹ۿ| ޵һɫַ| ۺƵ| Ʒҹѹۿվ| ɫϰƵ߹| ޹ƷþþþþԻ | Ҹ| ɫ͵ר| AëƬ| þþƷѴƬƬ| ޹Ʒxo߹ۿ| Ů߲| ھƷ鶹վ91鶹 | Ƭ߹ۿ| ˳Ļ| Ʒþþþþ| ձҳվ| 3344߹ۿƵҳ | 91˿߹ۿ | ҹƵ| һƵ߹ۿwww | þù׾Ʒҹ| AVһ߿ | ׾ƷƵ| Ļ뾫ƷԴþ | AëƬA| ĻӰƬ߹ۿ| ij˾þþþӰԺѹۿ | þAëƬѹۿ| йɫվ| ɫһƵ| ޾Ʒþ| ˳ձ߹ۿ| ޾ƷŮ߹ۿ|