﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-My Rhythm-随笔分类-Others_4Data Persistence</title><link>http://www.blogjava.net/redcoatjk/category/48593.html</link><description>万物皆对象 万事归节奏</description><language>zh-cn</language><lastBuildDate>Fri, 27 May 2011 21:37:00 GMT</lastBuildDate><pubDate>Fri, 27 May 2011 21:37:00 GMT</pubDate><ttl>60</ttl><item><title>[转]java中hashcode()和equals()的详解</title><link>http://www.blogjava.net/redcoatjk/archive/2011/05/27/351200.html</link><dc:creator>redcoatjk</dc:creator><author>redcoatjk</author><pubDate>Fri, 27 May 2011 10:15:00 GMT</pubDate><guid>http://www.blogjava.net/redcoatjk/archive/2011/05/27/351200.html</guid><wfw:comment>http://www.blogjava.net/redcoatjk/comments/351200.html</wfw:comment><comments>http://www.blogjava.net/redcoatjk/archive/2011/05/27/351200.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/redcoatjk/comments/commentRss/351200.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/redcoatjk/services/trackbacks/351200.html</trackback:ping><description><![CDATA[摘自:<div>http://www.iteye.com/topic/257191</div><br />-----------------<br /><div>今天下午研究了半天hashcode()和equals()方法，终于有了一点点的明白，写下来与大家分享（zhaoxudong 2008.10.23晚21.36）。  <br />1. 首先equals()和hashcode()这两个方法都是从object类中继承过来的。  <br />equals()方法在object类中定义如下：  <br />&nbsp; public boolean equals(Object obj) {  <br />return (this == obj);  <br />}  <br />很明显是对两个对象的地址值进行的比较（即比较引用是否相同）。但是我们必需清楚，当String  、Math、还有Integer、Double。。。。等这些封装类在使用equals()方法时，已经覆盖了object类的equals（）方法。比 如在String类中如下：  <br />&nbsp; public boolean equals(Object anObject) {  <br />if (this == anObject) {  <br />&nbsp;&nbsp;&nbsp; return true;  <br />}  <br />if (anObject instanceof String) {  <br />&nbsp;&nbsp;&nbsp; String anotherString = (String)anObject;  <br />&nbsp;&nbsp;&nbsp; int n = count;  <br />&nbsp;&nbsp;&nbsp; if (n == anotherString.count) {  <br />char v1[] = value;  <br />char v2[] = anotherString.value;  <br />int i = offset;  <br />int j = anotherString.offset;  <br />while (n-- != 0) {  <br />&nbsp;&nbsp;&nbsp; if (v1[i++] != v2[j++])  <br />return false;  <br />}  <br />return true;  <br />&nbsp;&nbsp;&nbsp; }  <br />}  <br />return false;  <br />}  <br />很明显，这是进行的内容比较，而已经不再是地址的比较。依次类推Double、Integer、Math。。。。等等这些类都是重写了equals()方法的，从而进行的是内容的比较。当然了基本类型是进行值的比较，这个没有什么好说的。  <br />我们还应该注意，Java语言对equals()的要求如下，这些要求是必须遵循的：  <br />&#8226; 对称性：如果x.equals(y)返回是&#8220;true&#8221;，那么y.equals(x)也应该返回是&#8220;true&#8221;。  <br />&#8226; 反射性：x.equals(x)必须返回是&#8220;true&#8221;。  <br />&#8226; 类推性：如果x.equals(y)返回是&#8220;true&#8221;，而且y.equals(z)返回是&#8220;true&#8221;，那么z.equals(x)也应该返回是&#8220;true&#8221;。  <br />&#8226; 还有一致性：如果x.equals(y)返回是&#8220;true&#8221;，只要x和y内容一直不变，不管你重复x.equals(y)多少次，返回都是&#8220;true&#8221;。  <br />&#8226; 任何情况下，x.equals(null)，永远返回是&#8220;false&#8221;；x.equals(和x不同类型的对象)永远返回是&#8220;false&#8221;。  <br />以上这五点是重写equals()方法时，必须遵守的准则，如果违反会出现意想不到的结果，请大家一定要遵守。  <br />2. 其次是hashcode() 方法，在object类中定义如下：  <br />&nbsp; public native int hashCode();  <br />说明是一个本地方法，它的实现是根据本地机器相关的。当然我们可以在自己写的类中覆盖hashcode()方法，比如String、 Integer、Double。。。。等等这些类都是覆盖了hashcode()方法的。例如在String类中定义的hashcode()方法如下：  <br />&nbsp;&nbsp;&nbsp; public int hashCode() {  <br />int h = hash;  <br />if (h == 0) {  <br />&nbsp;&nbsp;&nbsp; int off = offset;  <br />&nbsp;&nbsp;&nbsp; char val[] = value;  <br />&nbsp;&nbsp;&nbsp; int len = count;  <br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; len; i++) {  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h = 31*h + val[off++];  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hash = h;  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return h;  <br />}  <br />解释一下这个程序（String的API中写到）：  <br />s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]  <br />使用 int 算法，这里 s[i] 是字符串的第 i 个字符，n 是字符串的长度，^ 表示求幂。（空字符串的哈希码为 0。）  <br /> <br />3.这里我们首先要明白一个问题：  <br />equals()相等的两个对象，hashcode()一定相等；  <br />equals（）不相等的两个对象，却并不能证明他们的hashcode()不相等。换句话说，equals()方法不相等的两个对象，hashcode()有可能相等。（我的理解是由于哈希码在生成的时候产生冲突造成的）。  <br />反过来：hashcode()不等，一定能推出equals()也不等；hashcode()相等，equals()可能相等，也可能不等。解释 下第3点的使用范围，我的理解是在object、String等类中都能使用。在object类中，hashcode()方法是本地方法，返回的是对象的 地址值，而object类中的equals()方法比较的也是两个对象的地址值，如果equals()相等，说明两个对象地址值也相等，当然 hashcode()也就相等了；在String类中，equals()返回的是两个对象内容的比较，当两个对象内容相等时，  <br />Hashcode()方法根据String类的重写（第2点里面已经分析了）代码的分析，也可知道hashcode()返回结果也会相等。以此类 推，可以知道Integer、Double等封装类中经过重写的equals()和hashcode()方法也同样适合于这个原则。当然没有经过重写的 类，在继承了object类的equals()和hashcode()方法后，也会遵守这个原则。  <br /> <br />4.谈到hashcode()和equals()就不能不说到hashset,hashmap,hashtable中的使用，具体是怎样呢，请看如下分析：  <br />Hashset是继承Set接口，Set接口又实现Collection接口，这是层次关系。那么hashset是根据什么原理来存取对象的呢？  <br />在hashset中不允许出现重复对象，元素的位置也是不确定的。在hashset中又是怎样判定元素是否重复的呢？这就是问题的关键所在，经过一下午的查询求证终于获得了一点启示，和大家分享一下，在java的集合中，判断两个对象是否相等的规则是：  <br />1)，判断两个对象的hashCode是否相等  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果不相等，认为两个对象也不相等，完毕  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果相等，转入2) <br />（这一点只是为了提高存储效率而要求的，其实理论上没有也可以，但如果没有，实际使用时效率会大大降低，所以我们这里将其做为必需的。后面会重点讲到这个问题。）  <br />2)，判断两个对象用equals运算是否相等  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果不相等，认为两个对象也不相等  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果相等，认为两个对象相等（equals()是判断两个对象是否相等的关键）  <br />为什么是两条准则，难道用第一条不行吗？不行，因为前面已经说了，hashcode()相等时，equals()方法也可能不等，所以必须用第2条准则进行限制，才能保证加入的为非重复元素。  <br />比如下面的代码：  <br /> <br />public static void main(String args[]){  <br />String s1=new String("zhaoxudong");  <br />String s2=new String("zhaoxudong");  <br />System.out.println(s1==s2);//false  <br />System.out.println(s1.equals(s2));//true  <br />System.out.println(s1.hashCode());//s1.hashcode()等于s2.hashcode()  <br />System.out.println(s2.hashCode());  <br />Set hashset=new HashSet();  <br />hashset.add(s1);  <br />hashset.add(s2);  <br />/*实质上在添加s1,s2时，运用上面说到的两点准则，可以知道hashset认为s1和s2是相等的，是在添加重复元素，所以让s2覆盖了s1;*/  <br />Iterator it=hashset.iterator();  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(it.hasNext())  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(it.next());  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <br />最后在while循环的时候只打印出了一个&#8221;zhaoxudong&#8221;。  <br />输出结果为：false  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; true  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -967303459  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -967303459  <br />这是因为String类已经重写了equals()方法和hashcode()方法，所以在根据上面的第1.2条原则判定时，hashset认为它们是相等的对象，进行了重复添加。  <br />但是看下面的程序：  <br />import java.util.*;  <br />public class HashSetTest  <br />{  <br />&nbsp;&nbsp; public static void main(String[] args)  <br />&nbsp;&nbsp;&nbsp; {  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HashSet hs=new HashSet();  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hs.add(new Student(1,"zhangsan"));  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hs.add(new Student(2,"lisi"));  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hs.add(new Student(3,"wangwu"));  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hs.add(new Student(1,"zhangsan"));  <br />&nbsp;  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Iterator it=hs.iterator();  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(it.hasNext())  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(it.next());  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <br />&nbsp;&nbsp;&nbsp;&nbsp; }  <br />}  <br />class Student  <br />&nbsp;&nbsp; {  <br />&nbsp;&nbsp;&nbsp;&nbsp; int num;  <br />&nbsp;&nbsp;&nbsp;&nbsp; String name;  <br />&nbsp;&nbsp;&nbsp;&nbsp; Student(int num,String name)  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.num=num;  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.name=name;  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String toString()  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return num+":"+name;  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />输出结果为：  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1:zhangsan  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1:zhangsan  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3:wangwu  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2:lisi  <br />问题出现了，为什么hashset添加了相等的元素呢，这是不是和hashset的原则违背了呢？回答是：没有  <br />因为在根据hashcode()对两次建立的new  Student(1,"zhangsan")对象进行比较时，生成的是不同的哈希码值，所以hashset把他当作不同的对象对待了，当然此时的 equals()方法返回的值也不等（这个不用解释了吧）。那么为什么会生成不同的哈希码值呢？上面我们在比较s1和s2的时候不是生成了同样的哈希码 吗？原因就在于我们自己写的Student类并没有重新自己的hashcode()和equals()方法，所以在比较时，是继承的object类中的 hashcode()方法，呵呵，各位还记得object类中的hashcode()方法比较的是什么吧！！  <br />它是一个本地方法，比较的是对象的地址（引用地址），使用new方法创建对象，两次生成的当然是不同的对象了（这个大家都能理解吧。。。），造成 的结果就是两个对象的hashcode()返回的值不一样。所以根据第一个准则，hashset会把它们当作不同的对象对待，自然也用不着第二个准则进行 判定了。那么怎么解决这个问题呢？？  <br />答案是：在Student类中重新hashcode()和equals()方法。  <br />例如：  <br />&nbsp; class Student  <br />{  <br />int num;  <br />String name;  <br />Student(int num,String name)  <br />{  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.num=num;  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.name=name;  <br />}  <br />public int hashCode()  <br />{  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return num*name.hashCode();  <br />}  <br />public boolean equals(Object o)  <br />{  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Student s=(Student)o;  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return num==s.num &amp;&amp; name.equals(s.name);  <br />}  <br />public String toString()  <br />{  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return num+":"+name;  <br />}  <br />}  <br />根据重写的方法，即便两次调用了new Student(1,"zhangsan")，我们在获得对象的哈希码时，根据重写的方法hashcode()，获得的哈希码肯定是一样的（这一点应该没有疑问吧）。  <br />当然根据equals()方法我们也可判断是相同的。所以在向hashset集合中添加时把它们当作重复元素看待了。所以运行修改后的程序时，我们会发现运行结果是：  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1:zhangsan  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3:wangwu  <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2:lisi  <br />可以看到重复元素的问题已经消除。  <br />关于在hibernate的pojo类中，重新equals()和hashcode()的问题：  <br />1)，重点是equals，重写hashCode只是技术要求（为了提高效率）  <br />2)，为什么要重写equals呢，因为在java的集合框架中，是通过equals来判断两个对象是否相等的  <br />3)，在hibernate中，经常使用set集合来保存相关对象，而set集合是不允许重复的。我们再来谈谈前面提到在向hashset集合中添加元素时,怎样判断对象是否相同的准则，前面说了两条，其实只要重写equals()这一条也可以。  <br />但当hashset中元素比较多时，或者是重写的equals()方法比较复杂时，我们只用equals()方法进行比较判断，效率也会非常低， 所以引入了hashcode()这个方法，只是为了提高效率，但是我觉得这是非常有必要的（所以我们在前面以两条准则来进行hashset的元素是否重复 的判断）。  <br />比如可以这样写：  <br />public int hashCode(){  <br />&nbsp;&nbsp; return&nbsp; 1;}//等价于hashcode无效  <br />这样做的效果就是在比较哈希码的时候不能进行判断，因为每个对象返回的哈希码都是1，每次都必须要经过比较equals()方法后才能进行判断是否重复，这当然会引起效率的大大降低。  <br />我有一个问题，如果像前面提到的在hashset中判断元素是否重复的必要方法是equals()方法（根据网上找到的观点），但是这里并没有涉及到关于哈希表的问题，可是这个集合却叫hashset，这是为什么？？  <br />我想，在hashmap,hashtable中的存储操作，依然遵守上面的准则。所以这里不再多说。这些是今天看书，网上查询资料，自己总结出来 的，部分代码和语言是引述，但是千真万确是自己总结出来的。有错误之处和不详细不清楚的地方还请大家指出，我也是初学者，所以难免会有错误的地方，希望大 家共同讨论。        </div><img src ="http://www.blogjava.net/redcoatjk/aggbug/351200.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/redcoatjk/" target="_blank">redcoatjk</a> 2011-05-27 18:15 <a href="http://www.blogjava.net/redcoatjk/archive/2011/05/27/351200.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]JNDI到底是什么，有什么作用</title><link>http://www.blogjava.net/redcoatjk/archive/2011/05/22/350754.html</link><dc:creator>redcoatjk</dc:creator><author>redcoatjk</author><pubDate>Sun, 22 May 2011 02:34:00 GMT</pubDate><guid>http://www.blogjava.net/redcoatjk/archive/2011/05/22/350754.html</guid><wfw:comment>http://www.blogjava.net/redcoatjk/comments/350754.html</wfw:comment><comments>http://www.blogjava.net/redcoatjk/archive/2011/05/22/350754.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/redcoatjk/comments/commentRss/350754.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/redcoatjk/services/trackbacks/350754.html</trackback:ping><description><![CDATA[摘自:<div>http://shitou521.iteye.com/blog/696006</div><div><h3>JNDI的一篇文章</h3> <p style="padding-right: 0px; padding-left: 0px; font-size: 16px; padding-bottom: 0px; margin: 0px 0px 0.5em; color: black; line-height: 1.5em; padding-top: 10px;">前端时间总是在搞不清JNDI到底是干什么，虽然是一值在用，却不知道他最初出现的原因，用来，说不清是用来干什么，下面我相信介能解开这个迷雾里。</p>  <div>【<strong style="font-weight: bold;">转贴一篇</strong>】&nbsp;<br />------------&nbsp;<br />JNDI是 Java 命名与目录接口（Java Naming and Directory Interface），在J2EE规范中是重要的规范之一，不少专家认为，没有透彻理解JNDI的意义和作用，就没有真正掌握J2EE特别是EJB的知识。&nbsp;<br /><br />那么，JNDI到底起什么作用？<span style="color: red;">//带着问题看文章是最有效的</span>&nbsp;<br /><br />要了解JNDI的作用，我们可以从&#8220;如果不用JNDI我们怎样做？用了JNDI后我们又将怎样做？&#8221;这个问题来探讨。&nbsp;<br /><br />没有JNDI的做法：&nbsp;<br /><br />程序员开发时，知道要开发访问MySQL数据库的应用，于是将一个对 MySQL JDBC 驱动程序类的引用进行了编码，并通过使用适当的 JDBC URL 连接到数据库。&nbsp;<br />就像以下代码这样：&nbsp;<br /><br /><div style="font-size: 12px; margin-left: 9px; width: 694px; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; background-color: transparent; padding: 1px;"> <div> <div style="font-weight: bold; margin: 0px; color: black; text-align: left; padding: 3px;">Java代码&nbsp; </div> </div> <ol style="padding-right: 0px; padding-left: 0px; font-size: 1em; padding-bottom: 2px; margin: 0px 0px 1px; color: #2b91af; line-height: 1.4em; padding-top: 2px; background-color: #ffffff; border: #d1d7dc 1px solid;"><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;"><span style="color: black;">Connection&nbsp;conn=</span><span style="font-weight: bold; color: #7f0055;">null</span><span style="color: black;">;&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;"><span style="font-weight: bold; color: #7f0055;">try</span><span style="color: black;">&nbsp;{&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;Class.forName(<span style="color: blue;">"com.mysql.jdbc.Driver"</span><span style="color: black;">,&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055;">true</span><span style="color: black;">,&nbsp;Thread.currentThread().getContextClassLoader());&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;conn=DriverManager.&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;getConnection(<span style="color: blue;">"jdbc:mysql://MyDBServer?user=qingfeng&amp;password=mingyue"</span><span style="color: black;">);&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;......&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;conn.close();&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">}&nbsp;<span style="font-weight: bold; color: #7f0055;">catch</span><span style="color: black;">(Exception&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">}&nbsp;<span style="font-weight: bold; color: #7f0055;">finally</span><span style="color: black;">&nbsp;{&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055;">if</span><span style="color: black;">(conn!=</span><span style="font-weight: bold; color: #7f0055;">null</span><span style="color: black;">)&nbsp;{&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055;">try</span><span style="color: black;">&nbsp;{&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.close();&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="font-weight: bold; color: #7f0055;">catch</span><span style="color: black;">(SQLException&nbsp;e)&nbsp;{}&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">}&nbsp;&nbsp;</span></li></ol> </div> <br /><br /><br />这是传统的做法，也是以前非Java程序员（如Delphi、VB等）常见的做法。这种做法一般在小规模的开发过程中不会产生问题，只要程序员熟悉Java语言、了解JDBC技术和MySQL，可以很快开发出相应的应用程序。&nbsp;<br /><br />没有JNDI的做法存在的问题：&nbsp;<br />1、数据库服务器名称MyDBServer 、用户名和口令都可能需要改变，由此引发JDBC URL需要修改；&nbsp;<br />2、数据库可能改用别的产品，如改用DB2或者Oracle，引发JDBC驱动程序包和类名需要修改；&nbsp;<br />3、随着实际使用终端的增加，原配置的连接池参数可能需要调整；&nbsp;<br />4、......&nbsp;<br /><br />解决办法：&nbsp;<br />程 序员应该不需要关心&#8220;具体的数据库后台是什么？JDBC驱动程序是什么？JDBC  URL格式是什么？访问数据库的用户名和口令是什么？&#8221;等等这些问题，程序员编写的程序应该没有对 JDBC  驱动程序的引用，没有服务器名称，没有用户名称或口令 &#8212;&#8212;  甚至没有数据库池或连接管理。而是把这些问题交给J2EE容器来配置和管理，程序员只需要对这些配置和管理进行引用即可。&nbsp;<br /><br />由此，就有了JNDI。&nbsp;<br /><span style="color: red;">//看的出来，是为了一个最最核心的问题：是为了解耦，是为了开发出更加可维护、可扩展//的系统</span>&nbsp;<br /><br />用了JNDI之后的做法：&nbsp;<br />首先，<span style="color: red;">在在J2EE容器中配置JNDI参数</span>，定义一个数据源，也就是JDBC引用参数，给这个数据源设置一个名称；然后，在程序中，通过数据源名称引用数据源从而访问后台数据库。&nbsp;<br /><br /><span style="color: red;">//红色的字可以看出，JNDI是由j2ee容器提供的功能</span>&nbsp;<br /><br />具体操作如下（以JBoss为例）：&nbsp;<br />1、配置数据源&nbsp;<br />在JBoss  的 D:\jboss420GA\docs\examples\jca 文件夹下面，有很多不同数据库引用的数据源定义模板。将其中的  mysql-ds.xml 文件Copy到你使用的服务器下，如 D:\jboss420GA\server\default\deploy。&nbsp;<br />修改 mysql-ds.xml 文件的内容，使之能通过JDBC正确访问你的MySQL数据库，如下：&nbsp;<br /><div style="font-size: 12px; margin-left: 9px; width: 694px; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; background-color: transparent; padding: 1px;"> <div> <div style="font-weight: bold; margin: 0px; color: black; text-align: left; padding: 3px;">Java代码&nbsp; </div> </div> <ol style="padding-right: 0px; padding-left: 0px; font-size: 1em; padding-bottom: 2px; margin: 0px 0px 1px; color: #2b91af; line-height: 1.4em; padding-top: 2px; background-color: #ffffff; border: #d1d7dc 1px solid;"><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;"><span style="color: black;">&lt;?xml&nbsp;version=</span><span style="color: blue;">"1.0"</span><span style="color: black;">&nbsp;encoding=</span><span style="color: blue;">"UTF-8"</span><span style="color: black;">?&gt;&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&lt;datasources&gt;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&lt;local-tx-datasource&gt;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&lt;jndi-name&gt;MySqlDS&lt;/jndi-name&gt;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&lt;connection-url&gt;jdbc:mysql:<span style="color: #008200;">//localhost:3306/lw&lt;/connection-url&gt;</span><span style="color: black;">&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&lt;driver-<span style="font-weight: bold; color: #7f0055;">class</span><span style="color: black;">&gt;com.mysql.jdbc.Driver&lt;/driver-</span><span style="font-weight: bold; color: #7f0055;">class</span><span style="color: black;">&gt;&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&lt;user-name&gt;root&lt;/user-name&gt;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&lt;password&gt;rootpassword&lt;/password&gt;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&lt;exception-sorter-<span style="font-weight: bold; color: #7f0055;">class</span><span style="color: black;">-name&gt;&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&lt;/exception-sorter-<span style="font-weight: bold; color: #7f0055;">class</span><span style="color: black;">-name&gt;&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&lt;metadata&gt;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;type-mapping&gt;mySQL&lt;/type-mapping&gt;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/metadata&gt;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&lt;/local-tx-datasource&gt;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&lt;/datasources&gt;&nbsp;&nbsp;</span></li></ol> </div> <br /><br />这里，定义了一个名为MySqlDS的数据源，其参数包括JDBC的URL，驱动类名，用户名及密码等。&nbsp;<br /><br />2、在程序中引用数据源：&nbsp;<br /><br /><div style="font-size: 12px; margin-left: 9px; width: 694px; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; background-color: transparent; padding: 1px;"> <div> <div style="font-weight: bold; margin: 0px; color: black; text-align: left; padding: 3px;">Java代码&nbsp; </div> </div> <ol style="padding-right: 0px; padding-left: 0px; font-size: 1em; padding-bottom: 2px; margin: 0px 0px 1px; color: #2b91af; line-height: 1.4em; padding-top: 2px; background-color: #ffffff; border: #d1d7dc 1px solid;"><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;"><span style="color: black;">Connection&nbsp;conn=</span><span style="font-weight: bold; color: #7f0055;">null</span><span style="color: black;">;&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;"><span style="font-weight: bold; color: #7f0055;">try</span><span style="color: black;">&nbsp;{&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;Context&nbsp;ctx=<span style="font-weight: bold; color: #7f0055;">new</span><span style="color: black;">&nbsp;InitialContext();&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;Object&nbsp;datasourceRef=ctx.lookup(<span style="color: blue;">"java:MySqlDS"</span><span style="color: black;">);&nbsp;</span><span style="color: #008200;">//引用数据源</span><span style="color: black;">&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;DataSource&nbsp;ds=(Datasource)datasourceRef;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;conn=ds.getConnection();&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;......&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;c.close();&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">}&nbsp;<span style="font-weight: bold; color: #7f0055;">catch</span><span style="color: black;">(Exception&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">}&nbsp;<span style="font-weight: bold; color: #7f0055;">finally</span><span style="color: black;">&nbsp;{&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055;">if</span><span style="color: black;">(conn!=</span><span style="font-weight: bold; color: #7f0055;">null</span><span style="color: black;">)&nbsp;{&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055;">try</span><span style="color: black;">&nbsp;{&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.close();&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="font-weight: bold; color: #7f0055;">catch</span><span style="color: black;">(SQLException&nbsp;e)&nbsp;{&nbsp;}&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">}&nbsp;&nbsp;</span></li></ol> </div> <br /><br />直接使用JDBC或者通过JNDI引用数据源的编程代码量相差无几，但是现在的程序可以不用关心具体JDBC参数了。<span style="color: red;">//解藕了，可扩展了</span>&nbsp;<br />在系统部署后，如果数据库的相关参数变更，只需要重新配置 mysql-ds.xml 修改其中的JDBC参数，只要保证数据源的名称不变，那么程序源代码就无需修改。&nbsp;<br /><br />由此可见，<span style="color: red;">JNDI避免了程序与数据库之间的紧耦合，使应用更加易于配置、易于部署</span>。&nbsp;<br /><br />JNDI的扩展：&nbsp;<br />JNDI在满足了数据源配置的要求的基础上，还进一步扩充了作用：所有与系统外部的资源的引用，都可以通过JNDI定义和引用。&nbsp;<br /><span style="color: red;">//注意什么叫资源</span>&nbsp;<br /><br />所以，在J2EE规范中，J2EE 中的资源并不局限于 JDBC 数据源。引用的类型有很多，其中包括资源引用（已经讨论过）、环境实体和 EJB 引用。特别是 EJB 引用，它暴露了 JNDI 在 J2EE 中的另外一项关键角色：查找其他应用程序组件。&nbsp;<br /><br />EJB  的 JNDI 引用非常类似于 JDBC  资源的引用。在服务趋于转换的环境中，这是一种很有效的方法。可以对应用程序架构中所得到的所有组件进行这类配置管理，从 EJB 组件到 JMS  队列和主题，再到简单配置字符串或其他对象，这可以降低随时间的推移服务变更所产生的维护成本，同时还可以简化部署，减少集成工作。外部资源&#8221;。&nbsp;<br /><br /><br />总结：&nbsp;<br /><span style="color: red;">J2EE 规范要求所有 J2EE 容器都要提供 JNDI 规范的实现。</span><span style="color: red;">//sun 果然喜欢制定规范</span>JNDI  在 J2EE 中的角色就是&#8220;交换机&#8221; &#8212;&#8212; J2EE 组件在运行时间接地查找其他组件、资源或服务的通用机制。在多数情况下，提供 JNDI  供应者的容器可以充当有限的数据存储，这样管理员就可以设置应用程序的执行属性，并让其他应用程序引用这些属性（Java 管理扩展（Java  Management Extensions，JMX）也可以用作这个目的）。JNDI 在 J2EE  应用程序中的主要角色就是提供间接层，这样组件就可以发现所需要的资源，而不用了解这些间接性。&nbsp;<br /><br />在 J2EE 中，JNDI 是把 J2EE 应用程序合在一起的粘合剂，JNDI 提供的间接寻址允许跨企业交付可伸缩的、功能强大且很灵活的应用程序。这是 J2EE 的承诺，而且经过一些计划和预先考虑，这个承诺是完全可以实现的。&nbsp;<br /><br /><strong style="font-weight: bold;"><br />从上面的文章中可以看出：&nbsp;<br />1、JNDI 提出的目的是为了解藕，是为了开发更加容易维护，容易扩展，容易部署的应用。&nbsp;<br />2、JNDI 是一个sun提出的一个规范(类似于jdbc),具体的实现是各个j2ee容器提供商，sun&nbsp;&nbsp; 只是要求，j2ee容器必须有JNDI这样的功能。&nbsp;<br />3、JNDI 在j2ee系统中的角色是&#8220;交换机&#8221;，是J2EE组件在运行时间接地查找其他组件、资源或服务的通用机制。&nbsp;<br />4、JNDI 是通过资源的名字来查找的，资源的名字在整个j2ee应用中(j2ee容器中)是唯一的。&nbsp;<br /><br />再转一篇文章：&nbsp;<br /></strong><br /><br />JNDI全称 Java Naming and Directory Interface&nbsp;<br />JNDI 是Java平台的一个标准扩展，提供了一组接口、类和关于命名空间的概念。如同其它很多Java技术一样，JDNI是provider-based的技 术，暴露了一个API和一个服务供应接口（SPI）。这意味着任何基于名字的技术都能通过JNDI而提供服务，只要JNDI支持这项技术。JNDI目前所 支持的技术包括LDAP、CORBA Common Object  Service（COS）名字服务、RMI、NDS、DNS、Windows注册表等等。很多J2EE技术，包括EJB都依靠JNDI来组织和定位实体。&nbsp;<br />JDNI通过绑定的概念将对象和名称联系起来。在一个文件系统中，文件名被绑定给文件。在DNS中，一个IP地址绑定一个URL。在目录服务中，一个对象名被绑定给一个对象实体。&nbsp;<br />JNDI 中的一组绑定作为上下文来引用。每个上下文暴露的一组操作是一致的。例如，每个上下文提供了一个查找操作，返回指定名字的相应对象。每个上下文都提供了绑 定和撤除绑定名字到某个对象的操作。JNDI使用通用的方式来暴露命名空间，即使用分层上下文以及使用相同命名语法的子上下文。&nbsp;<br />jndi的用途：&nbsp;<br />1。你可以用jndi来得到object类的属性&nbsp;<br />如：&nbsp;<br /><div style="font-size: 12px; margin-left: 9px; width: 694px; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; background-color: transparent; padding: 1px;"> <div> <div style="font-weight: bold; margin: 0px; color: black; text-align: left; padding: 3px;">Java代码&nbsp; </div> </div> <ol style="padding-right: 0px; padding-left: 0px; font-size: 1em; padding-bottom: 2px; margin: 0px 0px 1px; color: #2b91af; line-height: 1.4em; padding-top: 2px; background-color: #ffffff; border: #d1d7dc 1px solid;"><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;"><span style="color: black;">Attribute&nbsp;attr&nbsp;=directory.getAttributes(personName).get(</span><span style="color: blue;">"email"</span><span style="color: black;">);&nbsp;&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">String&nbsp;email&nbsp;=&nbsp;(String)attr.get();&nbsp;&nbsp;&nbsp;</span></li></ol> </div> <br />2。你可以用jndi来搜索对象&nbsp;<br />如：&nbsp;<br /><div style="font-size: 12px; margin-left: 9px; width: 694px; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; background-color: transparent; padding: 1px;"> <div> <div style="font-weight: bold; margin: 0px; color: black; text-align: left; padding: 3px;">Java代码&nbsp; </div> </div> <ol style="padding-right: 0px; padding-left: 0px; font-size: 1em; padding-bottom: 2px; margin: 0px 0px 1px; color: #2b91af; line-height: 1.4em; padding-top: 2px; background-color: #ffffff; border: #d1d7dc 1px solid;"><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;"><span style="color: black;">foxes&nbsp;=&nbsp;directory.search(</span><span style="color: blue;">"o=Wiz,c=US"</span><span style="color: black;">,&nbsp;</span><span style="color: blue;">"sn=Fox"</span><span style="color: black;">,&nbsp;controls);&nbsp;&nbsp;&nbsp;</span></span></li></ol> </div> <br />查找谁的名字叫Fox在wiz部门的员工？&nbsp;<br />3。你可以用jndi通过naming/directory服务查询像printers和databases的对象&nbsp;<br />如：查询 Printer&nbsp;<br /><div style="font-size: 12px; margin-left: 9px; width: 694px; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; background-color: transparent; padding: 1px;"> <div> <div style="font-weight: bold; margin: 0px; color: black; text-align: left; padding: 3px;">Java代码&nbsp; </div> </div> <ol style="padding-right: 0px; padding-left: 0px; font-size: 1em; padding-bottom: 2px; margin: 0px 0px 1px; color: #2b91af; line-height: 1.4em; padding-top: 2px; background-color: #ffffff; border: #d1d7dc 1px solid;"><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;"><span style="color: black;">Printer&nbsp;printer&nbsp;=&nbsp;(Printer)namespace.lookup(printerName);&nbsp;&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">printer.print(document);&nbsp;&nbsp;&nbsp;</span></li></ol> </div> <br />4。你可以用jndi列表出命名空间的特殊级别的内容&nbsp;<br />如：&nbsp;<br /><div style="font-size: 12px; margin-left: 9px; width: 694px; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; background-color: transparent; padding: 1px;"> <div> <div style="font-weight: bold; margin: 0px; color: black; text-align: left; padding: 3px;">Java代码&nbsp; </div> </div> <ol style="padding-right: 0px; padding-left: 0px; font-size: 1em; padding-bottom: 2px; margin: 0px 0px 1px; color: #2b91af; line-height: 1.4em; padding-top: 2px; background-color: #ffffff; border: #d1d7dc 1px solid;"><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;"><span style="color: black;">NamingEnumeration&nbsp;list&nbsp;=&nbsp;namespace.list(</span><span style="color: blue;">"o=Widget,&nbsp;c=US"</span><span style="color: black;">;&nbsp;&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;"><span style="font-weight: bold; color: #7f0055;">while</span><span style="color: black;">&nbsp;(list.hasMore())&nbsp;{&nbsp;&nbsp;&nbsp;</span></span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">NameClassPair&nbsp;entry&nbsp;=&nbsp;(NameClassPair)list.next();&nbsp;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">display(entry.getName(),&nbsp;entry.getClassName());&nbsp;&nbsp;&nbsp;</span></li><li style="padding-right: 0px; padding-left: 10px; font-size: 1em; padding-bottom: 0px; margin: 0px 0px 0px 38px; border-left: #d1d7dc 1px solid; line-height: 18px; padding-top: 0px; background-color: #fafafa;"><span style="color: black;">}&nbsp;&nbsp; <br /></span></li></ol> </div> </div></div><img src ="http://www.blogjava.net/redcoatjk/aggbug/350754.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/redcoatjk/" target="_blank">redcoatjk</a> 2011-05-22 10:34 <a href="http://www.blogjava.net/redcoatjk/archive/2011/05/22/350754.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>