﻿<?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-黄小二的讀書筆記-文章分类-J2SE</title><link>http://www.blogjava.net/kiant/category/34637.html</link><description>有才而性缓定属大才，有智而气和斯为大智。人偏狭我受之以宽容，人险仄我持之以坦荡。缓事宜急干，敏则有功；急事宜缓办，忙则多措。
--李叔同</description><language>zh-cn</language><lastBuildDate>Mon, 05 Apr 2010 16:24:29 GMT</lastBuildDate><pubDate>Mon, 05 Apr 2010 16:24:29 GMT</pubDate><ttl>60</ttl><item><title>使用 dom4j 解析 XML</title><link>http://www.blogjava.net/kiant/articles/317474.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Mon, 05 Apr 2010 02:23:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/317474.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/317474.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/317474.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/317474.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/317474.html</trackback:ping><description><![CDATA[<br />
dom4j 是一种解析 XML 文档的开放源代码 XML 框架。<br />
<br />
推荐文章<br />
使用 dom4j 解析 XML&nbsp;&nbsp;&nbsp;&nbsp;http://www.ibm.com/developerworks/cn/xml/x-dom4j.html<br />
<br />
dom4j&nbsp;[百度百科]&nbsp;&nbsp;&nbsp;&nbsp;http://baike.baidu.com/view/1460716.htm<br />
<br />
官网&nbsp;&nbsp;&nbsp;&nbsp;http://www.dom4j.org/
<img src ="http://www.blogjava.net/kiant/aggbug/317474.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2010-04-05 10:23 <a href="http://www.blogjava.net/kiant/articles/317474.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2 读书笔记（一） 前言、安装、配置</title><link>http://www.blogjava.net/kiant/articles/270126.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Mon, 11 May 2009 15:11:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/270126.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/270126.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/270126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/270126.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/270126.html</trackback:ping><description><![CDATA[<br />
内容多来自书本、网络和教程，在此特别感谢：<br />
Struts2权威指南--基于WebWork核心的MVC开发&nbsp; 作者：李刚<br />
浪曦_Struts2应用开发系列&nbsp;讲师：风中叶<br />
<a href="http://www.blogjava.net/max/category/16130.html" target="_blank">Max On Java 的 Struts 2.0 系列</a><br />
<br />
<strong>一、前言</strong><br />
Struts2 是 WebWork 的升级。它同样适用拦截器作为处理（Advice），以用户的业务逻辑控制器为目标，创建一个控制器代理。<br />
<br />
Tomcat 文件服务器配置项目：
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">&lt;</span><span style="color: #000000">Context&nbsp;path</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">/deviantART</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;docBase</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">D:\workstation\deviantART\WebRoot</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;reloadable</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">true</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">/&gt;<br />
&lt;/Host&gt;</span></div>
<em style="font-size: 10pt">conf/server.xml<br />
</em>path：URL虚拟路径<br />
docBase：对应的物理地址<br />
reloadable：是否自动更新，发布后建议为 false <br />
<br />
<fieldset><legend>Tips:</legend>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在 MyEclipse 等开发工具中，会将 src 源代码目录里的任何改动都自动编译到 \WebRoot\WEB-INF 目录下，简化了操作。</fieldset> <br />
<br />
<hr />
<strong>二、安装<br />
</strong><br />
Struts2 的几个核心 jar 文件：<br />
commons-logging-1.0.4.jar、<br />
freemarker-2.3.8.jar、<br />
ognl-2.6.11.jar、<br />
struts2-core-2.0.11.jar、<br />
xwork-2.0.4.jar <br />
<br />
<br />
<hr />
<strong>三、配置：<br />
<br />
</strong>编辑Web应用的web.xml配置文件，配置Struts 2的核心Filter。
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="GBK"</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">web-app&nbsp;</span><span style="color: #ff0000">version</span><span style="color: #0000ff">="2.4"</span><span style="color: #ff0000">&nbsp;xmlns</span><span style="color: #0000ff">="http://java.sun.com/xml/ns/j2ee"</span><span style="color: #ff0000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"<br />
</span><span style="color: #ff0000">&nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation</span><span style="color: #0000ff">="http://java.sun.com/xml/ns/j2ee&nbsp;http://java.sun.&nbsp;com/xml/ns/j2ee/web-app_2_4.xsd"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<br />
<img alt="" src="http://www.blogjava.net/Images/dot.gif" /><img alt="" src="http://www.blogjava.net/Images/dot.gif" /><img alt="" src="http://www.blogjava.net/Images/dot.gif" /><img alt="" src="http://www.blogjava.net/Images/dot.gif" /><br />
<br />
</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;定义Struts&nbsp;2的FilterDispatcher的Filter&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;定义核心Filter的名字&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000">&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">struts2</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;定义核心Filter的实现类&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000">&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">org.apache.Struts2.dispatcher.FilterDispatcher</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">&nbsp;filter-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<br />
</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;FilterDispatcher用来初始化Struts&nbsp;2并且处理所有的Web请求&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Struts2</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">/*</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #0000ff">&nbsp;&lt;/</span><span style="color: #800000">filter-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">web-app</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span></div>
<em>web.xml</em> <br />
<br />
配置Action
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="GBK"</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000"><br />
</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;指定Struts&nbsp;2配置文件的DTD信息&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;!</span><span style="color: #ff00ff">DOCTYPE&nbsp;struts&nbsp;PUBLIC"-//Apache&nbsp;Software&nbsp;Foundation//DTD&nbsp;Struts&nbsp;Configuration&nbsp;2.0//EN""http://struts.apache.org/dtds/struts-2.0.dtd"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">struts</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color: #800000">package&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="strutsqs"</span><span style="color: #ff0000">&nbsp;extends</span><span style="color: #0000ff">="struts-default"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color: #800000">action&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Login"</span><span style="color: #ff0000">&nbsp;class</span><span style="color: #0000ff">="lee.LoginAction"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">result&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="error"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">/error.jsp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">result</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">result&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="success"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">/welcome.jsp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">result</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #0000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/</span><span style="color: #800000">action</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #0000ff">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/</span><span style="color: #800000">package</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">struts</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span></div>
<em>struts.xml</em><br />
<br />
Struts 2还有一个配置 Struts 2全局属性的 Properties 文件：
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">#指定Struts&nbsp;2处于开发状态<br />
struts.devMode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000"><br />
#指定当Struts&nbsp;2配置文件改变后，Web框架是否重新加载Struts&nbsp;2配置文件<br />
struts.configuration.xml.reload</span><span style="color: #000000">=</span><span style="color: #0000ff">true</span><span style="color: #000000">&nbsp;</span></div>
<em>struts.properties</em><br />
<br />
<br />
ps. 更详细的请阅览<br />
<a href="http://www.blogjava.net/max/archive/2006/10/10/74353.html" target="_blank">&nbsp;Max On Java 的 Struts 2.0 系列：为Struts 2.0做好准备</a>&nbsp;<br />
&nbsp; 
<img src ="http://www.blogjava.net/kiant/aggbug/270126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2009-05-11 23:11 <a href="http://www.blogjava.net/kiant/articles/270126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>'Hibernate 完全手册' 读书笔记（五） 事务和并发、缓存、高级特性、附录</title><link>http://www.blogjava.net/kiant/articles/265417.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Tue, 14 Apr 2009 01:56:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/265417.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/265417.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/265417.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/265417.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/265417.html</trackback:ping><description><![CDATA[<p><br />
<strong>1、事务</strong></p>
<p>1-1、类别</p>
<p>● 本地事务<br />
&nbsp; 如果事务只和一个资源管理器有关，则为本地事物。在本地事务中，事务管理器只是将事务的管理委托给底层的资源管理器。</p>
<p><br />
● 分布式事务<br />
&nbsp; 分布式事务和多个可能不同的资源管理器以一种协调的方式进行交互。</p>
<p><br />
1-2、Java 中事务处理</p>
<p>&nbsp; JDBC 事务：由底层数据库事务管理器控制，操作比较简单，但是不适合控制多个应用程序组件的事务，并且没有传播的上下问。</p>
<p>&nbsp; JTA 和 JTS：Java 事务 API 和 Java 事务服务，可以跨越多个组件和数据库使用事务。在应用程序使用 JTA 控制事务操作时，需要从 JNDI 上下文中获取 UserTranscation 和数据源。<br />
UserTranscation ut = (UserTranscation) ctx.lookup("UserTranscation");</p>
<p><br />
1-3、Hibernate 事务<br />
&nbsp; <br />
● 基于 JDBC </p>
<p>&nbsp; Transcation 事务对象必须从 Session 中获取，即事务必须和一个 Session 相关联。</p>
<p>采用 Hibernate 内置的 current session 和上下文管理。<br />
&lt;property name="current_session_context_class"&gt;thread&lt;/property&gt;<br />
...<br />
sessionFactory.getCurrentSession().beginTranscation();</p>
<p><br />
● 基于 JTA</p>
<p>&nbsp; 提供了跨 Session 的事务管理能力。<br />
使用 SessionFactory.getCurrentSession() 方法简化事务上下文的传播，即在事务绑定 Session。</p>
<p><br />
&nbsp; 虽然一个 Session 范围内可以存在多个事务操作，但是 Hibernate 并不支持嵌套的事务模型。<br />
tx1<br />
tx2<br />
...<br />
tx2.commit();</p>
<p>//数据库操作，操作无效<br />
tx1.commit();</p>
<p>&nbsp;</p>
<p>
<hr />
<strong>2、并发控制</strong>
<p>&nbsp;</p>
<p>&nbsp; 如果事务都是串行执行，则许多资源将处于空闲状态。为了充分利用资源，发挥数据库共享资源的优势，必须允许多个事务并发地执行。</p>
<p>&nbsp; 在单处理机系统中，事务并发执行实际上是这些并行事务轮流交叉执行，即交叉并发方式，并不是真正的并行执行。在多处理机系统中，每个处理机运行一个事务，实现事务真正意义上的并存运行，即同时并发方式。</p>
<p>&nbsp; 当多个用户并发地存取数据库时，就会产生多个事务同时存取同一数据的情况。所以，必须实现一个控制系统，使一个事务所做的修改不会对其他事务所做的修改产生负面影响，这就是并发控制。</p>
<p>&nbsp; <br />
2-1、封锁</p>
<p>&nbsp; 对并发操作进行的正确调度，防止并发操作破坏了事务的隔离性。采用封锁技术，事务 T 可以向系统发出请求，对某个对象例如表、记录加锁，在事务 T 释放锁之前，其他事务不能更新这些数据对象。<br />
&nbsp;<br />
&nbsp; 基本的封锁有： <br />
排他锁（Exclusive Locks，X 锁）：写锁或者独占锁。<br />
共享锁（Share Locks，S 锁）：读锁。允许和其他事务一起读取数据对象D，但不能对D 做任何修改。</p>
<p><br />
2-2、事务隔离</p>
<p>&nbsp; 使用封锁技术，事务对申请的资源加锁，但是会影响数据库性能。根据数据对象封锁的程度，可以分成多种不同的事务隔离级别。</p>
<p>&nbsp; 数据并发执行时，产生不一致的现象：</p>
<p>丢失更新（Lost Update）<br />
&nbsp; 两个事务读入同一数据并修改，然后提交修改，T2 提交的结果破坏了 T1 提交的结果，导致 T1 的修改丢失。</p>
<p>② 不可重复读<br />
&nbsp; 事务T1 读取数据后，事务T2 执行了同一数据的跟新操作，使得事务 T1 无法再现前一次读取的结果。<br />
&nbsp;&nbsp;&nbsp; 事务1 读取某一数据后，事务2 对该数据作了修改，事务1 再次读取时，得到数据和前一次不一致。<br />
&nbsp;&nbsp;&nbsp; ① 事务1 读取某一些记录后，事务2 删除了同一数据源的部分数据，事务1 再次读取时，发现某些记录丢失。<br />
&nbsp;&nbsp;&nbsp; ① 事务1 读取某一些记录后，事务2 插入了同一数据源的新数据，事务1 再次读取时，发现某些记录增加。</p>
<p>③ 读&#8220;脏&#8221;数据<br />
&nbsp; 事务T1 修改某一数据，并将其写回物理数据库。事务T2 读取同一数据后，事务T1 由于某种原因被撤销，数据库将已经修改的数据恢复原值，导致事务T2 保持的数据和数据库中的数据产生了不一致。</p>
<p><br />
&nbsp; ANSI SQL-99 标准定义了下列隔离级别：</p>
<p>● 未提交读（Read Uncommitted）：隔离事务的最低级别，只能保证不会读取到物理上损坏的数据。H:1；允许产生：①②③</p>
<p>● 已提交读（Read Committed）：常见数据库引擎的默认级别，保证一个事务不会读取到另一个事务已修改但未提交的数据。H:2；允许产生：①②</p>
<p>● 可重复读（Repeatable Read）：保证一个事务不能更新已经由另一个事务读取但是未提交的数据。相当于应用中的已提交读和乐观并发控制。H:4；允许产生：①</p>
<p>● 可串行化（Serializable）：隔离事务的最高级别，事务之间完全隔离。系统开销最大。H:8；允许产生：</p>
<p><br />
&nbsp; 在数据库中，可以手工设置事务的隔离级别。<br />
&nbsp; Hibernate 在配置文件中声明事务的隔离级别，Hibenate 获取数据库连接后，将根据隔离级别自动设置数据库连接为指定的事务隔离级别。<br />
&lt;property name="connection.isolation"&gt;8&lt;/property&gt;</p>
<p><br />
2-3、并发控制类型</p>
<p>&nbsp; 根据使用的锁定策略和隔离等级，可以把事务的并发控制分为两种：</p>
<p>① 悲观并发控制<br />
&nbsp; <br />
&nbsp; 用户使用时锁定数据。主要应用于数据争用激烈的环境中，以及发生并发冲突时用锁保护数据的成本低于回滚事务成本的环境中。</p>
<p>&nbsp; Hibernate 的悲观锁定不在内存中锁定数据，由底层数据库负责完成。</p>
<p><br />
② 乐观并发控制<br />
&nbsp; <br />
&nbsp; 用户读取数据时不锁定数据。当一个用户更新数据时，系统将进行检查该用户读取数据后其他用户是否更改了该数据，是则产生一个错误，一般情况下，收到错误信息的用户将回滚事务并重新开始。主要用户数据争用不大，且偶尔回滚事务的成本低于读取数据时锁定数据的成本的环境中。</p>
<p>&nbsp; Hibernate 中使用元素 version 和 timestamp 实现乐观并发控制模式的版本控制，并提供多种编程方式。版本是数据库表中的一个字段，可以是一个递增的整数，也可以是一个时间戳，它们对应 Java 持久化类的一个属性。事务提交成功后，Hibernate 自动修改版本号。如果另外一个事务同时访问同一数据，若发现提交前的版本号和事前载入的版本号有出入，则认为发生了冲突，事务停止执行，撤销操作，并抛出异常。应用程序必须捕捉该异常并做出一定的处理。</p>
<p>⒈应用程序级别的版本控制<br />
⒉长生命周期会话的自动化版本控制<br />
⒊托管对象的自动化版本控制<br />
⒋定制自动化版本控制</p>
<p>&nbsp;</p>
<p>
<hr />
<strong>3、Hibernate 缓存</strong>
<p>&nbsp;</p>
<p>&nbsp; Hibernate 提供两级缓存架构，第一级缓存是 Session 内的缓存，第二级缓存是一个可插拔的缓存，能够借助第三方的组件实现。如果应用程序中经常使用同样的条件查询数据，还可以使用查询缓存来提高查询效率。</p>
<p>&nbsp; 针对缓存的范围，可以将 Hibernate 持久层缓存分为三个层次：</p>
<p>① 事务级缓存<br />
&nbsp; <br />
&nbsp; 缓存只能被当前事务访问。缓存的生命周期以来与事务的生命周期。事务缓存由 Session 实现。一个 Session 的缓存的内容只有在本 Session 实例范围内可用。</p>
<p>② 应用级缓存</p>
<p>&nbsp; 缓存在某个应用范围内被所有事务共享。缓存的生命周期依赖于应用程序的生命周期。应用级缓存由 SessionFactory 实现，Session 实例由其创建，并共享其缓存。</p>
<p>③ 分布式缓存</p>
<p>&nbsp; 集群环境中，缓存被一个 JVM 或多个 JVM 的进程共享。分布式缓存由多个应用级的缓存实例组成，缓存中的数据被复制到集群环境中的每个 JVM 节点，JVM 间通过远程通信来保证缓存中数据的一致性。</p>
<p><br />
3-1、缓存查询结果</p>
<p>&nbsp; 经常使用同样的条件查询数据，则可使用查询缓存。查询缓存需要和二级缓存联合使用，在二级缓存中，可以专门为查询缓存开辟一个命名缓存区域。查询缓存启动后将创建两个缓存区域，org.hibernate.cache.StandardQueryCache 实现保存查询结果集；org.hibernate.cache.UpdateTimestampsCache 实现保存最近更新的查询表的时间戳。</p>
<p>&lt;property name="cache.use_query_cache"&gt;true&lt;/propery&gt;</p>
<p>//使用查询缓存<br />
query.setCacheable(true);</p>
<p>//给查询缓存指定特定的命名缓存区域<br />
query.setCacheRegion("queryCache");</p>
<p>//如果其他进程更新了结果集，强行刷新缓冲区域<br />
query.setCacheMode(CacheMode.REFRESH);</p>
<p>//刷新某个或全部的缓存<br />
SessionFactory.evictQueries() 方法</p>
<p>&nbsp;</p>
<p>
<hr />
<strong>4、高级特性</strong>
<p>&nbsp;</p>
<p>4-1、数据库连接池 ConnectionProvider</p>
<p>&nbsp; J2SE 环境中使用建议。</p>
<p><br />
4-2、使用数据源 <br />
&nbsp; Hibernate 中，DatasourceConnectionProvider 实现了 ConnectionProvider 接口并封装了数据源的获取方法，充当了 Hibernate 和数据源间的适配器。</p>
<p>&nbsp; J2EE 环境中使用建议。</p>
<p><br />
4-3、过滤数据<br />
&nbsp; <br />
&nbsp; 把公共的数据过滤条件提取出来。从 Hibernate 3.0 开始，可以利用 Hibernate Filter 对某个类或集合附加预先定义的过滤条件，在查询时过滤指定条件的数据。该过滤器是全局有效的，使用时候，还可以指定特定参数。</p>
<p><br />
4-4、批量处理<br />
&nbsp; <br />
&nbsp; 批量处理引发异常的根源在于缓存中保存了过多的持久化实例而耗尽内存。</p>
<p>① 应用程序级别的批处理</p>
<p>&nbsp; 指定 Hibernate 处理 SQL 语句时，必须积累到指定数量后再向数据库提交操作。<br />
&nbsp; &lt;property name="jdbc.batch_size"&gt;20&lt;/property&gt;</p>
<p><br />
② 无状态 Session（StatelessSession）</p>
<p>&nbsp; StatelessSession 接口没有持久化上下文，也不负责持久化实例的生命周期，没有一级缓存，操作也不会影响到二级和查询缓存。</p>
<p><br />
③ 使用 DML 风格的 HQL 语句绕过内存直接进行数据处理</p>
<p>&nbsp; "delete Product p where p.id &gt; :id"</p>
<p><br />
4-4、延迟加载</p>
<p>&nbsp; 设置延迟加载的属性和集合只能在该实例依附的 Session 范围内被访问，会话关闭后，实例从持久态转为托管态，再次访问该实例的一些属性时候，有可能会抛出 LazyInitializationException 异常。</p>
<p>① 属性延迟加载（大对象）<br />
② 持久化类延迟加载<br />
③ 集合延迟加载</p>
<p><br />
4-5、数据抓取策略（Fetching strategies）</p>
<p>&nbsp; 可以在 Hibernate 中设定相应的数据抓取策略，减少系统产生的数据库查询操作，优化系统性能。</p>
<p>&nbsp; 在 Hibernate 中，延迟（lazy）定义了一种契约，用来表示托管状态实例中那些数据是有效的，而抓取（fetch）是用来调整 Hibernate 性能的。</p>
<p><br />
4-5、监控性能<br />
&nbsp; org.hibernate.stat 包提供的工具类。</p>
<p><br />
<hr />
<strong>5、附录</strong>
<p>&nbsp;5-1、XML 元数据<br />
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://doc.javanb.com/hibernate-reference-3-2-0-zh/ch18s02.html" target="_blank">18.2. XML映射元数据 - Hibernate reference 3.2.0 ga 正式版中文参考手册<br />
</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://doc.javanb.com/hibernate-reference-3-2-0-zh/ch18s03.html" target="_blank">18.3. 操作XML数据 （通过dom4j会话读入和更新应用程序中的XML文档）</a><br />
<br />
5-2、开源工具箱</p>
<p>CownewStudio 是一个基于 Eclipse 的 Hibernate 正向建模辅助工具。通过它用户能以图形化的方式建立对象模型，然后根据模型生成持久化类、映射文件和数据库表。</p>
<p>JDBMonitor。模拟一个 JDBC 驱动来代替真正的 JDBC 驱动，截取应用程序对数据库的操作，并以合适的方式记录下来，提供性能分析的来源和依据。</p>
<p>&nbsp;</p>
<br />
 <img src ="http://www.blogjava.net/kiant/aggbug/265417.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2009-04-14 09:56 <a href="http://www.blogjava.net/kiant/articles/265417.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>'Hibernate 完全手册' 读书笔记（四） 查询语言</title><link>http://www.blogjava.net/kiant/articles/265072.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Sat, 11 Apr 2009 18:11:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/265072.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/265072.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/265072.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/265072.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/265072.html</trackback:ping><description><![CDATA[<p><br />
<strong>1、查询返回</strong></p>
<p>● 查询语句可以返回多个对象或属性，存放在 Object[] 队列中。</p>
<p>● 将查询结果的所有属性都存放在一个 List 对象中：<br />
&nbsp; select new list(xxx.xxxx,xx.xx) .....<br />
这里的 new list 是实例化 java.util.ArraryList 对象。</p>
<p>● 将查询结果封装成一个安全的 Java 对象<br />
&nbsp; select new EncCustomer(xx.xxx, xx.xx)....</p>
<p>● 将查询结果封装成 Map 对象（利用别名）<br />
&nbsp; select new map(xx.xxx as aaaa, xx.xxxx as bb) .....<br />
.....<br />
&nbsp; Map obj = (Map)list.get(i);<br />
&nbsp; obj.get("aaaa");&nbsp; <br />
&nbsp; obj.get("bb");</p>
<p><br />
● distinct 删除重复数据</p>
<p><br />
<strong>
<hr />
2、参数绑定机制</strong></p>
<p>● <br />
&nbsp; q.setParameter("name", name);<br />
&nbsp; Hibernate 能根据参数值的 Java 类型推断出对应的映射类型，对于日期类型，如 java.util.Date 类型，会对应多种映射类型，这时候需要显示指定。<br />
&nbsp; q.setParameter("date", Hibernate.DATE);</p>
<p>● <br />
&nbsp; q.setProperties(obj);<br />
&nbsp; 根据 obj 的属性名对应 HQL 语义中定义的命名参数进行查询。</p>
<p><br />
<strong>
<hr />
3、HQL 子查询<br />
</strong>&nbsp;&nbsp; 用于子查询的集合函数 size()、minIndex()、maxIndex()、minElement()、maxElement() 和 elements()。</p>
<p><br />
<strong>
<hr />
4、集合过滤</strong><br />
&nbsp; 对于某持久化对象的 items 属性内元素性能优化（过滤集合内数据、排序等）。</p>
<p>&nbsp; Session.createFilter(object, string);<br />
&nbsp; 返回是 Query 类型<br />
&nbsp; 参数 object 是持久化对象的集合。<br />
&nbsp; 参数 string 是 HQL 的过滤条件</p>
<p>//过滤 prod 的集合 items<br />
List items = session.createFilter(prod.getItems(),<br />
&nbsp;"this.unitCost&lt;100 order by this.ListPrice desc").List();<br />
//绑定过滤的结果 itmes 到属性<br />
prod.setItems(items);</p>
<p><br />
<strong>
<hr />
5、条件查询 QBC</strong></p>
<p>5-1、Restrictions 过滤结果集</p>
<p><br />
5-2、结果集排序<br />
&nbsp;.addOrder(Order.asc("name"))<br />
&nbsp;.addOrder(Order.desc("category"))<br />
&nbsp;.list();</p>
<p><br />
5-3、createCriteria() 关联查询<br />
&nbsp; List list = sess.createCriteria(Product.class)<br />
&nbsp;.add(Restrictions.like("name", "%o%"))<br />
&nbsp;.createCriteria("items")&nbsp;&nbsp;<br />
&nbsp;.add(Restrictions.ge("listPrice", new Float(100.0))<br />
&nbsp;.list();<br />
//返回一个新的 Criteria 实例，该实例引用 items 集合中的元素，并且为该集合元素增加了元素属性 listPrice 大于等于 100.0 的过滤条件。</p>
<p>或者使用别名<br />
&nbsp;.createAlias("items", "ite")<br />
&nbsp;.add(Restrictions.ge("ite.listPrice", new Float(100.0))</p>
<p><br />
5-4、设置加载策略<br />
&nbsp;.setFetchMode("items", FetchMode.EAGER) <br />
&nbsp;.list();</p>
<p>&nbsp; DEFAULT：默认<br />
&nbsp; EAGER/JOIN：强制立即加载<br />
&nbsp; LAZY/SELECT：强制延迟加载</p>
<p><br />
5-5、聚合和分组&nbsp; org.hibernate.criterion.Projections </p>
<p>&nbsp;.setProjection(Projections.rowCount())<br />
&nbsp;.uniqueResult()；</p>
<p>&nbsp;.add(Projections.groupProperty("imagePath"))<br />
&nbsp;.list();</p>
<p><br />
5-6、离线与子查询</p>
<p>&nbsp; 离线查询方式在 Session 范围之外定义一个离线查询，然后使用任意的 Session 执行查询。该方法主要通过 org.hibernate.criterion.DetachedCriteria 类实现。</p>
<p><br />
<strong>
<hr />
6、Native SQL 查询</strong></p>
<p>&nbsp;&nbsp; 应用程序中使用与数据库相关的 SQL 查询语句</p>
<p>6-1、Native SQL 应用程序接口</p>
<p>&nbsp; 主要使用 SQLQuery.addEntity() 实现返回结果为实体的查询，SQLQuery.addScalar() 则返回标量值。<br />
&nbsp; SQLQuery.addJoin(String alias, String path) 用于将映射对象所关联的实体或集合对应起来。</p>
<p>&nbsp; <br />
6-2、命名查询<br />
&nbsp; sess.getNamedQuery(string);</p>
<p>&nbsp; 在 xml 文件中使用 &lt;! [CDATA []] &gt; 元表示其中的内容是区分其他元素定义的纯文本。例如： &lt; 符号。</p>
<p><br />
6-3、使用存储过程<br />
&nbsp; Hibernate 3.0 以上的版本已经支持和利用存储过程来进行查询，存储过程返回的参数是标量与实体，这里可以利用返回类型的定义将存储过程返回的参数映射到对象的属性中。</p>
<p>&lt;sql-query name="productQuery" callable="true"&gt;<br />
&nbsp; &lt;return alias="prod" class="petstore.domain.Product"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;return-property name="productId" column="PRODUCTID" /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;return-property name="description" column="DESCRIPTION" /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;return-property name="name" column="NAME" /&gt;<br />
&nbsp; &lt;/return&gt;<br />
&nbsp; {? = call getProduct(?)}<br />
&lt;/sql-query&gt;</p>
<p>List list = query.list();</p>
<p>&nbsp;</p>
 <img src ="http://www.blogjava.net/kiant/aggbug/265072.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2009-04-12 02:11 <a href="http://www.blogjava.net/kiant/articles/265072.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>'Hibernate 完全手册' 读书笔记（三） 映射、操作对象</title><link>http://www.blogjava.net/kiant/articles/265049.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Sat, 11 Apr 2009 12:46:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/265049.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/265049.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/265049.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/265049.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/265049.html</trackback:ping><description><![CDATA[<p><br />
<strong>1、对象关系映射</strong></p>
<p>1-1、单向多对一关联</p>
<p>&nbsp;产品和分类的关系：多个不同产品属于同一种分类。<br />
private Category category；<br />
&lt;many-to-one name="category" column="categoryId" not-null="true" /&gt;</p>
<p><br />
1-2、一对多映射<br />
private Set products = new HashSet();<br />
&lt;set name="products"&nbsp;&nbsp;&lt;!--Category 中集合属性名称为 products--&gt;<br />
&nbsp; table="product"&nbsp;&nbsp;&lt;!--集合属性对应表的名称为 product--&gt;<br />
&nbsp; schema="test"&nbsp;&nbsp;&nbsp;&lt;!--表的 schema 名称为 test--&gt;<br />
&nbsp; lazy="true"&nbsp;&nbsp;&nbsp;&lt;!--此集合采用延时加载策略--&gt;<br />
&nbsp; inverse="true"&nbsp;&nbsp;&lt;!--由关联属性的另一方作为关联的主控方--&gt;<br />
&nbsp; cascade="delete"&nbsp;&nbsp;&lt;!--采用级联删除，当 Category 被删除时关联的此集合内容也将被删除--&gt;<br />
&nbsp; sort="natural"&nbsp;&nbsp;&lt;!--自然排序集合内容--&gt;<br />
&nbsp; order-by="productId asc"&nbsp;&lt;!--按 productId 字段升序排列集合内容--&gt;<br />
&nbsp; &gt;<br />
&nbsp; &lt;key column="category_fk" /&gt;<br />
&nbsp; <br />
&nbsp; &lt;one-to-many class="petstore.domain.Product" /&gt;<br />
&lt;/set&gt;<br />
</p>
<p><br />
1-3、继承映射<br />
</p>
<p><br />
<hr />
<strong>2、Hibernate 操作对象</strong><br />
<br />
2-1、对象的三种状态</p>
<p>● 瞬时态（Transient）--VO（Value Ojbect）<br />
&nbsp; 对象实例产生到被 JVM 垃圾回收为止并不受 Hibernate 框架管理。</p>
<p>● 持久态（Persistent）--PO（Persistent Ojbect）<br />
&nbsp; 对象实例被 Hibernate 框架管理，该对象可能是刚被保存的，或刚从数据库中被加载的。Hibernate 会检测处于持久态的对象任何改动，在当前操作单元执行完毕将对象与数据库同步，即将对象的属性保存到数据库映射对应的字段中。简单点说就是该实体对象与 session 发生关系，而且处于 session 的有效期内。<br />
&nbsp; <br />
● 托管态（Detached）--VO（Value Ojbect）<br />
&nbsp; 与持久对象关联的 Session 被关闭后，对象就变为托管的，可继续被修改。托管对象如果重新关联到某个新的 Session 上，会再次变为持久的，同时改动也将会被持久化到数据库。这个期间的转变过程可以看作是应用程序事务，即中间会给用户思考时间的长时间运行的操作单元。<br />
&nbsp; 处于托管态对象具有与数据库表记录间的联系（持久化标识，identifier）。</p>
<p><br />
<br />
2-2、对象操作的应用程序接口</p>
<p>● 修改对象</p>
<p>&nbsp; 对于已经持久化的对象，不需要调用某个特定的方法就可以实现修改持久化，因为 Hibernate 会自动调用 flush() 方法保证与数据库的同步。</p>
<p>&nbsp; 对于处于托管状态的实例，Hibernate 通过提供 Session.update() 或 Session.merge() 方法，重新关联托管实例。但是需要注意的是：如果具有持久化标识（identifier）的对象之前已经被另一个会话连接（secondSession）装载了，应用程序关联操作会发生异常。</p>
<p>&nbsp; 使用 merge() 方法时，用户不必考虑 session 的状态，可随时将修改保存到数据库中。例如：Session 中存在相同标识的持久化实例时，Hibernate 便会根据用户给出的对象状态覆盖原有的持久化实例的状态。</p>
<p>&nbsp; 另外，Hibernate 还提供了 saveOrUpdate()方法，它即可分配新持久化标识（identifier），保存瞬时（transient）对象，又可更新/重新关联托管的（identifier）实例。</p>
<p><br />
● 删除对象<br />
&nbsp; 通过 HQL 语句，调用重载的 delete()，可以一次删除多个对象。<br />
&nbsp; session.delete("from Customer as c where c.customerId &lt;3");</p>
<p><br />
● 查询对象<br />
&nbsp; 已知对象表示符值查询<br />
&nbsp; 对象标识符未知查询 HQL<br />
&nbsp; 根据某些特定条件查询 QBC，Query By Criteria<br />
&nbsp; 按详例查询 QBE，Query By Example<br />
&nbsp; 调用数据库查询 native SQL</p>
<p>&nbsp; 查询条件参数 ？ 查询条件参数索引，由 0 开始。<br />
&nbsp; 查询条件实名 ：name<br />
&nbsp; 外置命名查询</p>
<p>&nbsp;&nbsp;&nbsp; 在映射文件定义查询语句，将程序与查询语句分离：<br />
&nbsp;&nbsp;&nbsp; &lt;query name="CategoryById"<br />
&nbsp;&lt;! [CDATA[<br />
&nbsp;&nbsp;from Category c where c.categoryId&gt;? ]]&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/query&gt;</p>
<p>&nbsp;&nbsp;&nbsp; 程序调用：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query q = sess.getNamedQuery("CategoryById");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q.setLong(0, name);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List cats = q.List();<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp; 用 Query 提供的 iterate() 方法遍历查询结果，如果查询的结果在 session 或二级缓存（second-level cache）中，那么使用 iterate() 方法可以得到更好的性能。</p>
<p>&nbsp; 如果 JDBC 驱动支持可滚动的 ResuleSet，Query 接口可以使用 ScrollableResults，允许你在查询结果中灵活移动（需要保持数据库连接和游标 cursor 处于抑制打开状态）。</p>
<p>ScrollableResults cates = q.scroll();<br />
cates.first()<br />
cates.scroll(5);</p>
<p><br />
● cascade 和 inverse 级联操作</p>
<p>inverse<br />
&nbsp; 只对 set，one-to-many（或 many-to-many）有效，对于 many-to-one，one-to-one 无效<br />
&nbsp; 对集合起整体作用</p>
<p>cascade<br />
&nbsp; 对关系标记都有效<br />
&nbsp; 对集合的一个元素起作用，如果集合为空，那么 cascade 不会引发关联操作<br />
&nbsp; <br />
&nbsp; 作用时机：在 flush 时（commit 会自动执行 flush），hibernate 会自行判断每个 set 是否有变化，对有变化的 set 执行相应的 SQL，if (inverse) return。即：cascade 在前，inverse 在后。</p>
<p>异常：<br />
org.hibernate.exception.ConstraintViolationException: could not insert</p>
<p>原因是 category_fk 字段约束不能为空，而在新建的 Product 对象时插入了空值，而且关联关系由 Caterogy 对象维持，而被关联的 Product 对象不知道自己与哪个 Category 对象关联。说到底就是 pro 对象的 categoryId 值为空。</p>
<p>&nbsp;</p>
  <img src ="http://www.blogjava.net/kiant/aggbug/265049.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2009-04-11 20:46 <a href="http://www.blogjava.net/kiant/articles/265049.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>'Hibernate 完全手册' 读书笔记（二） 初识、体系、对象标识符、配置、映射类型</title><link>http://www.blogjava.net/kiant/articles/264993.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Sat, 11 Apr 2009 02:45:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/264993.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/264993.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/264993.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/264993.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/264993.html</trackback:ping><description><![CDATA[<p><strong>1、使用 Hibernate 操作数据库</strong></p>
<p>1-1、使用 ThreadLocal 控制 Session</p>
<p>&nbsp;&nbsp;&nbsp; 应用程序根据配置文件构建应用程序运行的环境，建立全局范围内的 SessionFactory 对象。其内部包含了 Hibernate 运行的全部细节，是产生 Session 的工厂，它是线程安全的，只能在系统启动时实例化一次，系统运行期间不可修改。</p>
<p>&nbsp;&nbsp;&nbsp; Session 对象是 Hibernate 操作数据的核心，数据库的操作、对象生命周期的管理、应用事务的划分，都需要在 Session 对象中完成。Session&nbsp; 对象不是线程安全的，如果试图让多个线程同时使用一个 Session 对象，将会产生数据混乱，造成数据库的数据不一致。而且频繁开关 Session 是巨大的系统消耗。</p>
<p>&nbsp;&nbsp;&nbsp; 为了安全地使用 Session 对象，需要应用 Java 语言中的线程绑定机制--ThreadLocal，它代表一个线程的私有存取空间，能够隔离多线程环境中的并发机制，减少 Session 对象的创建和销毁次数，降低系统资源浪费。<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Code_Closed_Image_104728" onclick="this.style.display='none'; Code_Closed_Text_104728.style.display='none'; Code_Open_Image_104728.style.display='inline'; Code_Open_Text_104728.style.display='inline';" height="16" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_104728" style="display: none" onclick="this.style.display='none'; Code_Open_Text_104728.style.display='none'; Code_Closed_Image_104728.style.display='inline'; Code_Closed_Text_104728.style.display='inline';" height="16" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_104728" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">HibernateSessionFactory</span><span id="Code_Open_Text_104728" style="display: none"><br />
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span><img id="Codehighlighter1_37_757_Open_Image" onclick="this.style.display='none'; Codehighlighter1_37_757_Open_Text.style.display='none'; Codehighlighter1_37_757_Closed_Image.style.display='inline'; Codehighlighter1_37_757_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_37_757_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_37_757_Closed_Text.style.display='none'; Codehighlighter1_37_757_Open_Image.style.display='inline'; Codehighlighter1_37_757_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;HibernateSessionFactory&nbsp;</span><span id="Codehighlighter1_37_757_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_37_757_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><img alt="" src="http://www.blogjava.net/Images/dot.gif" /><br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;ThreadLocal</span><span style="color: #000000">&lt;</span><span style="color: #000000">Session</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;threadLocal&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ThreadLocal</span><span style="color: #000000">&lt;</span><span style="color: #000000">Session</span><span style="color: #000000">&gt;</span><span style="color: #000000">();<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><img alt="" src="http://www.blogjava.net/Images/dot.gif" /><br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img id="Codehighlighter1_198_513_Open_Image" onclick="this.style.display='none'; Codehighlighter1_198_513_Open_Text.style.display='none'; Codehighlighter1_198_513_Closed_Image.style.display='inline'; Codehighlighter1_198_513_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_198_513_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_198_513_Closed_Text.style.display='none'; Codehighlighter1_198_513_Open_Image.style.display='inline'; Codehighlighter1_198_513_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;Session&nbsp;getSession()&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;HibernateException&nbsp;</span><span id="Codehighlighter1_198_513_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_198_513_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session&nbsp;session&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Session)&nbsp;threadLocal.get();<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img id="Codehighlighter1_300_482_Open_Image" onclick="this.style.display='none'; Codehighlighter1_300_482_Open_Text.style.display='none'; Codehighlighter1_300_482_Closed_Image.style.display='inline'; Codehighlighter1_300_482_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_300_482_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_300_482_Closed_Text.style.display='none'; Codehighlighter1_300_482_Open_Image.style.display='inline'; Codehighlighter1_300_482_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(session&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">||</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">!</span><span style="color: #000000">session.isOpen())&nbsp;</span><span id="Codehighlighter1_300_482_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_300_482_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img id="Codehighlighter1_333_367_Open_Image" onclick="this.style.display='none'; Codehighlighter1_333_367_Open_Text.style.display='none'; Codehighlighter1_333_367_Closed_Image.style.display='inline'; Codehighlighter1_333_367_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_333_367_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_333_367_Closed_Text.style.display='none'; Codehighlighter1_333_367_Open_Image.style.display='inline'; Codehighlighter1_333_367_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(sessionFactory&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)&nbsp;</span><span id="Codehighlighter1_333_367_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_333_367_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rebuildSessionFactory();<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(sessionFactory&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">?</span><span style="color: #000000">&nbsp;sessionFactory.openSession()<br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threadLocal.set(session);<br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;session;<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><img alt="" src="http://www.blogjava.net/Images/dot.gif" />.<br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img id="Codehighlighter1_586_749_Open_Image" onclick="this.style.display='none'; Codehighlighter1_586_749_Open_Text.style.display='none'; Codehighlighter1_586_749_Closed_Image.style.display='inline'; Codehighlighter1_586_749_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_586_749_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_586_749_Closed_Text.style.display='none'; Codehighlighter1_586_749_Open_Image.style.display='inline'; Codehighlighter1_586_749_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;closeSession()&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;HibernateException&nbsp;</span><span id="Codehighlighter1_586_749_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_586_749_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">24</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session&nbsp;session&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Session)&nbsp;threadLocal.get();<br />
</span><span style="color: #008080">25</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threadLocal.set(</span><span style="color: #0000ff">null</span><span style="color: #000000">);<br />
</span><span style="color: #008080">26</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080">27</span><span style="color: #000000"><img id="Codehighlighter1_704_743_Open_Image" onclick="this.style.display='none'; Codehighlighter1_704_743_Open_Text.style.display='none'; Codehighlighter1_704_743_Closed_Image.style.display='inline'; Codehighlighter1_704_743_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_704_743_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_704_743_Closed_Text.style.display='none'; Codehighlighter1_704_743_Open_Image.style.display='inline'; Codehighlighter1_704_743_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(session&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)&nbsp;</span><span id="Codehighlighter1_704_743_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_704_743_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">28</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.close();<br />
</span><span style="color: #008080">29</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">30</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">31</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080">32</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><img alt="" src="http://www.blogjava.net/Images/dot.gif" /><br />
</span><span style="color: #008080">33</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080">34</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></span></div>
<br />
<br />
1-2、建立数据库结构 </p>
<p>&nbsp;&nbsp;&nbsp; 使用 Hibernate 时，设计生成数据库表结构的方式分成两种。</p>
<p>1、手工用 SQL 语句设计数据表结构</p>
<p>2、使用 Hibernate 根据映射文件自动构建数据库模式<br />
&nbsp;&nbsp;&nbsp; hibernate.cfg.xml:<br />
&nbsp;&lt;property name="hbm2dll.auto"&gt;creat&lt;/property&gt;<br />
&nbsp;&lt;property name="show_sql"&gt;true&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; log4j.properties<br />
&nbsp;log4j.logger.org.hibernate.tool.hbm2dll=debug</p>
<p>Hibernate 自行管理的数据库表结构：<br />
● none：不产生任何动作。<br />
● create：在应用启动时，自动生成数据库表结构并导入到数据库中。<br />
● create-drop：同 create，但在应用关闭时，删除已生成的数据库表结构；此方式常在测试时使用。<br />
● update：在应用启动时，检查持久化类和映射文件的改变，更新数据库表结构，比如：持久化类添加一个属性后，Hibernate 能自动添加对应字段到对应的数据库表中。<br />
</p>
<br />
<br />
3、使用 Session 操作数据库<br />
&nbsp; Hibernate 能自动管理系统中的持久化类和数据库模式，通过 Session 对象实现对象模型和关系模型的相互操作。<br />
Session 提供数据访问的接口：<br />
● get()：从数据库获取数据对象，不存在时则返回 null。<br />
● load()：从数据库获取数据对象，不存在时则抛出异常。<br />
● createQuery()：根据条件查询数据对象。<br />
● save()、update()、delete() 等方法。
<p>&nbsp;</p>
<p><br />
<hr />
<br />
<strong>2、Hibernate 基本组件接口</strong> <br />
<br />
<p>● Configuration（org.hibernate.cfg.Configuration）<br />
&nbsp; Hibernate 应用的入口，它使用配置文件初始化运行环境，是 SessionFactory 的工厂。通常情况下，一个应用程序中只允许创建一个单例的 Configuration 实例。</p>
<p>● SessionFactory（org.hibernate.SessionFactory）<br />
&nbsp; 是一个线程安全的高速缓存，其中包含了单一数据库和已编译映射文件的元数据，在运行环境不可改变。它是 Session 的工厂，并能从 ConnectionProvider 中获取 JDBC 连接。它可能持有一个可选的能在进程级别或者集群级别事务间重用的数据缓存（二级缓存）。SessionFactory 从 Configuration 中获取，在一个应用范围中，不允许改变。</p>
<p>● Session（org.hibernate.Session）<br />
&nbsp; 单线程的短生命周期的对象，是应用程序和持久化存储的一次对话。封装了一个 JDBC 连接，也是 Transaction 的工厂。它保持一个持久化对象的强制缓存（一级缓存），用来遍历对象图或者根据标识符查询对象。Session 提供了一系列方法，可以方便地实现对象持久化操作。</p>
<p>● Transcation（org.hibernate.Transcation）<br />
&nbsp; 可选，单线程、短生命周期的对象，应用程序用它来表示一批任务的原子操作。是底层 JDBC，JTA 或者 CORBA 事务的抽象。一个 Session 在某些情况下可能跨越多个 Transcation 事务。</p>
<p>● ConnectionProvider（org.hibernate.connection.ConnectionProvider）<br />
&nbsp; 可选，JDBC 连接的工厂和连接池，是底层 Datasource 或 DriverManager 的抽象应用，对应用程序不可见。可扩展实现。</p>
<p>● TranscationFactory（org.hibernate.TranscationFactory）<br />
&nbsp; 可选，事务实例工厂。对应用程序不可见。可扩展实现。</p>
<p><br />
&nbsp; 在最小集合应用框架中，应用程序直接使用 JDBC/JTA，并自行完成事务处理。<br />
&nbsp;conn = DriverManager.getConnection(xxx);<br />
&nbsp;conn.setAutoCommit(false);<br />
&nbsp;...<br />
&nbsp;conn.commit();</p>
<p><br />
<hr />
<br />
<strong>3、Hibernate 生命周期</strong><br />
<br />
① Configuration 对象根据配置文件的设置，读取属性配置信息。<br />
② Configuration 对象根据配置信息，按照映射文件、类缓存、集合缓存、监听器、事件的顺序依次读取并解析。<br />
③ 通过调用 Configuration 对象构建 SessionFactory。<br />
④ 调用 SessionFactory 实例获得 Session 对象。<br />
⑤ 启动事务。<br />
⑥ 提交事务。<br />
⑦ 关闭应用（Session 和 SessionFactory）。 <br />
<br />
<hr />
<br />
<strong>4、Hibernate 中对象的状态</strong> <br />
<br />
&nbsp; 为了区分持久化类的实例对象，根据对象和会话的关联状态，可以分为三种情况：
<p>&nbsp;</p>
<p>● 暂态状态。对象刚建立，还没有使用 Hibernate 进行保存。该对象在数据库中没有记录，也不在 session 缓存中。如果该对象是自动生成主键，则该对象的对象标识符为空。</p>
<p>● 持久化对象。对象已经通过 Hibernate 进行了持久化，数据库中已经存在对应的记录。如果该对象是自动生成主键，则该对象的对象标识符已被赋值。</p>
<p>● 托管对象。该对象是经过 Hibernate 保存过或者从数据库中取出的，但是与之关联的 session 已经被关闭。虽然它拥有对象标识符，且数据库中存在对应的记录，但是已经不再被 Hibernate 管理。<br />
</p>
<p><br />
ps.&nbsp;<a href="http://www.blogjava.net/vip01/archive/2007/01/08/92430.html" target="_blank">[转] PO BO VO DTO POJO DAO概念及其作用（附转换图）</a> <br />
</p>
<p><br />
<hr />
<br />
<strong>5、对象标识符</strong><br />
&nbsp; <br />
&nbsp; 关系数据库表的主键在 Java 应用环境中的体现。 <br />
<br />
<p>5-1、关系型数据库的主键生成机制<br />
&nbsp; 序列生成主键，整数<br />
&nbsp; 自动增长组件，整数<br />
&nbsp; 全局统一标识符 GUID（Globally Unique Identifier），字符串主键</p>
<p>&nbsp; <br />
5-2、Java 环境中的对象识别机制<br />
&nbsp; 引用比较，比地址 &#8220;==&#8221;<br />
&nbsp; 内容比较，比数据 equals() 方法</p>
<p><br />
5-3、Hibernate 对象识别符的作用<br />
&nbsp; 在生成 Java 对象时，给标识属性分配一个唯一的值，用于区分同一个类的多个不同的实例。体现在 Hibernate 中就是对象标识符。</p>
<p><br />
5-4、Hibernate 内置标识符生成器的使用方法<br />
&nbsp; org.hibernate.id.IdentifierGenerator 接口。</p>
<p>ps.&nbsp; <a href="http://aumy2008.blogbus.com/logs/13417260.html" target="_blank">映射对象标识符</a><br />
</p>
<p>5-5、使用复合主键时组合标识符的使用方法（常用于遗留的系统中）<br />
&nbsp; 嵌入式组合标识符/映射式组合标识符，映射多个主键字段和持久化类的多个属性。</p>
<p><br />
<hr />
<br />
<strong>6、配置 Hibernate</strong> <br />
<br />
6-1、配置方式<br />
&nbsp; 可编程还是文件配置方式 <br />
<br />
<p>Hibernate JDBC 配置属性<br />
&nbsp; hibernate.jdbc.fatch_size：指定 JDBC 抓取数据的数量大小，非零值<br />
&nbsp; hibernate.jdbc.batach_size：允许 Hibernate 使用 JDBC2 的批量更新，非零值，建议 5 到 30<br />
&nbsp; hibernate.jdbc.provider_class：自定义的 ConnectionProvider 类名，用于向 Hibernate 提供 JDBC 连接<br />
&nbsp; hibernate.jdbc.autocommit：确认是否开启 JDBC 自动提交功能，默认为 false 不自动提交</p>
<p><br />
6-2、方言<br />
&nbsp; 屏蔽底层数据库系统的方言机制，方便与数据库间迁移。<br />
&nbsp; MySQL：org.hibernate.dialect.MySQLDialect<br />
&nbsp; MySQL with InnoDB：org.hibernate.dialect.MySQLInnoDBDialect<br />
&nbsp; MySQL with MyISAM：org.hibernate.dialect.MySQLMyISAMDialect</p>
<p><br />
6-3、Hibernate 日志系统<br />
&nbsp; 使用 Log4J 作为&nbsp; Hibernate 的日志系统，需要将 Log4J 的库文件 log4j.jar 放置到类路径下（其发布包以包含 Log4J 的库文件）。然后编写日志配置文件 log4j.properties 并放到 classpath 路径中。</p>
<p>&nbsp; Log4J 中，几个日志输出级别的顺序是：只输出高于或等于 设定级别 的记录。<br />
trace &lt; debug &lt; info &lt; warn &lt; error &lt; fatal</p>
<p>&nbsp; 在开发模式中，可以选择 DEBUG 级别的输出；应用部署后，可以配置为 ERROR。&nbsp; <br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Code_Closed_Image_104409" onclick="this.style.display='none'; Code_Closed_Text_104409.style.display='none'; Code_Open_Image_104409.style.display='inline'; Code_Open_Text_104409.style.display='inline';" height="16" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_104409" style="display: none" onclick="this.style.display='none'; Code_Open_Text_104409.style.display='none'; Code_Closed_Image_104409.style.display='inline'; Code_Closed_Text_104409.style.display='inline';" height="16" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_104409" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">log4j.properties</span><span id="Code_Open_Text_104409" style="display: none"><br />
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">#设置日志根级别和输出路径<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.rootLogger</span><span style="color: #000000">=</span><span style="color: #000000">INFO,CONSOLE,FILE<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#日志输出路径——控制台<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.CONSOLE</span><span style="color: #000000">=</span><span style="color: #000000">org.apache.log4j.ConsoleAppender<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.stdout.Target</span><span style="color: #000000">=</span><span style="color: #000000">System.out<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.CONSOLE.layout</span><span style="color: #000000">=</span><span style="color: #000000">org.apache.log4j.PatternLayout<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.CONSOLE.layout.ConversionPattern</span><span style="color: #000000">=%</span><span style="color: #000000">d</span><span style="color: #000000">|</span><span style="color: #000000">ABSOLUTE&nbsp;</span><span style="color: #000000">%</span><span style="color: #000000">5p&nbsp;</span><span style="color: #000000">%</span><span style="color: #000000">c</span><span style="color: #000000">|</span><span style="color: #000000">1</span><span style="color: #000000">|</span><span style="color: #000000">:</span><span style="color: #000000">%</span><span style="color: #000000">L&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">%</span><span style="color: #000000">m</span><span style="color: #000000">%</span><span style="color: #000000">n<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#日志输出路径——文件<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.FILE</span><span style="color: #000000">=</span><span style="color: #000000">org.apache.log4j.FileAppender<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.FILE.File</span><span style="color: #000000">=</span><span style="color: #000000">hibernate.log<br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.FILE.layout</span><span style="color: #000000">=</span><span style="color: #000000">org.apache.log4j.PatternLayout<br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.FILE.layout.ConversionPattern</span><span style="color: #000000">=%</span><span style="color: #000000">d</span><span style="color: #000000">|</span><span style="color: #000000">ABSOLUTE&nbsp;</span><span style="color: #000000">%</span><span style="color: #000000">5p&nbsp;</span><span style="color: #000000">%</span><span style="color: #000000">c</span><span style="color: #000000">|</span><span style="color: #000000">1</span><span style="color: #000000">|</span><span style="color: #000000">:</span><span style="color: #000000">%</span><span style="color: #000000">L&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">%</span><span style="color: #000000">m</span><span style="color: #000000">%</span><span style="color: #000000">n<br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#日志输出级别<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.logger.org.hibernate</span><span style="color: #000000">=</span><span style="color: #000000">INFO<br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#日志输出类别<br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.logger.org.hibernate.hql.ast.AST</span><span style="color: #000000">=</span><span style="color: #000000">WARN<br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.logger.net.sf.ehcache</span><span style="color: #000000">=</span><span style="color: #000000">INFO<br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.logger.org.hibernate.SQL</span><span style="color: #000000">=</span><span style="color: #000000">DEBUG</span></span></div>
<br />
<br />
<hr />
<br />
<strong>7、Hibernate 映射类型</strong> <br />
<br />
</p>
<p><br />
7-1、时间日期映射类型（内置映射类型）</p>
<p>&nbsp; Java 语言提供了 java.util.Date 和 java.util.Calendar 两个类实现时间的运算。此外，JDBC 还提供了 java.util.Date 的三个扩展类 java.sql.Timestamp、java.sql.Time 和 java.sql.Date 分别对应标准 SQL 数据类型中的 TIMESPAME/DATETIME（时间日期）、TIME（时间）、DATE（日期）。</p>
<p>java.util.Date/java.sql.Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;H:date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL:DATE<br />
java.util.Time/java.sql.Time&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;H:time&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL:TIME<br />
java.util.Date/java.sql.Timestamp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;H:timestamp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL:TIMESTAMP/DATETIME<br />
java.util.Calendar&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;H:calendar&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL:TIMESTAMP/DATETIME<br />
java.util.Calendar&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; H:calendar_date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL:DATE</p>
<p><br />
7-2、自定义映射类型</p>
<p><br />
&nbsp;</p>
 <img src ="http://www.blogjava.net/kiant/aggbug/264993.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2009-04-11 10:45 <a href="http://www.blogjava.net/kiant/articles/264993.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>'Hibernate 完全手册' 读书笔记（一） 对象持久化基础</title><link>http://www.blogjava.net/kiant/articles/264770.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Fri, 10 Apr 2009 01:50:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/264770.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/264770.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/264770.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/264770.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/264770.html</trackback:ping><description><![CDATA[<p><br />
&nbsp;&nbsp;&nbsp; 数据库技术已经成为企业信息平台的核心。应用程序必须将业务相关的数据通过一定方式持久化到数据库，还应能够从数据库获取已有的数据，以适当的形式提供给客户或支撑系统的运行。</p>
<p>&nbsp;&nbsp;&nbsp; 关键点：如何高效地存取数据、简化编程模型、降低应用的复杂度</p>
<p>&nbsp;&nbsp;&nbsp; 在系统中引入持久层，负责所有相关数据的持久化操作，可以为整个应用系统提供一个高层、统一、安全、并发的数据持久机制。</p>
<p><br />
1、对象持久化技术</p>
<p>1-1、Java 对象序列化<br />
&nbsp;&nbsp;&nbsp; 序列化是 Java 语言中内置的轻量级数据持久化机制，该机制可以将任何实现了 java.io.Serializable 接口的对象转化为连续的字节流数据，保存在文件中，或者通过网络进行传输。这些数据日后可被还原为原先的对象状态。<br />
&nbsp;&nbsp;&nbsp; 缺点：局限性大，查询只能返回数据流的下一个对象，不提供部分的读取和更新，不提供对象的生命周期管理，只是简单的读取和写入，不提供并发和事务特性。</p>
<p>1-2、使用 JDBC<br />
&nbsp;&nbsp;&nbsp; JDBC（Java Database Connectivity）是用来访问关系数据库系统的标准 Java API。JDBC 只是提供访问数据的接口，其底层实现有特定的数据库厂商实现。<br />
&nbsp;&nbsp;&nbsp; 缺点：直接使用 JDBC 实现持久化时，SQL 语句和应用代码混杂在一起，逻辑混乱。另外直接使用 SQL 操作数据库，不是面向对象。</p>
<p>1-3、使用 JDO<br />
&nbsp;&nbsp;&nbsp; Java 数据对象（Java Data Object）是 JCP（Java Community Process）发布的一个规范，是 Java 对象持久化的标准。JDO 仅定义了标准的编程接口，而把关系映射的定义留给软件供应商实现。</p>
<p>1-4、实体 EJB<br />
&nbsp;&nbsp;&nbsp; 实体 EJB（Enterpise Java Bean）是 Java 领域的数据持久化标准。</p>
<p>1-5、对象关系映射<br />
&nbsp;&nbsp;&nbsp; 对象关系映射（Ojbect Relation Mapping）在对象模型和关系模型之间建立沟通的桥梁。ORM 技术封装了数据持久化的操作细节，为应用程序提供了一只访问的接口，使应用程序可以专注于业务逻辑的处理。它采用 POJO（Plain Old Java Object，简单的传统对象）作为域对象的表述，不涉及域对象之外的技术细节，降低的 ORM 技术的侵入性，实现简单，便于测试，具备高扩展性。</p>
<p><br />
2、对象关系映射模型<br />
&nbsp;&nbsp;&nbsp; 一个完整的对象关系映射框架，应具备以下四个方面：</p>
<p>①、一个元数据映射规范，负责持久化类、类属性的数据库表、字段的映射，实现对象和关系的语义连接。<br />
②、一组对象操作接口，用于完成数据的增加、删除、修改和更新等操作。<br />
③、一种面向对象的查询语言，该语言能理解继承、多态和关联等面向对象特性，实现基于对象的查询并在对象之间导航。<br />
④、一系列与数据库现关的技术实现和最佳实践，保证系统的完整性并提高系统的可用性和扩展性。比如：事务、缓存和数据抓取策略等。</p>
<p>对象模型（类、属性、关联）&nbsp;&nbsp; &lt;==&gt;&nbsp;&nbsp; 关系模型（表、字段、约束）</p>
<p>&nbsp;<br />
<br />
ps. &lt;Hibernate 完全手册&gt;<br />
ISBN 978-7-111-23764-8<br />
机械工业出版社<br />
侯志松 余周 郑焕 等编著</p>
 <img src ="http://www.blogjava.net/kiant/aggbug/264770.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2009-04-10 09:50 <a href="http://www.blogjava.net/kiant/articles/264770.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式相关（增加收集中...）</title><link>http://www.blogjava.net/kiant/articles/235788.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Tue, 21 Oct 2008 13:48:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/235788.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/235788.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/235788.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/235788.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/235788.html</trackback:ping><description><![CDATA[<br />
<br />
正则表达式是一个描述字符模式的对象。<br />
<br />
<br />
<br />
<strong><span style="font-size: 14pt;">Java 里的正则表达式</span></strong><br />
<br />
<a href="http://www.chinaitpower.com/A200507/2005-07-24/165713.html" target="_blank">简化范式匹配</a><br />
<br />
<a href="http://www.ibm.com/developerworks/cn/java/j-validating/" target="_blank">使用正则表达式验证本地化数据</a><br />
<br />
<a href="http://www.diybl.com/course/3_program/java/javajs/2008513/115720.html" target="_blank">java中常用的匹配正则表达式实例大全</a><br />
<br />
<a href="http://www.ibm.com/developerworks/cn/linux/l-sp/part2/" target="_blank">安全编程: 验证输入</a><br />
<br />
<br />
<strong><span style="font-size: 14pt;">JavaScript 里的正则表达式</span></strong><br />
<br />
<a target="_blank" href="http://www.cnblogs.com/temptation/archive/2007/07/10/812685.html">[转] 一些常用的正则表达式（JS）</a><br />
<br />
<a target="_blank" href="http://www.javaeye.com/topic/30728">JS的正则表达式</a><br />
<br />
<a target="_blank" href="http://blog.csdn.net/zxy6173/archive/2007/01/19/1488140.aspx">javaScript 中的正则表达式解析</a><br />
<br />
<br />
<br />
<br />
<img src ="http://www.blogjava.net/kiant/aggbug/235788.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2008-10-21 21:48 <a href="http://www.blogjava.net/kiant/articles/235788.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA 中各种数据库连接方式（补齐中）</title><link>http://www.blogjava.net/kiant/articles/234126.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Mon, 13 Oct 2008 15:39:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/234126.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/234126.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/234126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/234126.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/234126.html</trackback:ping><description><![CDATA[<br />
<br />
<strong>JDBC-ODBC 桥连</strong>（不需驱动）<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Connection conn = DriverManager.getConnection("jdbc:odbc:test", "sa", "love2you");<br />
<strong><br />
SQL SERVER 2005 直连</strong>&nbsp;&nbsp;&nbsp; [<a href="http://www.microsoft.com/downloads/details.aspx?familyid=C47053EB-3B64-4794-950D-81E1EC91C1BA&amp;displaylang=zh-cn" target="_blank">驱动下载</a>]<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Connection conn = DriverManager.getConnection(<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; "jdbc:sqlserver://10.0.0.99:1433;databaseName=deviantART", <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; "sa", <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; "love2you");<br />
<br />
<br />
转==============<br />
<p>常用 JDBC 驱动名字和 URL 列表 </p>
<p>ODBC&nbsp; driver<br />
sun.jdbc.odbc.JdbcOdbcDriver<br />
jdbc:odbc:name </p>
<p>用 COM.ibm.db2.jdbc.net.DB2Driver 连接到 DB2 数据库<br />
一个 DB2 URL 的示例:<br />
jdbc:db2://aServer.myCompany.com:50002/name </p>
<p>用 com.sybase.jdbc.SybDriver连接到 Sybase 数据库<br />
一个 Sybase URL 的示例:<br />
jdbc:sybase:Tds:aServer.myCompany.com:2025 </p>
<p>MySQL driver<br />
com.mysql.jdbc.Driver<br />
jdbc:mysql://hostname:3306/dbname?useUnicode=true&amp;amp;characterEncoding=GBK </p>
<p>Microsoft SQL Server Driver<br />
com.microsoft.jdbc.sqlserver.SQLServerDriver<br />
jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=WapSvc;User=sa;Password=pwd </p>
<p>Informix<br />
com.informix.jdbc.IfxDriver<br />
jdbc:informix-sqli://hostname:1526/dbname:INFORMIXSERVER=informixservername;user=username;password=password </p>
<p>Oracle<br />
oracle.jdbc.driver.OracleDriver<br />
jdbc:oracle:thin:@hostname:1521:&lt;SID&gt; </p>
<p>Postgresql<br />
org.postgresql.Driver<br />
jdbc:postgresql://localhost/soft </p>
<p>Apache Derby/Java DB<br />
org.apache.derby.jdbc.ClientDriver<br />
jdbc:derby://localhost:1527/databaseName;create=true </p>
<p>Access 是通过 ODBC 连接的. Excel 也可以. 甚至可以动态构造连接字符串: </p>
<p>这样可以直接连接到 Access 数据库文件. </p>
<p>jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\mydata.mdb </p>
<p>类似的 Excel 文件也可以用类似方法: </p>
<p>jdbc:odbc:Driver={Microsoft Excel Driver (*.xls)};DBQ=.\mydata.xls</p>
<p>&nbsp;</p>
<br />
<br />
<br />
  <img src ="http://www.blogjava.net/kiant/aggbug/234126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2008-10-13 23:39 <a href="http://www.blogjava.net/kiant/articles/234126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java程序设计语言（第4版） 笔记</title><link>http://www.blogjava.net/kiant/articles/233806.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Sat, 11 Oct 2008 15:28:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/233806.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/233806.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/233806.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/233806.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/233806.html</trackback:ping><description><![CDATA[The Java Programming Language (Four Edition)<br />
<br />
<br />
<a href="#1">
第一章&nbsp; 快速浏览</a><br />
<a href="#2">第二章&nbsp; 类与对象</a><br />
<a href="#3">第三章&nbsp; 类的扩展</a><br />
<a href="#4">第四章&nbsp; 接口</a><br />
<a href="#5">第五章&nbsp; 嵌套类和接口</a><br />
<a href="#6">第六章&nbsp; 枚举类型</a><br />
<a href="#7">第七章&nbsp; 语言符号、值和变量</a><br />
<a href="#8">第八章&nbsp; 包装器类</a><br />
<a href="#9">第九章&nbsp; 运算符和表达式</a><br />
<a href="#10">第十章&nbsp; 控制流</a><br />
<a href="#11">
第十一章&nbsp; 泛型类型</a><br />
<a href="#12">
第十二章&nbsp; 异常和断言</a><br />
<a href="#13">
第十三章&nbsp; 字符串与正则表达式</a><br />
<a href="#14">
第十四章&nbsp; 线程</a><br />
<a href="#15">
第十五章&nbsp; 注解</a><br />
<a href="#16">
第十六章&nbsp; 反射</a><br />
<a href="#17">
第十七章&nbsp; 垃圾回收器与内存</a><br />
<a href="#18">
第十八章&nbsp; 包</a><br />
<a href="#19">
第十九章&nbsp; 文档注释</a><br />
<a href="#20">
第二十章&nbsp; I/O 包</a><br />
<a href="#21">
第二十一章&nbsp; 集合</a><br />
<a href="#22">
第二十二章&nbsp; 各种常用工具</a><br />
<a href="#23">
第二十三章&nbsp; 系统编程</a><br />
<a href="#24">
第二十四章&nbsp; 国际化和本地化</a><br />
<a href="#25">
第二十五章&nbsp; 标准包</a><br />
<br />
<br />
<br />
<a name='1' id='1'></a><strong><span style="font-size: 14pt;">第一章&nbsp; 快速浏览</span></strong><br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="2" id="2"></a><strong><span style="font-size: 14pt;">第二章&nbsp; 类与对象</span></strong><br />
<br />
<strong>2.1、静态字段</strong><br />
&nbsp;&nbsp;&nbsp; 将字段声明为 static（静态字段），会使该字段只有一个实例，并且该实例能被该类的所有对象共享。<br />
&nbsp;&nbsp;&nbsp; 而且无论创建了该类的多少个实例，这个字段的都只有一份（内存中唯一？）。 <br />
<br />
<br />
<strong>2.2、初始化块</strong><br />
&nbsp;&nbsp;&nbsp; 字段另一种更复杂的初始化方式就是使用初始块。<br />
&nbsp;&nbsp;&nbsp; 初始块是一段出现在类声明中的语句块，它位于所有成员、构造器以及声明之外，它可以初始化对象的字段。<br />
&nbsp;&nbsp;&nbsp; 它们会被优先执行，就像它们放置在类的每一个构造器的开头那样，如果有多个块，它们会按照在类中出现的先后顺序执行。<br />
&nbsp;&nbsp;&nbsp; 只有当类的所有构造器都声明会抛出某个检查型异常时，它的初始块才可以抛出该异常。<br />
&nbsp;&nbsp;&nbsp; 应该审慎的使用初始块，用它们来表示那些构造器不能单独轻易完成的工作。<br />
<br />
例如<br />
&nbsp;&nbsp;&nbsp; public long idNum;<br />
&nbsp;&nbsp;&nbsp; private static long nextID = 0;<br />
<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; idNum = nextID++;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
<br />
<strong>2.3、静态初始化</strong><br />
&nbsp;&nbsp;&nbsp; 静态初始块被声明为 static，只能引用类的静态成员，不能抛出任何检查型异常。<br />
<br />
&nbsp;&nbsp;&nbsp; 类内部的初始化顺序是从前到后的，即代码中的&#8220;字段初始化器&#8221;或&#8220;初始块&#8221;都是按照从头到尾的顺序执行。<br />
<br />
例如：要确保静态字段 kk 在被访问前已初始化。<br />
&nbsp;&nbsp;&nbsp; static int kk = 9;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; static{<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("1");&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; static{<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println(kk);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
<br />
<strong>2.4、参数值</strong><br />
&nbsp;&nbsp;&nbsp; 准确的讲，Java 只有一种参数传递方式，即值传递，这样有利于保持简单，传递的也只是这个值的副本。<br />
<br />
<br />
<strong>2.5、使用方法来控制访问</strong><br />
&nbsp;&nbsp;&nbsp; 控制内部数据访问的方法有时被称为访问方法（accessor method），使用它们可以增强类数据的封装性。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="3" id="3"></a><strong><span style="font-size: 14pt;">第三章&nbsp; 类的扩展</span></strong><br />
<br />
<strong>3.1、扩展类的构造器</strong><br />
&nbsp;&nbsp;&nbsp; 扩展类的构造器必须通过隐式或显式地调用其超类的构造器，将继承而来的字段的构造工作委托给超类。<br />
构造器的顺序依赖：<br />
&nbsp;&nbsp;&nbsp; 1、调用其超类的构造器（同样 3步顺序递归调用到 Object）；<br />
&nbsp;&nbsp;&nbsp; 2、用这些字段的初始器和初始化块来初始化它们；<br />
&nbsp;&nbsp;&nbsp; 3、执行构造体。<br />
<br />
<br />
<strong>3.2、继承与重定义成员</strong><br />
&nbsp;&nbsp;&nbsp; ● 重载（overloading）：提供多个具有相同名字的方法，但是它们拥有可以彼此区分开的不同签名。<br />
&nbsp;&nbsp;&nbsp; 签名是由方法名及其参数的类型和数量组成的，它并不包含返回类型或者抛出的异常列表，并且我们无法基于这些因素来重载方法。<br />
&nbsp;&nbsp;&nbsp; 不同重载的方法可以有不同类型的返回值。<br />
<br />
&nbsp;&nbsp;&nbsp; ● 重写（overriding）：将方法的超类实现替换为自己的实现。其签名必须相同，但是他们的返回类型可以按照某种方式变换。<br />
&nbsp;&nbsp;&nbsp; 1、签名（方法名、参数类型和个数）必须相同。<br />
&nbsp;&nbsp;&nbsp; 2、返回类型：引用类型的可以返回超类所声明的子类（is a 关系），基本类型的返回必须相同。<br />
&nbsp;&nbsp;&nbsp; 3、访问修饰符：可以改变，但只能提供更多的访问权限，否则违反契约（不能替代超类实现）。<br />
&nbsp;&nbsp;&nbsp; 4、可以改变其他方法修饰符（synchronized、native和strictfp），static 则是必须保持一致，final 可以修饰重写的方法（超类被重写的方法则不能是 final）。<br />
&nbsp;&nbsp;&nbsp; 5、throws 子句：重写 throws 子句可以少于超类所列出的数量、或者更为具体，还可以没有任何 throws 子句。但是不能比超类的范围广（必须是多态兼容的）。<br />
&nbsp;&nbsp;&nbsp; 6、私有的方法：对于超类的 private 方法，子类没有重写，对私有方法的调用总会调用当前类中所声明的方法实现。<br />
<br />
例如：<br />
&nbsp;&nbsp;&nbsp; public static void name() throws IndexOutOfBoundsException {....}<br />
<br />
正确的重写：&nbsp;&nbsp;&nbsp; public static void name() {....}<br />
<br />
错误的重写：&nbsp;&nbsp;&nbsp; public static void name() throws ClassNotFoundException {....}<br />
<br />
<br />
<strong>3.3、兼容类型的实现</strong><br />
&nbsp;&nbsp;&nbsp; ● 向上转型：向继承结构高端转换，其线程是安全的。<br />
&nbsp;&nbsp;&nbsp; ● 向下转型：向继承结构低端转换，非安全线程。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; instanceof 操作符检测一个对象所输入的类，返回值为 false/true，常用语安全的将一个引用向下转型。<br />
例：if (sref instanceof More)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mref = (More) sref;<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="4" id="4"></a><strong><span style="font-size: 14pt;">第四章&nbsp; 接口</span></strong><br />
<br />
<strong>4.1、抽象类与抽象方法</strong><br />
&nbsp;&nbsp;&nbsp; 通过使用抽象类，我们可以声明只定义了部分实现的类，而让扩展类去提供其部分方法或者全部方法的具体实现。<br />
&nbsp;&nbsp;&nbsp; 任何拥有 abstract 方法的类都必须声明为 abstract。<br />
&nbsp;&nbsp;&nbsp; 不能创建抽象类的对象，应为某些可能会被调用的方法没有任何有效的实现。<br />
&nbsp;&nbsp;&nbsp; 不能是 static 因为 static 不能是 abstract 的。<br />
<br />
<br />
<strong>4.2、接口</strong><br />
&nbsp;&nbsp;&nbsp; 接口是纯设计的表现形式，而类则是设计和实现的混合物。<br />
&nbsp;&nbsp;&nbsp; 接口类型的引用只能访问接口成员。&nbsp;&nbsp;&nbsp; Exam xxx = new ImplExam();<br />
&nbsp;&nbsp;&nbsp; ● 接口常量：隐式 public final static，必须有初始器（值）。<br />
&nbsp;&nbsp;&nbsp; ● 接口方法：隐式 public abstract，除注解外不允许有其他方法修饰符（如 synchronized、native和strictfp 等用于定义实现细节的修饰符）；不能是 final 因为它还没有被实现；不能是 static 因为 static 不能是 abstract 的。<br />
<br />
<br />
<strong>4.3、扩展接口</strong><br />
&nbsp;&nbsp;&nbsp; 可以使用 extends 扩展接口（接口继承接口），接口支持多重继承其他接口。<br />
<br />
&nbsp;&nbsp;&nbsp; public interface C extends A, B {....}<br />
<br />
&nbsp;&nbsp;&nbsp; ● 继承和隐藏常量<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、新声明常量都将隐藏继承而来的常量。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、继承而来的常量可以使用该常量完全限定名访问（X.val，常见引用 static 成员形式）。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、一个接口继承了两个或者多个名字相同常量，那么该常量所有简单引用都具有二义性，会导致编译出错。所以，必须显式使用接口常量，例如 X.val 和 Y.val 等等。&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4、在继承一个类的同时还实现了多个接口，也可能会遇到二义性的问题。<br />
<br />
&nbsp;&nbsp;&nbsp; ● 继承、覆盖和重载方法<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、一个接口同时实现了两个签名相同的方法，只会有一个这样的方法存在，不会有二义性。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、遇到签名相同，返回不同的方法，除非某些返回的类型是其他的子类型，否则不同的返回会产生二义性。<br />
<br />
<br />
<strong>4.4、接口的应用</strong><br />
&nbsp;&nbsp;&nbsp; 任何一个希望被继承的主要类，不管是否抽象类，都应该是一个接口的实现。（同样是 is a 的关系，继承只能扩展一个，但是接口能实现多个。）<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="6" id="6"></a><strong><span style="font-size: 14pt;">第六章&nbsp; 枚举类型</span></strong><br />
&nbsp;&nbsp;&nbsp; 枚举是一个特殊的类，它要表示的每一个具名常量都有与之对应的预定义实例。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="7" id="7"></a><strong><span style="font-size: 14pt;">第七章&nbsp; 语言符号、值和变量</span></strong><br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="8" id="8"></a><strong><span style="font-size: 14pt;">第八章&nbsp; 包装器类</span></strong><br />
<br />
<strong>8.1、包装器类构造</strong><br />
&nbsp;&nbsp;&nbsp; 每一个包装器为它所指的基本类型定义一个不可改变对象。<br />
例如： new Integer(1);&nbsp;&nbsp;&nbsp; 创建对象，他的值始终保持1，不可改变其值。<br />
<br />
<br />
<strong>8.2、装/拆箱转换</strong><br />
&nbsp;&nbsp;&nbsp; Integer val = 3;<br />
&nbsp;&nbsp;&nbsp; int x = val.intValue();<br />
&nbsp;&nbsp;&nbsp; 装/拆箱转换需分配一个包装器类实例，这样会消耗内存。<br />
<br />
&nbsp;&nbsp;&nbsp; 由于包装器类是不可变的，所以两个拥有相同值的对象在一定范围是可以互换使用的（数值型为 -128~127）。<br />
例如：<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; public static boolean sameArgs(Integer a, Integer b) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return a == b;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //判断是否对象相同<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
true&nbsp;&nbsp;&nbsp; sameArgs(12, 12);<br />
false&nbsp;&nbsp;&nbsp; sameArgs(12, new Integer(12));<br />
false&nbsp;&nbsp;&nbsp; sameArgs(1280, 1280);<br />
<br />
<br />
<br />
<span style="font-size: 14pt;"><strong><a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="9" id="9"></a>第九章&nbsp; 运算符和表达式</strong></span><strong></strong><br />
<br />
<strong>9.1、类型转换</strong><br />
&nbsp;&nbsp;&nbsp; ● 隐式拓宽：将整形转换为浮点型，反之则不可以，整形转换浮点型不会产生精度丢失现象。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 长整型 long --&gt; （隐式转换）float&nbsp; --&gt;&nbsp; （强制转换）long&nbsp;&nbsp; 也是可行的，但会丢失精度。<br />
<br />
&nbsp;&nbsp;&nbsp; ● 显式强制类型转换<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、浮点数转换为整数时，小数点后的部分会舍去。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、double 强制转换 float 可能会发生：a.精度丢失；b.得到0；c.或者大于 float 型范围，得到无穷大。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、整数间转换，通过舍去高位，从而有可能被动改变符号。<br />
<br />
<br />
<strong>9.2、运算符优先级</strong><br />
&nbsp;&nbsp;&nbsp; 用括号将运算符括起来，可提高可读性并确保正确的优先顺序。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="10" id="10"></a><strong><span style="font-size: 14pt;">第十章&nbsp; 控制流</span></strong><br />
<br />
<strong>10.1、增强的 for 语句</strong><br />
<br />
&nbsp;&nbsp;&nbsp; for(Type loop-variable : set-expression)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; statement<br />
<br />
&nbsp;&nbsp;&nbsp; ● 对于数组：使用 for-each 的优点在于不必使用数组下标，缺点是只能查看，不能修改数组元素。<br />
&nbsp;&nbsp;&nbsp; ● 对于元素集合：迭代的元素提供简答语法结构，但不能同时迭代多个集合。<br />
&nbsp;&nbsp;&nbsp; ● 不是同步的，非线程安全的。<br />
<br />
<br />
<strong>10.2、标号<br />
<br />
</strong>
&nbsp;&nbsp;&nbsp; label: statement<br />
<br />
&nbsp;&nbsp;&nbsp; 利用标号命名语句，在配合 break lable; 和 continue lable; 将控制流转到严格受限的地方。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="11" id="11"></a><strong><span style="font-size: 14pt;">
第十一章&nbsp; 泛型类型</span></strong><br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="12" id="12"></a><a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="12" id="12"></a><strong><span style="font-size: 14pt;">
第十二章&nbsp; 异常和断言</span></strong><br />
<br />
<strong>
12.1、断言（assertion）</strong><br />
&nbsp;&nbsp;&nbsp; 用来检查永远都应该是 true 的情况，如果发现断言是 false，就会抛出异常。添加测试断言可以为我们提供一种在程序中的错误引发奇怪后果前捕获它们的途径。<br />
<br />
&nbsp;&nbsp;&nbsp; 语法：&nbsp;&nbsp;&nbsp; assert eval-expr [: detail-expr]<br />
<br />
&nbsp;&nbsp;&nbsp; 在断言被关闭时（默认情况下），断言是不被计算了。所以 ：<br />
assert ++i &lt; max;&nbsp;&nbsp;&nbsp; ++i 块有可能不会起作用，建议分开写。<br />
<br />
&nbsp;&nbsp;&nbsp; 断言应该用来测试从来不发生的情况，因为断言会抛出 Error 而不是 Exception。然而，使断言成为必须会使代码的运行环境变得复杂，因为当前断言的打开及关闭间反复操作会带来复杂性，所以不建议使用。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="13" id="13"></a><strong><span style="font-size: 14pt;">
第十三章&nbsp; 字符串与正则表达式</span></strong><br />
<br />
<strong>
13.1、正则表达式的匹配</strong><br />
&nbsp;&nbsp;&nbsp; java.util.regex 包提供 正则表达式（regular expression）用于&#8220;检测字符串是否和某种模式匹配&#8221;或者&#8220;挑选字符串中各个部分&#8221;。<br />
<br />
&nbsp;&nbsp;&nbsp; ● 重用已编译的模式：执行匹配所涉及的所有状态都驻留在匹配器中，所以多个匹配器可以共享同一模式。 <br />
&nbsp;&nbsp;&nbsp; Pattern p = Pattern.compile(regularExpression);&nbsp;&nbsp;&nbsp; //将给定的正则表达式编译到模式中<br />
&nbsp;&nbsp;&nbsp; Matcher m = p.matcher(sequence);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //利用输入序列从模式创建匹配器<br />
&nbsp;&nbsp;&nbsp; boolean b = m.matches();&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //尝试将整个输入序列与该模式匹配<br />
<br />
&nbsp;&nbsp;&nbsp; ● 仅使用一次正则表达式<br />
&nbsp;&nbsp;&nbsp; boolean b = Pattern.matches(regex, sequence);&nbsp;&nbsp;&nbsp; //编译给定正则表达式并尝试将给定输入与其匹配<br />
&nbsp;&nbsp;&nbsp; <br />
<br />
<strong>
13.2、正则表达式的替换</strong><br />
&nbsp;&nbsp;&nbsp; 通过调用模式的 matcher 方法从模式创建匹配器。创建匹配器后，可以使用它执行三种不同的匹配操作： <br />
<br />
&nbsp;&nbsp;&nbsp; ● matches 方法尝试将整个输入序列与该模式匹配。<br />
&nbsp;&nbsp;&nbsp; ● lookingAt 尝试将输入序列从头开始与该模式匹配。 <br />
&nbsp;&nbsp;&nbsp; ● find 方法扫描输入序列以查找与该模式匹配的下一个子序列。 <br />
<br />
&nbsp;&nbsp;&nbsp; 每个方法都返回一个表示成功或失败的布尔值。通过查询匹配器的状态可以获取关于成功匹配的更多信息。 <br />
<br />
ps.正则表达式本身复杂，只有在确实需要的情况下才使用它。在使用的时候，尽量确保模式的清晰度。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="14" id="14"></a>
<span style="font-size: 14pt;"><strong>第十四章&nbsp; 线程</strong></span><strong></strong><br />
&nbsp;&nbsp;&nbsp; 在计算机中每次执行一步的操作序列被称为线程（thread），而这种单线程编程模型正是大多数程序员所使用的模型。线程可以独立于其他线程执行一项任务，线程间也可以共享访问对象。当两个线程在修改同一块数据时，如果它们是会对数据造成破坏的交叉方式去执行，那么就会出现竞争危机，解决的方法是利用一个锁和对象关联起来，这个锁可以告知该对象是否正在被使用。<br />
<br />
<br />
<strong>14.1、创建线程</strong><br />
&nbsp;&nbsp;&nbsp; ● 扩展 Thread 类来创建新的线程，重写 run 方法。<br />
&nbsp;&nbsp;&nbsp; class PrimeThread extends Thread {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long minPrime;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PrimeThread(long minPrime) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.minPrime = minPrime;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // compute primes larger than minPrime<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; . . .<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
下列代码会创建并启动一个线程： <br />
&nbsp;&nbsp;&nbsp;&nbsp; PrimeThread p = new PrimeThread(143);&nbsp;&nbsp;&nbsp; //创建该类实例<br />
&nbsp;&nbsp;&nbsp;&nbsp; p.start();&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //启动线程，Java 虚拟机调用该线程的 run 方法。<br />
<br />
<br />
&nbsp;&nbsp;&nbsp; ● 声明实现 Runnable 接口的类。该类然后实现 run 方法。<br />
&nbsp;&nbsp;&nbsp;&nbsp; class PrimeRun implements Runnable {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long minPrime;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PrimeRun(long minPrime) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.minPrime = minPrime;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // compute primes larger than minPrime<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; . . .<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
下列代码会创建并启动一个线程： <br />
&nbsp;&nbsp;&nbsp;&nbsp; PrimeRun p = new PrimeRun(143);&nbsp;&nbsp;&nbsp; //分配该类对象<br />
&nbsp;&nbsp;&nbsp;&nbsp; new Thread(p).start();&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //利用对象构造一个新的线程，并启动<br />
<br />
<br />
&nbsp;&nbsp;&nbsp; ps.每个线程都有一个标识名，多个线程可以同名。如果线程创建时没有指定标识名，就会为其生成一个新名称。<br />
<br />
<br />
<strong>
14.2、隐藏线程的 run 方法</strong><br />
&nbsp;&nbsp;&nbsp; run 方法是公共的，为了防止客户端私自调用该方法，我们可以不起实现 Runable 接口，而是定义一个内部的 Runable 对象，确保不被滥用。例如：<br />
<br />
&nbsp; public class Ping2 {<br />
&nbsp;&nbsp;&nbsp; public Ping2() {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Runnable service = new Runnable(){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; public void run() {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //......<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } ;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; new Thread(service).start();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp; }<br />
<br />
<br />
<strong>
14.3、线程的结束</strong><br />
&nbsp;&nbsp;&nbsp; 有三种情况可使线程终止：<br />
&nbsp;&nbsp;&nbsp; ● run 方法正常返回（常规方式）<br />
&nbsp;&nbsp;&nbsp; ● run 方法意外结束<br />
&nbsp;&nbsp;&nbsp; ● 应用程序终止<br />
<br />
&nbsp;&nbsp;&nbsp; Thread.currentThread().interrupt(); 向线程发送中断：中断一个线程通常不会影响它正在执行的操作，但是像 sleep 和 wait 这样会抛出 InterruptedException 异常的方法除外。<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; 一个线程可以使用某种形式的 join 方法来等待另一个线程终止。<br />
<br />
&nbsp;&nbsp;&nbsp; 不要使用 stop 方法：首先因为 stop 不能强制终止任何线程，无力对付恶意方法；其次，stop 会影响同步锁，破坏对象。所以建议转而使用 interrupt 方法。<br />
<br />
<br />
<strong>
14、4 同步</strong><br />
&nbsp;&nbsp;&nbsp; 当多线程使用同一个对象时，存在着由于交叉操作而破坏数据的可能性，所以在某些动作操作对象之前，必须先获得对象的锁来阻止其他对象获得这个锁，直至它被持有者释放为止。<br />
<br />
&nbsp;&nbsp;&nbsp; 利用 synchronized 的声明，我们可以确保多个运行的线程不会互相干扰，因为每一个方法都将互斥地执行（在该方法调用结束前不能被其他方法调用）。<br />
<br />
&nbsp;&nbsp;&nbsp; 线程安全：多个线程可以并发调用对象上的方法，并且在每个线程中被调用的方法都在执行所期望的作业。<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="15" id="15"></a><strong><span style="font-size: 14pt;">
第十五章、注解</span></strong><br />
&nbsp;&nbsp;&nbsp; 注解以结构化的方式提供了程序及其元素（类、方法、字段、变量等等）的信息，这些信息能够被外部工具自动处理。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="16" id="16"></a><strong><span style="font-size: 14pt;">
第十六章&nbsp; 反射</span></strong><br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="17" id="17"></a><strong><span style="font-size: 14pt;">
第十七章&nbsp; 垃圾回收器与内存</span></strong><br />
&nbsp;&nbsp;&nbsp; Java 虚拟机可以使用一种称为垃圾回收（garbage collection）的技术来确定对象在程序中何时不再被引用，因此它可以安全地释放对象占用的内存空间。<br />
<br />
&nbsp;&nbsp;&nbsp; 当我们从任何可执行代码都无法到达某个对象时，它所占的空间就可以被回收。垃圾回收会占用一定的系统资源，通常情况下，只有需要更多的内存空间或者避免发生内存溢出时，垃圾回收器才会运行。但是程序可能没有发生内存溢出，甚至在没有接近内存退出的时候就退出了，所以可能根本不需要执行垃圾回收。<br />
<br />
&nbsp;&nbsp;&nbsp; 垃圾回收并不能保证内存中总是会有空间来创建新对象，不停的创建对象并置于使用列表中，就会造成内存泄漏。垃圾回收解决了很多（但并非全部）的内存分配问题。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; System.runFinalization();&nbsp;&nbsp;&nbsp; //运行挂起 finalization 的所有对象的终止方法&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  <br />
&nbsp;&nbsp;&nbsp; System.gc();&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //运行垃圾回收器<br />
<br />
&nbsp;&nbsp;&nbsp; Runtime.getRuntime().runFinalization();<br />
&nbsp;&nbsp;&nbsp; Runtime.getRuntime().gc();<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="18" id="18"></a><strong><span style="font-size: 14pt;">
第十八章&nbsp; 包<br />
<br />
</span>
18.1、导入机制</strong><br />
&nbsp;&nbsp;&nbsp; 如果声明了一个对 Xxx 类的引用，那么编译器就会按照下面的顺序搜索该类型：<br />
&nbsp;&nbsp;&nbsp; 1、包括继承类型在内的当前类型。<br />
&nbsp;&nbsp;&nbsp; 2、当前类型的嵌套类型。<br />
&nbsp;&nbsp;&nbsp; 3、显式命名的导入类型（单类型导入， import attr.Attributed;）<br />
&nbsp;&nbsp;&nbsp; 4、在同一个包中声明的其他类型。<br />
&nbsp;&nbsp;&nbsp; 5、隐式命名的导入类型（按需导入，import attr.*;）<br />
<br />
&nbsp;&nbsp;&nbsp; 为了避免导入同名的两个类型产生二义性，建议使用完全限定名。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="19" id="19"></a><strong><span style="font-size: 14pt;">
第十九章&nbsp; 文档注释</span></strong><br />
<br />
<strong>19.1、剖析文档注释</strong><br />
&nbsp;&nbsp;&nbsp; /** <br />
&nbsp;&nbsp;&nbsp;&nbsp; * 文档注释第一句应该是一个良好的摘要。<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 文档注释中可以嵌套标准的 HTML 标签，用于格式指令或链接到其他文档。<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 如果想使用 @ 字符，请使用 @，否则会被当作文档注释标签的开始。<br />
&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; <br />
<br />
<span style="font-size: 14pt;"><strong><br />
</strong></span><a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="20" id="20"></a><span style="font-size: 14pt;"><strong>
第二十章&nbsp; I/O 包</strong></span><strong></strong><br />
&nbsp;&nbsp;&nbsp; java.io 包是用流（stream）定义 I/O 的，流是有序的数据序列，它有一个源（输入流）和目的地（输出流）。<br />
&nbsp;&nbsp;&nbsp; java.nio 包是用缓冲区（buffer）和通道（channel）定义 I/O 的，它用于高吞吐量服务器。<br />
&nbsp;&nbsp;&nbsp; java.net 包基于对套接字的使用，用一种基于流或通道的模型提供对网络 I/O 的特殊支持。<br />
<br />
<br />
<strong>
20.1、流的概述</strong><br />
&nbsp;&nbsp;&nbsp; I/O 主要有两部分：<br />
&nbsp;&nbsp;&nbsp; ● 字符流（character stream，16位的 UTF-16 字符），它基于文本的 I/O，有读取器（reader）和写入器（write）。<br />
&nbsp;&nbsp;&nbsp; ● 字节流（byte stream，通常是 8位），它基于数据的 I/O，有输入流（input stream）和输出流（output stream）。<br />
<br />
&nbsp;&nbsp;&nbsp; 转换流 InputStreamReader 与 OutputStreamWriter 可以通过指定或者默认的编码机制在 字符流 与 字节流 之间互相转换，类似于&#8220;黏合剂&#8221;，使我们可以以一种统一的、平台无关的方式使用现有的 8位字符编码机制去处理本地字符集。<br />
&nbsp;&nbsp;&nbsp; InputStreamReader 对象读取字节，并使用适合该流的编码机制将其转换为字符。<br />
&nbsp;&nbsp;&nbsp; OutputStreamWriter 对象将接受提供的字符，使用适合的编码机制将它们转换为字节。<br />
&nbsp;&nbsp;&nbsp; （注：无 ReaderStreamInput 类将字符转换为字节，也无 WriterOutputStream 这个类将字节转译为字符）<br />
<br />
&nbsp;&nbsp;&nbsp; InputStreamReader(InputStream in);<br />
&nbsp;&nbsp;&nbsp; OutputStreamWriter(OutputStream out);<br />
&nbsp;&nbsp;&nbsp; 关闭转换流的同时也会关闭掉将其关联的字节流，所以一定要慎重。<br />
<br />
<br />
<strong>
20.2、数据字节流</strong><br />
&nbsp;&nbsp;&nbsp; 通过流来传输特定类型的二进制数据。DataInput 和 DataOutput。<br />
<br />
<br />
<strong>
20.3、对象序列化</strong><br />
&nbsp;&nbsp;&nbsp; 将对象的表示转换为字节流的过程成为序列化，而从字节流中重构一个对象的过程被称为反序列化。<br />
&nbsp;&nbsp;&nbsp; 当 ObjectOutputStream 写入序列化对象是，该对象必须实现 Serializable 接口，声明该类为可序列化的。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="21" id="21"></a><strong><span style="font-size: 14pt;">
第二十一章&nbsp; 集合<br />
<br />
</span>
21.1、迭代</strong><br />
&nbsp;&nbsp;&nbsp; 对 Collection 使用 iterator 方法将获得一个 Iterator 对象，这个对象可以遍历集合内容，而且每次都只能访问一个元素。<br />
&nbsp;&nbsp;&nbsp; 与增强型 for 循环相比，它可以通过 remove 方法移除元素，这种方式是安全的。<br />
<br />
<br />
<strong>
21.2、同步</strong><br />
&nbsp;&nbsp;&nbsp; java.util 包中提供的所有集合实现都是非同步的（除了 Vector、Dictionary、Hashtable 等遗留下来的集合）。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="22" id="22"></a><strong><span style="font-size: 14pt;">
第二十二章&nbsp; 各种常用工具</span></strong><br />
&nbsp;&nbsp;&nbsp; ● Formatter：用于产生格式化文本。<br />
&nbsp;&nbsp;&nbsp; ● Random：用以产生伪随机数序列的类。<br />
&nbsp;&nbsp;&nbsp; ● Scanner：该类用于扫描文本，并根据正则表达式模式将其解析成基本数据类型或者字符串。<br />
&nbsp;&nbsp;&nbsp; ● Timer/TimerTask：用于调度将来某个时刻运行任务的一种方式（包括重复发生），每个 Timer 对象都有一个相关联的线程。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="23" id="23"></a><strong><span style="font-size: 14pt;">
第二十三章&nbsp; 系统编程</span></strong><br />
&nbsp;&nbsp;&nbsp; 应用程序有时必须同 Java 虚拟机的运行时系统或底层操作系统进行交互。java.lang 中有三个主要的类提供了这个访问：<br />
<br />
<br />
<strong>
23.1、System 类</strong><br />
&nbsp;&nbsp;&nbsp; System 类提供了用于操纵系统状态的的静态方法，并起到了资源仓库的作用。它有四个通用领域的功能性：<br />
&nbsp;&nbsp;&nbsp; ● 标准 I/O 流<br />
&nbsp;&nbsp;&nbsp; ● 操纵系统属性<br />
&nbsp;&nbsp;&nbsp; ● 用于访问当前 Runtime 对象的工具方法和便利方法。<br />
&nbsp;&nbsp;&nbsp; ● 安全性<br />
<br />
<br />
<strong>
23.2、Runtime 类</strong><br />
&nbsp;&nbsp;&nbsp; 提供了访问虚拟机的运行时系统的接口。当前 Runtime 对象提供了对每个运行时系统的功能进行交互的能力，例如与垃圾回收器交互、执行其他程序及关闭运行时系统。<br />
<br />
<br />
<strong>
23.3、Process 类</strong><br />
&nbsp;&nbsp;&nbsp; 表示的是正在运行的进程，它是通过调用 Runtime.exec 来执行另一个程序时创建的，也可以通过直接使用 ProcesssBuilder 对象来创建。<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="24" id="24"></a><strong><span style="font-size: 14pt;">
第二十四章&nbsp; 国际化和本地化<br />
<br />
</span>
24.1、区域</strong><br />
&nbsp;&nbsp;&nbsp; java.util.Locale 对象描述了区域。<br />
<br />
<br />
<strong>
24.2、资源束</strong><br />
&nbsp;&nbsp;&nbsp; java.util.ResourceBundle 类。<br />
<br />
<br />
<strong>
24.3、货币</strong><br />
&nbsp;&nbsp;&nbsp; java.util.Currency 类可以帮助我们正确格式化货币值。<br />
<br />
<br />
<strong>
24.4、时间、日期、日历</strong><br />
&nbsp;&nbsp;&nbsp; 时间是用长整型 long 表示的，从 1970 年开始，可以通过 java.util.Date 类获得时间，时间的比较可以用 before 和 after 方法，或者可以用 getTime/setTime 方法获得/设置时间的 long 型值。Date 没有提供本地化支持，我们可以使用更有效复杂的区域敏感的 Calendar 和 DateFormat 类来代替它。<br />
<br />
&nbsp;&nbsp;&nbsp; 抽象类 Calendar 表示不同标记时间的方式，同时也提供了许多用的日历字段。<br />
&nbsp;&nbsp;&nbsp; GregorianCalendar 类表示日历。<br />
&nbsp;&nbsp;&nbsp; SimpleDateFormat 类格式化、解析时间的类。<br />
例：<br />
&nbsp;&nbsp;&nbsp; Calendar cal = new GregorianCalendar(1972, Calendar.OCTOBER, 26);<br />
&nbsp;&nbsp;&nbsp; System.out.println(cal.getTime());<br />
<br />
<br />
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="25" id="25"></a>
<span style="font-size: 14pt;"><strong>第二十五章&nbsp; 标准包</strong></span><strong></strong><br />
&nbsp;&nbsp;&nbsp; ● java.awt：抽象工具箱的抽象层，用来编写平台无关的图形用户界面。<br />
&nbsp;&nbsp;&nbsp; ● java.applet：Applet 类和相关类型，用于编写可嵌入其他应用程序的子程序，如 HTML 浏览器。<br />
&nbsp;&nbsp;&nbsp; ● java.beans：用于编写客户端可重用的 JavaBeans 构件。<br />
&nbsp;&nbsp;&nbsp; ● java.lang.instrument：用于定义代理的服务。<br />
&nbsp;&nbsp;&nbsp; ● java.lang.managerment：用于监视并管理其所在的虚拟机以及操作系统服务。<br />
&nbsp;&nbsp;&nbsp; ● java.math：数学<br />
&nbsp;&nbsp;&nbsp; ● java.net：网络<br />
&nbsp;&nbsp;&nbsp; ● java.rmi：远程方法调用<br />
&nbsp;&nbsp;&nbsp; ● java.security 与相关的工具包：安全工具。<br />
&nbsp;&nbsp;&nbsp; ● java.sql：关系数据库访问<br />
<br />
&nbsp;&nbsp;&nbsp; ● javax.* ：标准扩展工具包<br />
&nbsp;&nbsp;&nbsp; ● javax.sound：创建和操作声音的子包。<br />
&nbsp;&nbsp;&nbsp; ● javax.swing：GUI构建的 Swing 包。<br />
<img src ="http://www.blogjava.net/kiant/aggbug/233806.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2008-10-11 23:28 <a href="http://www.blogjava.net/kiant/articles/233806.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转] java的 Collection 和 Map 详解</title><link>http://www.blogjava.net/kiant/articles/226964.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Thu, 04 Sep 2008 07:06:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/226964.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/226964.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/226964.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/226964.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/226964.html</trackback:ping><description><![CDATA[原文转自： <a href="http://www.diybl.com/course/3_program/java/javajs/2007917/71621.html" target="_blank">http://www.diybl.com/course/3_program/java/javajs/2007917/71621.html</a><br />
<br />
<br />
<fieldset><legend>前言</legend>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;线性表，链表，哈希表是常用的数据结构，在进行Java开发时，JDK已经为我们提供了一系列相应的类来实现基本的数据结构。这些类均在java.util包中。本文试图通过简单的描述，向读者阐述各个类的作用以及如何正确使用这些类。&nbsp;&nbsp;&nbsp; <br />
&nbsp;<br />
Collection&nbsp; <br />
├List&nbsp; <br />
│├LinkedList&nbsp; <br />
│├ArrayList&nbsp; <br />
│└Vector&nbsp; <br />
│　└Stack&nbsp; <br />
└Set&nbsp;
<p>Map&nbsp; <br />
├Hashtable&nbsp; <br />
├HashMap&nbsp; <br />
└WeakHashMap</p>
</fieldset><br />
<br />
<br />
<fieldset><legend>Collection接口</legend>　　Collection是最基本的集合接口，一个Collection代表一组Object，即Collection的元素（Elements）。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java&nbsp; SDK不提供直接继承自Collection的类，Java&nbsp;SDK提供的类都是继承自Collection的&#8220;子接口&#8221;如List和Set。&nbsp; <br />
所有实现Collection接口的类都必须提供两个标准的构造函数：无参数的构造函数用于创建一个空的Collection，有一个Collection参数的构造函数用于创建一个新的Collection，这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。&nbsp; <br />
如何遍历Collection中的每一个元素？不论Collection的实际类型如何，它都支持一个iterator()的方法，该方法返回一个迭代子，使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下：&nbsp; <br />
Iterator&nbsp; it&nbsp; =&nbsp; collection.iterator();&nbsp; //&nbsp; 获得一个迭代子&nbsp; <br />
while(it.hasNext())&nbsp; {&nbsp; <br />
Object&nbsp; obj&nbsp; =&nbsp; it.next();&nbsp; //&nbsp; 得到下一个元素&nbsp; <br />
}&nbsp; <br />
由Collection接口派生的两个接口是List和Set。&nbsp; </fieldset>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_150728" onclick="this.style.display='none'; Code_Closed_Text_150728.style.display='none'; Code_Open_Image_150728.style.display='inline'; Code_Open_Text_150728.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11" /><img id="Code_Open_Image_150728" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_150728.style.display='none'; Code_Closed_Image_150728.style.display='inline'; Code_Closed_Text_150728.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11" /><span id="Code_Closed_Text_150728" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">List接口 </span><span id="Code_Open_Text_150728" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: rgb(0, 0, 0);">List接口&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　List是有序的Collection，使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引（元素在List中的位置，类似于数组下标）来访问List中的元素，这类似于Java的数组。和下面要提到的Set不同，List允许有相同的元素。&nbsp;&nbsp;<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　除了具有Collection接口必备的iterator()方法外，List还提供一个listIterator()方法，返回一个ListIterator接口，和标准的Iterator接口相比，ListIterator多了一些add()之类的方法，允许添加，删除，设定元素，还能向前或向后遍历。&nbsp;&nbsp;<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　实现List接口的常用类有LinkedList，ArrayList，Vector和Stack。&nbsp;</span></span></div>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_150801" onclick="this.style.display='none'; Code_Closed_Text_150801.style.display='none'; Code_Open_Image_150801.style.display='inline'; Code_Open_Text_150801.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11" /><img id="Code_Open_Image_150801" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_150801.style.display='none'; Code_Closed_Image_150801.style.display='inline'; Code_Closed_Text_150801.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11" /><span id="Code_Closed_Text_150801" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">LinkedList类 </span><span id="Code_Open_Text_150801" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: rgb(0, 0, 0);">LinkedList类&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　LinkedList实现了List接口，允许null元素。此外LinkedList提供额外的get，remove，insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈（stack），队列（queue）或双向队列（deque）。&nbsp;&nbsp;<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　注意LinkedList没有同步方法。如果多个线程同时访问一个List，则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List：&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　　　List&nbsp;&nbsp;list&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;Collections.synchronizedList(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;LinkedList(<img alt="" src="http://www.blogjava.net/Images/dot.gif" />));&nbsp;&nbsp;</span></span></div>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_150921" onclick="this.style.display='none'; Code_Closed_Text_150921.style.display='none'; Code_Open_Image_150921.style.display='inline'; Code_Open_Text_150921.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11" /><img id="Code_Open_Image_150921" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_150921.style.display='none'; Code_Closed_Image_150921.style.display='inline'; Code_Closed_Text_150921.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11" /><span id="Code_Closed_Text_150921" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">Vector类 </span><span id="Code_Open_Text_150921" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: rgb(0, 0, 0);">Vector类&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Vector非常类似ArrayList，但是Vector是同步的。由Vector创建的Iterator，虽然和ArrayList创建的Iterator是同一接口，但是，因为Vector是同步的，当一个Iterator被创建而且正在被使用，另一个线程改变了Vector的状态（例如，添加或删除了一些元素），这时调用Iterator的方法时将抛出ConcurrentModificationException，因此必须捕获该异常。</span></span></div>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_150944" onclick="this.style.display='none'; Code_Closed_Text_150944.style.display='none'; Code_Open_Image_150944.style.display='inline'; Code_Open_Text_150944.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11" /><img id="Code_Open_Image_150944" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_150944.style.display='none'; Code_Closed_Image_150944.style.display='inline'; Code_Closed_Text_150944.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11" /><span id="Code_Closed_Text_150944" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">Stack 类 </span><span id="Code_Open_Text_150944" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: rgb(0, 0, 0);">Stack&nbsp;&nbsp;类&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Stack继承自Vector，实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法，还有peek方法得到栈顶的元素，empty方法测试堆栈是否为空，search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。&nbsp;&nbsp;</span></span></div>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_151008" onclick="this.style.display='none'; Code_Closed_Text_151008.style.display='none'; Code_Open_Image_151008.style.display='inline'; Code_Open_Text_151008.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11" /><img id="Code_Open_Image_151008" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_151008.style.display='none'; Code_Closed_Image_151008.style.display='inline'; Code_Closed_Text_151008.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11" /><span id="Code_Closed_Text_151008" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">Set接口 </span><span id="Code_Open_Text_151008" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: rgb(0, 0, 0);">Set接口&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　Set是一种不包含重复的元素的Collection，即任意的两个元素e1和e2都有e1.equals(e2)</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">，Set最多有一个null元素。&nbsp;&nbsp;<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　很明显，Set的构造函数有一个约束条件，传入的Collection参数不能包含重复的元素。&nbsp;&nbsp;<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　请注意：必须小心操作可变对象（Mutable&nbsp;&nbsp;Object）。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">true将导致一些问题。&nbsp;&nbsp;</span></span></div>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_150850" onclick="this.style.display='none'; Code_Closed_Text_150850.style.display='none'; Code_Open_Image_150850.style.display='inline'; Code_Open_Text_150850.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11" /><img id="Code_Open_Image_150850" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_150850.style.display='none'; Code_Closed_Image_150850.style.display='inline'; Code_Closed_Text_150850.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11" /><span id="Code_Closed_Text_150850" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">ArrayList类 </span><span id="Code_Open_Text_150850" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: rgb(0, 0, 0);">ArrayList类&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　ArrayList实现了可变大小的数组。它允许所有元素，包括null。ArrayList没有同步。size，isEmpty，get，set方法运行时间为常数。但是add方法开销为分摊的常数，添加n个元素需要O(n)的时间。其他的方法运行时间为线性。&nbsp;&nbsp;<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　每个ArrayList实例都有一个容量（Capacity），即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加，但是增长算法并没有定义。当需要插入大量元素时，在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。&nbsp;&nbsp;<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　和LinkedList一样，ArrayList也是非同步的（unsynchronized）。&nbsp;&nbsp;</span></span></div>
<br />
<br />
<br />
<fieldset><legend>Map接口</legend>　请注意，Map没有继承Collection接口，Map提供key到value的映射。一个Map中不能包含相同的key，每个key只能映射一个value。Map接口提供3种集合的视图，Map的内容可以被当作一组key集合，一组value集合，或者一组key-value映射。 </fieldset>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_151650" onclick="this.style.display='none'; Code_Closed_Text_151650.style.display='none'; Code_Open_Image_151650.style.display='inline'; Code_Open_Text_151650.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" alt="" align="top" height="16" width="11" /><img id="Code_Open_Image_151650" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_151650.style.display='none'; Code_Closed_Image_151650.style.display='inline'; Code_Closed_Text_151650.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" alt="" align="top" height="16" width="11" /><span id="Code_Closed_Text_151650" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">Hashtable类 </span><span id="Code_Open_Text_151650" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /><span style="color: rgb(0, 0, 0);">Hashtable类&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　Hashtable继承Map接口，实现一个key</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">value映射的哈希表。任何非空（non</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">）的对象都可作为key或者value。&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　添加数据使用put(key,&nbsp;&nbsp;value)，取出数据使用get(key)，这两个基本操作的时间开销为常数。Hashtable通过initial&nbsp;&nbsp;capacity和load&nbsp;&nbsp;factor两个参数调整性能。通常缺省的load&nbsp;&nbsp;factor&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">.75较好地实现了时间和空间的均衡。增大load&nbsp;&nbsp;factor可以节省空间但相应的查找时间将增大，这会影响像get和put这样的操作。使用Hashtable的简单示例如下，将1，</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">，3放到Hashtable中，他们的key分别是&#8221;one&#8221;，&#8221;two&#8221;，&#8221;three&#8221;：&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　　　Hashtable&nbsp;&nbsp;numbers&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;Hashtable();&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　　　numbers.put(&#8220;one&#8221;,&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;Integer(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">));&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　　　numbers.put(&#8220;two&#8221;,&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;Integer(</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">));&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　　　numbers.put(&#8220;three&#8221;,&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;Integer(</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">));&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　要取出一个数，比如2，用相应的key：&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　　　Integer&nbsp;&nbsp;n&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;(Integer)numbers.get(&#8220;two&#8221;);&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　　　System.out.println(&#8220;two&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&#8221;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;n);&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置，因此任何作为key的对象都必须实现hashCode和equals方法。hashCode和equals方法继承自根类Object，如果你用自定义的类当作key的话，要相当小心，按照散列函数的定义，如果两个对象相同，即obj1.equals(obj2)</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">，则它们的hashCode必须相同，但如果两个对象不同，则它们的hashCode不一定不同，如果两个不同对象的hashCode相同，这种现象称为冲突，冲突会导致操作哈希表的时间开销增大，所以尽量定义好的hashCode()方法，能加快哈希表的操作。&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　如果相同的对象有不同的hashCode，对哈希表的操作会出现意想不到的结果（期待的get方法返回null），要避免这种问题，只需要牢记一条：要同时复写equals方法和hashCode方法，而不要只写其中一个。&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　Hashtable是同步的。&nbsp;&nbsp;</span></span></div>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_151723" onclick="this.style.display='none'; Code_Closed_Text_151723.style.display='none'; Code_Open_Image_151723.style.display='inline'; Code_Open_Text_151723.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" alt="" align="top" height="16" width="11" /><img id="Code_Open_Image_151723" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_151723.style.display='none'; Code_Closed_Image_151723.style.display='inline'; Code_Closed_Text_151723.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" alt="" align="top" height="16" width="11" /><span id="Code_Closed_Text_151723" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">HashMap类 </span><span id="Code_Open_Text_151723" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /><span style="color: rgb(0, 0, 0);">HashMap类&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　HashMap和Hashtable类似，不同之处在于HashMap是非同步的，并且允许null，即null&nbsp;&nbsp;value和null&nbsp;&nbsp;key。但是将HashMap视为Collection时（values()方法可返回Collection），其迭代子操作时间开销和HashMap的容量成比例。因此，如果迭代操作的性能相当重要的话，不要将HashMap的初始化容量设得过高，或者load&nbsp;&nbsp;factor过低。&nbsp;&nbsp;</span></span></div>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_151750" onclick="this.style.display='none'; Code_Closed_Text_151750.style.display='none'; Code_Open_Image_151750.style.display='inline'; Code_Open_Text_151750.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" alt="" align="top" height="16" width="11" /><img id="Code_Open_Image_151750" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_151750.style.display='none'; Code_Closed_Image_151750.style.display='inline'; Code_Closed_Text_151750.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" alt="" align="top" height="16" width="11" /><span id="Code_Closed_Text_151750" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">WeakHashMap类 </span><span id="Code_Open_Text_151750" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" /><span style="color: rgb(0, 0, 0);">WeakHashMap类&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" alt="" align="top" />　　WeakHashMap是一种改进的HashMap，它对key实行&#8220;弱引用&#8221;，如果一个key不再被外部所引用，那么该key可以被GC回收。&nbsp;&nbsp;</span></span></div>
<br />
<br />
<fieldset><legend>总结</legend>如果涉及到堆栈，队列等操作，应该考虑用List，对于需要快速插入，删除元素，应该使用LinkedList，如果需要快速随机访问元素，应该使用ArrayList。</fieldset>
<img src ="http://www.blogjava.net/kiant/aggbug/226964.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2008-09-04 15:06 <a href="http://www.blogjava.net/kiant/articles/226964.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDBC 直连 SQL2005 的一点心得</title><link>http://www.blogjava.net/kiant/articles/214637.html</link><dc:creator>黄小二</dc:creator><author>黄小二</author><pubDate>Sun, 13 Jul 2008 15:39:00 GMT</pubDate><guid>http://www.blogjava.net/kiant/articles/214637.html</guid><wfw:comment>http://www.blogjava.net/kiant/comments/214637.html</wfw:comment><comments>http://www.blogjava.net/kiant/articles/214637.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kiant/comments/commentRss/214637.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kiant/services/trackbacks/214637.html</trackback:ping><description><![CDATA[<br />
一、配置 SQL Server 2005 以允许远程连接&nbsp;&nbsp;&nbsp;&nbsp;(通过使用实例名称来运行 SQL Server 2005 )<br />
<a href="http://support.microsoft.com/kb/914277/zh-cn" target="_blank">http://support.microsoft.com/kb/914277/zh-cn</a> <br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_010749" onclick="this.style.display='none'; Code_Closed_Text_010749.style.display='none'; Code_Open_Image_010749.style.display='inline'; Code_Open_Text_010749.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11" /><img id="Code_Open_Image_010749" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_010749.style.display='none'; Code_Closed_Image_010749.style.display='inline'; Code_Closed_Text_010749.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11" /><span id="Code_Closed_Text_010749" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">摘要&amp;总结</span><span id="Code_Open_Text_010749" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: rgb(0, 0, 0);">在尝试从远程计算机连接到&nbsp;Microsoft&nbsp;SQL&nbsp;Server&nbsp;</span><span style="color: rgb(0, 0, 0);">2005</span><span style="color: rgb(0, 0, 0);">&nbsp;实例时，可能会接收到错误消息。在使用任何程序连接到&nbsp;SQL&nbsp;Server&nbsp;时都可能会发生此问题。例如，在使用&nbsp;SQLCMD&nbsp;实用工具连接到&nbsp;SQL&nbsp;Server&nbsp;时收到以下错误消息：<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />Sqlcmd:错误:Microsoft&nbsp;SQL&nbsp;Native&nbsp;Client:建立到服务器的连接时发生错误。连接到&nbsp;SQL&nbsp;Server&nbsp;</span><span style="color: rgb(0, 0, 0);">2005</span><span style="color: rgb(0, 0, 0);">&nbsp;时，默认设置&nbsp;SQL&nbsp;Server&nbsp;不允许远程连接这个事实可能会导致失败。<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />如果没有将&nbsp;SQL&nbsp;Server&nbsp;</span><span style="color: rgb(0, 0, 0);">2005</span><span style="color: rgb(0, 0, 0);">&nbsp;配置为接受远程连接，则可能会发生此问题。默认情况下，SQL&nbsp;Server&nbsp;</span><span style="color: rgb(0, 0, 0);">2005</span><span style="color: rgb(0, 0, 0);">&nbsp;Express&nbsp;Edition&nbsp;和&nbsp;SQL&nbsp;Server&nbsp;</span><span style="color: rgb(0, 0, 0);">2005</span><span style="color: rgb(0, 0, 0);">&nbsp;Developer&nbsp;Edition&nbsp;不允许远程连接。若要配置&nbsp;SQL&nbsp;Server&nbsp;</span><span style="color: rgb(0, 0, 0);">2005</span><span style="color: rgb(0, 0, 0);">&nbsp;以允许远程连接，请完成以下所有步骤：<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8226;&nbsp;在您要从远程计算机连接到的&nbsp;SQL&nbsp;Server&nbsp;实例上启用远程连接。&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#8226;&nbsp;打开&nbsp;SQL&nbsp;Server&nbsp;Browser&nbsp;服务。&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#8226;&nbsp;配置防火墙以允许与&nbsp;SQL&nbsp;Server&nbsp;和&nbsp;SQL&nbsp;Server&nbsp;Browser&nbsp;服务相关的网络通讯。&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />启用&nbsp;SQL&nbsp;Server&nbsp;Browser&nbsp;服务<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><strong>如果您是通过使用实例名称来运行&nbsp;SQL&nbsp;Server&nbsp;</strong></span><strong><span style="color: rgb(0, 0, 0);">2005</span><span style="color: rgb(0, 0, 0);">&nbsp;并且在连接字符串中没有使用特定的&nbsp;TCP</span><span style="color: rgb(0, 0, 0);">/</span></strong><span style="color: rgb(0, 0, 0);"><strong>IP&nbsp;端口号，则必须启用&nbsp;SQL&nbsp;Server&nbsp;Browser&nbsp;服务以允许远程连接。<br />
</strong><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;例如，使用<strong>&nbsp;</strong></span><strong><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">计算机名</span><span style="color: rgb(0, 0, 0);">&gt;</span></strong><span style="color: rgb(0, 0, 0);"><strong>\SQLEXPRESS&nbsp;的默认实例名称</strong>安装的&nbsp;SQL&nbsp;Server&nbsp;</span><span style="color: rgb(0, 0, 0);">2005</span><span style="color: rgb(0, 0, 0);">&nbsp;Express。不管您正在运行多少个&nbsp;SQL&nbsp;Server&nbsp;</span><span style="color: rgb(0, 0, 0);">2005</span><span style="color: rgb(0, 0, 0);">&nbsp;实例，只需要启用一次&nbsp;SQL&nbsp;Server&nbsp;Browser&nbsp;服务。<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />(以下是个人的服务器上的配置，打开了&nbsp;TCP</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">IP&nbsp;和&nbsp;实例名)<br />
<img alt="同时使用 TCP/IP 和 Named Pipes (命名实例?)协议" src="http://www.blogjava.net/images/blogjava_net/kiant/2008.07.13/001.jpg" border="0" height="508" width="670" /></span></span></div>
<br />
<br />
<br />
<br />
二、通过 TCP 端口直接到 SQL Server 实例 (端口默认值是 1433)<br />
为SQL Server使用非标准的端口&nbsp;&nbsp;&nbsp;&nbsp;<a href=" http://www.windbi.com/showtopic-293.aspx" target="_blank">http://www.windbi.com/showtopic-293.aspx</a><br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_010657" onclick="this.style.display='none'; Code_Closed_Text_010657.style.display='none'; Code_Open_Image_010657.style.display='inline'; Code_Open_Text_010657.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11" /><img id="Code_Open_Image_010657" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_010657.style.display='none'; Code_Closed_Image_010657.style.display='inline'; Code_Closed_Text_010657.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11" /><span id="Code_Closed_Text_010657" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">摘要&amp;总结</span><span id="Code_Open_Text_010657" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><strong><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">、为社么要使用&nbsp;TCP</span><span style="color: rgb(0, 0, 0);">/</span></strong><span style="color: rgb(0, 0, 0);"><strong>IP&nbsp;连接</strong><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;在程序配置文件里，Data&nbsp;Source</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">（服务器的IP地址）比&nbsp;Data&nbsp;Source</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">(local)&nbsp;更有利于移植。<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">、服务器端关于标准端口(</span><span style="color: rgb(0, 0, 0);">1433</span></strong><span style="color: rgb(0, 0, 0);"><strong>)的更改</strong><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;当你安装SQL&nbsp;Server时，默认实例是监听1433端口号的。安全方面容易受到攻击。<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;当安装一个命名实例后，在它启动的时候默认使用的是动态决定的端口号。因此，命名实例每次启动时，都有可能监听不同的端口号。对于通过防火墙访问方式造成极大问题。<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;因此，<strong>为了限制对你的SQL&nbsp;Server的访问，你需要配置SQL&nbsp;Server去监听一个特定的端口</strong>。<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />(怎样配置SQL&nbsp;Server去监听特定的端口，示例中使用的是&nbsp;</span><span style="color: rgb(0, 0, 0);">1433</span><span style="color: rgb(0, 0, 0);">，你可以自由选择)<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/kiant/2008.07.13/002A.jpg" border="0" height="608" width="726" /><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<br />
<br />
3<strong>、使用特定端口设置时的客户端连接</strong><br />
客户端有3种方法连接到一个使用特定非标准端口号的实例。<br />
<br />
第一种方法是运行SQL Server Browser服务。<br />
第二个方法是在客户端机器上创建一个SQL Server的别名。<br />
最后一个方法是在连接字符串里通过编程来指定端口号。Data Source=SERVER2,8484;Initial Catalog=AdventureWorks<br />
<br />
(客户端协议)<br />
<img alt="客户端协议" src="http://www.blogjava.net/images/blogjava_net/kiant/2008.07.13/003.jpg" border="0" height="608" width="727" /><br />
<br />
<br />
<br />
结论<br />
正如你所看到的，在用一个特定的端口号来设置你的SQL Server实例时没有太多的工作要做。最大的问题就是确保连接字符串的编码要正确。当设置端口号的时候，要确保该端口号没有被使用。<strong>为了确保你的环境更加安全，我建议你关闭SQL Server Browser服务。这样所有的客户端在连接SQL Server的时候都要求指定端口号。<br />
</strong></span></span></div>
<br />
<br />
<br />
<br />
三、程序中使用端口连接数据库<br />
在连接到 SQL Server 数据库之前，必须首先在本地计算机或服务器上安装 SQL Server，并且必须在本地计算机上安装 JDBC 驱动程序。<br />
<a href="http://www.microsoft.com/downloads/details.aspx?familyid=C47053EB-3B64-4794-950D-81E1EC91C1BA&amp;displaylang=zh-cn" target="_blank">Microsoft SQL Server 2005 JDBC Driver 1.2 下载</a><br />
使用 JDBC 驱动程序&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://msdn.microsoft.com/zh-cn/library/ms378526.aspx" target="_blank">http://msdn.microsoft.com/zh-cn/library/ms378526.aspx</a><br />
创建连接 URL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://msdn.microsoft.com/zh-cn/library/ms378428.aspx" target="_blank">http://msdn.microsoft.com/zh-cn/library/ms378428.aspx</a><br />
myeclicse怎么与sql server 2005连接&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://zhidao.baidu.com/question/55043158.html?fr=qrl&amp;test=query" target="_blank">http://zhidao.baidu.com/question/55043158.html?fr=qrl&amp;test=query</a>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_063305" onclick="this.style.display='none'; Code_Closed_Text_063305.style.display='none'; Code_Open_Image_063305.style.display='inline'; Code_Open_Text_063305.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11" /><img id="Code_Open_Image_063305" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_063305.style.display='none'; Code_Closed_Image_063305.style.display='inline'; Code_Closed_Text_063305.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11" /><span id="Code_Closed_Text_063305" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">摘要&amp;总结</span><span id="Code_Open_Text_063305" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: rgb(0, 0, 0);"><strong>MyEclipse&nbsp;Database&nbsp;Explor&nbsp;配置</strong>&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />Driver&nbsp;Template&nbsp;：在下拉框中选择数据库驱动模板。这里这里选择&nbsp;Microsoft&nbsp;SQL&nbsp;Server&nbsp;</span><span style="color: rgb(0, 0, 0);">2005</span><span style="color: rgb(0, 0, 0);">&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />Driver&nbsp;JARS&nbsp;:&nbsp;添加sql&nbsp;jdbc&nbsp;。点击&nbsp;Add&nbsp;JARs&nbsp;。JDBC包的sqljdbc.jar文件。<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />Connection&nbsp;URL:&nbsp;&nbsp;jdbc:sqlserver:</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">10.0.0.99:1433;databaseName=AdventureWorks&nbsp;</span><span style="color: rgb(0, 128, 0);"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;或&nbsp;jdbc:sqlserver:</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">A9DFC026515C47B\MYSQL;databaseName=AdventureWorks&nbsp;&nbsp;(已启动SQL&nbsp;Server&nbsp;Browser服务)</span><span style="color: rgb(0, 128, 0);"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: rgb(0, 0, 0);">User&nbsp;name&nbsp;和&nbsp;Password为登陆名字和密码：&nbsp;好像必须填，</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">window&nbsp;身份验证</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">无效<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><strong>VS&nbsp;</strong></span><strong><span style="color: rgb(0, 0, 0);">2005</span><span style="color: rgb(0, 0, 0);">&nbsp;和&nbsp;SQL&nbsp;</span><span style="color: rgb(0, 0, 0);">2005</span></strong><span style="color: rgb(0, 0, 0);"><strong>&nbsp;中的配置</strong><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />几乎和MyEclipse&nbsp;Database&nbsp;Explor一样，只不过是&nbsp;端口号前面的&nbsp;</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">&nbsp;变成了&nbsp;</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />服务器名称：&nbsp;&nbsp;&nbsp;</span><strong><span style="color: rgb(0, 0, 0);">10.0</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">0.99</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">1433</span></strong><span style="color: rgb(0, 0, 0);"><strong>&nbsp;</strong><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><strong>与数据库建立简单连接</strong><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />若要使用&nbsp;DriverManager&nbsp;类连接到数据库，必须首先按如下方式注册驱动程序：<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />Class.forName(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">com.microsoft.sqlserver.jdbc.SQLServerDriver</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />加载驱动程序后，可通过使用连接&nbsp;URL&nbsp;来建立连接：<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />String&nbsp;connectionUrl&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">jdbc:sqlserver://localhost:1433;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">databaseName=AdventureWorks;user=MyUserName;password=*****;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />Connection&nbsp;con&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;DriverManager.getConnection(connectionUrl);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></span></div>
<br />
<br />
<br />
<br />
四、SQL 2005 更改sa密码<br />
<a href="http://topic.csdn.net/u/20071130/13/54df9ff6-ad1d-45a3-9d9b-da6a33714227.html" target="_blank">http://topic.csdn.net/u/20071130/13/54df9ff6-ad1d-45a3-9d9b-da6a33714227.html</a><br />
时间匆忙，没一一验证过。<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><img id="Code_Closed_Image_010436" onclick="this.style.display='none'; Code_Closed_Text_010436.style.display='none'; Code_Open_Image_010436.style.display='inline'; Code_Open_Text_010436.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" height="16" width="11" /><img id="Code_Open_Image_010436" style="display: none;" onclick="this.style.display='none'; Code_Open_Text_010436.style.display='none'; Code_Closed_Image_010436.style.display='inline'; Code_Closed_Text_010436.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" height="16" width="11" /><span id="Code_Closed_Text_010436" style="border: 1px solid rgb(128, 128, 128); background-color: rgb(255, 255, 255);">摘要</span><span id="Code_Open_Text_010436" style="display: none;"><br />
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: rgb(0, 0, 0);">企业管理里—安全性—账号—右健属性(最好取消密码策略这项)<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />sp_password&nbsp;</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(255, 0, 0);">OldPassword</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(255, 0, 0);">NewPassword</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(0, 0, 0);"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: rgb(0, 0, 255);">alter</span><span style="color: rgb(0, 0, 0);">&nbsp;login&nbsp;</span><span style="color: rgb(255, 0, 0);">[</span><span style="color: rgb(255, 0, 0);">sa</span><span style="color: rgb(255, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">with</span><span style="color: rgb(0, 0, 0);">&nbsp;password</span><span style="color: rgb(128, 128, 128);">=</span><span style="color: rgb(0, 0, 0);">N</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(255, 0, 0);">NewPassword</span><span style="color: rgb(255, 0, 0);">'</span><span style="color: rgb(0, 128, 128);">--</span><span style="color: rgb(0, 128, 128);">旧密码可以不用提供</span></span></div>
<br />
 <img src ="http://www.blogjava.net/kiant/aggbug/214637.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kiant/" target="_blank">黄小二</a> 2008-07-13 23:39 <a href="http://www.blogjava.net/kiant/articles/214637.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>