﻿<?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-tomjamescn-随笔分类-Database</title><link>http://www.blogjava.net/tomjamescn/category/41004.html</link><description>study java Platform....J2SE J2MM J2EE...</description><language>zh-cn</language><lastBuildDate>Tue, 13 Oct 2009 15:09:46 GMT</lastBuildDate><pubDate>Tue, 13 Oct 2009 15:09:46 GMT</pubDate><ttl>60</ttl><item><title>struts spring ibatis整合</title><link>http://www.blogjava.net/tomjamescn/archive/2009/09/25/296451.html</link><dc:creator>tomjamescn</dc:creator><author>tomjamescn</author><pubDate>Fri, 25 Sep 2009 09:13:00 GMT</pubDate><guid>http://www.blogjava.net/tomjamescn/archive/2009/09/25/296451.html</guid><wfw:comment>http://www.blogjava.net/tomjamescn/comments/296451.html</wfw:comment><comments>http://www.blogjava.net/tomjamescn/archive/2009/09/25/296451.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tomjamescn/comments/commentRss/296451.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tomjamescn/services/trackbacks/296451.html</trackback:ping><description><![CDATA[整合ssi虽然原理比较简单，但在实际操作的时候还是容易出错的，在这里也记录一下...<br />
各个组件的版本号：struts2.1 spring2.5 ibatis2.3<br />
<strong>struts2.1需要的包</strong><br />
&nbsp;&nbsp;&nbsp; 首先是struts2.1必须的包：<br />
<div align="center"><img alt="" src="http://www.blogjava.net/images/blogjava_net/tomjamescn/struts2.1package.jpg" height="146" width="235" /></div>
<br />
&nbsp;&nbsp;&nbsp; 然后是要与spring集成需要的包：struts2-spring-plugin-2.1.6.jar<br />
<br />
<strong>spring2.5需要的包</strong><br />
&nbsp;&nbsp;&nbsp; 这里用的是集成了spring所有模块的包：spring.jar<br />
<br />
<strong>ibatis2.3需要的包</strong><br />
&nbsp;&nbsp;&nbsp; ibatis-2.3.*.*.jar<br />
<br />
<strong>web.xml的配置</strong><br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">&lt;?</span><span style="color: #ff00ff;">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="color: #0000ff;">?&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<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 />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #ff0000;">&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi</span><span style="color: #0000ff;">="http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: #ff0000;"><br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #ff0000;">&nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation</span><span style="color: #0000ff;">="http://java.sun.com/xml/ns/j2ee&nbsp;<br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #0000ff;">&nbsp;&nbsp;&nbsp;&nbsp;http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">filter</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&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 />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&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;"><br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&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;"><br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">filter</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">listener</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">listener-class</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.springframework.web.context.ContextLoaderListener<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">listener-class</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">listener</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</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 />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&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 />
</span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&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;"><br />
</span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</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 />
</span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">welcome-file-list</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">welcome-file</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">login.jsp</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">welcome-file</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">welcome-file-list</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">24</span>&nbsp;<span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">web-app</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">25</span>&nbsp;</div>
<br />
<strong>applicationContext.xml的配置</strong><br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">&lt;?</span><span style="color: #ff00ff;">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="color: #0000ff;">?&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">beans&nbsp;</span><span style="color: #ff0000;">xmlns</span><span style="color: #0000ff;">="http://www.springframework.org/schema/beans"</span><span style="color: #ff0000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi</span><span style="color: #0000ff;">="http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: #ff0000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlns:aop</span><span style="color: #0000ff;">="http://www.springframework.org/schema/aop"</span><span style="color: #ff0000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlns:tx</span><span style="color: #0000ff;">="http://www.springframework.org/schema/tx"</span><span style="color: #ff0000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation</span><span style="color: #0000ff;">="<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/beans&nbsp;http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/aop&nbsp;http://www.springframework.org/schema/aop/spring-aop-2.5.xsd<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/tx&nbsp;http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bean&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="dataSource"</span><span style="color: #ff0000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class</span><span style="color: #0000ff;">="org.springframework.jdbc.datasource.DriverManagerDataSource"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="driverClassName"</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;">value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">org.gjt.mm.mysql.Driver</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">property</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="url"</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;">value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">jdbc:mysql://localhost:3306/test</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">property</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="username"</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;">value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">root</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">property</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="password"</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;">value</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">property</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bean</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bean&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="sqlMapClient"</span><span style="color: #ff0000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class</span><span style="color: #0000ff;">="org.springframework.orm.ibatis.SqlMapClientFactoryBean"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="dataSource"</span><span style="color: #ff0000;">&nbsp;ref</span><span style="color: #0000ff;">="dataSource"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="configLocation"</span><span style="color: #ff0000;">&nbsp;value</span><span style="color: #0000ff;">="WEB-INF/sql-map-config.xml"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bean</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bean&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="sqlMapClientTemplate"</span><span style="color: #ff0000;">&nbsp;class</span><span style="color: #0000ff;">="org.springframework.orm.ibatis.SqlMapClientTemplate"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="sqlMapClient"</span><span style="color: #ff0000;">&nbsp;ref</span><span style="color: #0000ff;">="sqlMapClient"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bean</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">&nbsp;其他配置，如DAO，Action--/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&lt;/beans&gt;</span></div>
<br />
<strong>sql-map-config.xml的配置</strong><br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">&lt;?</span><span style="color: #ff00ff;">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"&nbsp;</span><span style="color: #0000ff;">?&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;!</span><span style="color: #ff00ff;">DOCTYPE&nbsp;sqlMapConfig&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;PUBLIC&nbsp;"-//ibatis.apache.org//DTD&nbsp;SQL&nbsp;Map&nbsp;Config&nbsp;2.0//EN"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;"http://ibatis.apache.org/dtd/sql-map-config-2.dtd"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">sqlMapConfig</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">settings&nbsp;</span><span style="color: #ff0000;">useStatementNamespaces</span><span style="color: #0000ff;">="true"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">sqlMap&nbsp;</span><span style="color: #ff0000;">resource</span><span style="color: #0000ff;">="ssi/persistance/sqlmap/user_SqlMap.xml"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">sqlMapConfig</span><span style="color: #0000ff;">&gt;</span></div>
<br />
&nbsp;&nbsp;&nbsp; 具体sql-map文件的配置，这里就不写了，我也是刚刚学习ibatis，呵呵，由于最近马上就要开发了，就找了工具来加快速度，ibatis官方提供的ibator（原来叫abator）这个工具相当猛啊，还在学习中...<br />
<br />
&nbsp;&nbsp;&nbsp; 在配置过程当中，特别需要注意各个配置文件的存放位置，比如对于applicationContext.xml来说，默认应该存放在WEB-INF文件夹中，如果想放到类路径上去，需要在web.xml里面配置，一般配置在web.xml的开头部分：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">context-param</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">param-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">contextConfigLocation</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">param-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">param-value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
classpath:applicationContext.xml<br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">param-value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">context-param</span><span style="color: #0000ff;">&gt;</span></div>
<br />
<br />
<img src ="http://www.blogjava.net/tomjamescn/aggbug/296451.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tomjamescn/" target="_blank">tomjamescn</a> 2009-09-25 17:13 <a href="http://www.blogjava.net/tomjamescn/archive/2009/09/25/296451.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]hsqldb入门</title><link>http://www.blogjava.net/tomjamescn/archive/2009/09/24/296239.html</link><dc:creator>tomjamescn</dc:creator><author>tomjamescn</author><pubDate>Thu, 24 Sep 2009 01:55:00 GMT</pubDate><guid>http://www.blogjava.net/tomjamescn/archive/2009/09/24/296239.html</guid><wfw:comment>http://www.blogjava.net/tomjamescn/comments/296239.html</wfw:comment><comments>http://www.blogjava.net/tomjamescn/archive/2009/09/24/296239.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tomjamescn/comments/commentRss/296239.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tomjamescn/services/trackbacks/296239.html</trackback:ping><description><![CDATA[<p>来自：http://www.javaeye.com/topic/106626</p>
<p>一、简介： <br />
hsql数据库是一款纯Java编写的免费数据库，许可是BSD-style的协议。 <br />
相对其他数据库来说，其体积小，才563kb。 <br />
仅一个hsqldb.jar文件就包括了数据库引擎，数据库驱动，还有其他用户界面操作等内容。 <br />
下载地址：<a href="http://hsqldb.org/">http://hsqldb.org/</a> </p>
<p>二、使用hsql数据库： <br />
1、hsql数据库引擎有几种服务器模式：常用的Server模式、WebServer模式、Servlet模式、Standlone模式、Memory-On&amp;shy;ly数据库。 </p>
<p><br />
2、最为常用的Server模式： <br />
1)首先却换到lib文件夹下，运行java -cp hsqldb.jar <br />
org.hsqldb.Server -database.0 db/mydb -dbname.0 xdb <br />
执行命令后，将会在db文件夹下创建一个数据库mydb，别名（用于访问数据库）是xdb，如果存在mydb数据库，将会打开它。 <br />
2)运行数据库界面操作工具：java -cp hsqldb.jar <br />
org.hsqldb.util.DatabaseManager <br />
在Type选项里选上相应的服务器模式，这里选择HSQL <br />
Database Engine <br />
Server模式；Driver不用修改；URL修改为jdbc:hsqldb:hsql://localhost/xdb <br />
（主要这里xdb就是上面我们设置的别名）;user里设置用户名，第一次登录时，设置的是管理员的用户名，password设置密码。然后点击Ok。 <br />
3)第一次运行数据库引擎，创建数据库完毕。好了，你可以打开db文件夹，会发现里面多了几个文件。 <br />
mydb.properties文件：是关于数据库的属性文件。 <br />
mydb.script：hsql主要保存的表（这里按hsql的说法是Memory表，就是最为常用的），里面的格式都是文本格式，可以用文本查看，里面的语&amp;shy;句都是sql语句，熟悉sql语句的话，你也可以手动修改它。每次运行数据库引擎的话都是从这里加载进内存的。 <br />
mydb.lck表示数据库处于打开状态。 <br />
其他的请参看hsqldb包里的手册。 </p>
<p><br />
3、WebServer模式和Server运行模式基本一样，只是支持了Http等协议，主要用于防火墙，默认端口是9001。启动Server，java <br />
-cp hsqldb.jar org.hsqldb.WebServer ...剩余的和上面的一致。 </p>
<p><br />
4、Servlet模式可以允许你通过Servlet容器来访问数据库，请查看hsqlServlet.java的源代码，和WebServer类似。 </p>
<p><br />
5、另一个值得思考的模式是Standalone模式：不能通过网络来访问数据库，主要是在一个JVM中使用，那样的话，访问的速度会更加快。虽然文档里
面提到&amp;shy;主要是用于开发时使用，但是我们可以假设一下，该方法不需要一个引擎类的东西，而类似于打开文件的方式，返回一个
Connection对象： <br />
Connection c = DriverManager.getConnection("jdbc:hsqldb:file:mydb", <br />
"sa", ""); <br />
将会在当前目录找到mydb数据库相关文件，打开并返回一个Connection对象。该方式有点好处就是可以不使用引擎，在需要的时候操作数据。所以那
些对数&amp;shy;据库不是特别有要求的，但又需要一个操作数据库的方式的话，可以使用这种方法。对于那些不想额外在数据库引擎花费金钱的话，可以
使用这种方法。但是不推荐使用该&amp;shy;方法。记得Hibernate里SessionFactory可以使用
openSession(Connecttion <br />
c)来获得一个Session对象的，因此，在测试或者实际应用的话都可以这样使用。 </p>
<p><br />
6、Memory-Only <br />
数据库：顾名思义，主要是内存中使用，不用于保存数据。可以用于在内存中交换数据。 </p>
<p><br />
上面是关于hsqldb的一些基本信息的介绍，可以看到它的一些优势和特性。 <br />
我们可以把hsqldb内置在web程序中，除考虑Standalone模式外，最好是采用最为常用的Server模式。 <br />
那么Server模式如何和web程序合理搭配使用呢。 <br />
可以采用两种方式： <br />
1）采用上面提到的方法，运行java -cp hsqldb.jar <br />
org.hsqldb.Server -database.0 db/mydb -dbname.0 xdb <br />
来启动db，通过设置的URL：jdbc:hsqldb:hsql://localhost/xdb <br />
以达到在程序中访问hsql数据库的 <br />
（注：设置URL等信息，可以通过hibernate来配置，例如： <br />
hibernate.dialect org.hibernate.dialect.HSQLDialect <br />
hibernate.connection.driver_class org.hsqldb.jdbcDriver <br />
hibernate.connection.username sa <br />
hibernate.connection.password <br />
hibernate.connection.url jdbc:hsqldb:hsql://localhost/xdb ） <br />
2）为了省去第一种方法的琐碎，可以在启动web容器的过程中同时启动hsqldb。具体做法如下：编写一个有关hsql的Listener类，扩展javax&amp;shy;.servlet.ServletContextListener，可以在配置文件中设置dbPath、dbName、port等等hsqldb的信息，启动h&amp;shy;sqldb。 <br />
在web.xml中配置 <br />
&lt;listener&gt; </p>
<p><br />
&lt;listener-class&gt;com.iplan.portal.framework.web.HsqlListener&lt;/listener-class&amp;shy;&gt; <br />
&lt;/listener&gt; <br />
这样在启动web容器的时候，同时启动了hsqldb，关闭容器的时候同时也shutdown掉hsqldb。 </p>
<img src ="http://www.blogjava.net/tomjamescn/aggbug/296239.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tomjamescn/" target="_blank">tomjamescn</a> 2009-09-24 09:55 <a href="http://www.blogjava.net/tomjamescn/archive/2009/09/24/296239.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]关于Oracle ROWNUM的使用</title><link>http://www.blogjava.net/tomjamescn/archive/2009/08/30/293168.html</link><dc:creator>tomjamescn</dc:creator><author>tomjamescn</author><pubDate>Sun, 30 Aug 2009 03:56:00 GMT</pubDate><guid>http://www.blogjava.net/tomjamescn/archive/2009/08/30/293168.html</guid><wfw:comment>http://www.blogjava.net/tomjamescn/comments/293168.html</wfw:comment><comments>http://www.blogjava.net/tomjamescn/archive/2009/08/30/293168.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tomjamescn/comments/commentRss/293168.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tomjamescn/services/trackbacks/293168.html</trackback:ping><description><![CDATA[<p><strong title="rownum的概念，rownum是如何工作的。">ROWNUM的概念</strong><br />
ROWNUM是
一个虚假的列。它将被分配为 1，2，3，4，...N，N 是行的数量。一个ROWNUM值不是被永久的分配给一行
（这是最容易被误解的）。表中的某一行并没有标号；你不可以查询ROWNUM值为5的行——根本没有这个概念。另一个容易搞糊涂的问题是ROWNUM值是
何时被分配的。ROWNUM值的分配是在查询的谓词解析之后，任何排序和聚合之前进行的。ROWNUM值只有当被分配之后才会增长。这就是为什么下面的查
询永远都不会返回结果：<br />
select * from countries where rownum&gt;1;<br />
ROWNUM &gt; 1对于第一行来说并不是真值，ROWNUM没有增长到 2。所以，没有比1大的ROWNUM.永远都不要使用&#8217;ROWNUM&gt;？&#8216;和&#8217;ROWNUM=2&#8230;N&#8217;这样的条件。<br />
<br />
<strong title="如何用rownum显示排序结果的前N条记录">用rownum显示排序结果的前N条记录</strong><br />
FROM/WHERE子句先被执行.<br />
根据FROM/WHERE子句输出的行, ROWNUM被分配给他们并自增长.<br />
SELECT 被应用.<br />
GROUP BY 被应用.<br />
HAVING is 被应用.<br />
ORDER BY 被应用.<br />
这就是为什么下面的SQL几乎总是错误的:<br />
select rownum,job_title,min_salary<br />
from jobs where rownum&lt;3 order by min_salary;<br />
正确的写法: <br />
&nbsp; &nbsp; &nbsp; &nbsp; select rownum,tmp.* from (<br />
&nbsp; &nbsp; &nbsp; &nbsp; select job_title,min_salary <br />
&nbsp; &nbsp; &nbsp; &nbsp; from jobs order by min_salary) tmp<br />
&nbsp; &nbsp; &nbsp; &nbsp; where rownum&lt;=3;<br />
<br />
<strong title="如何用ROWNUM实现分页">用ROWNUM实现分页</strong><br />
select * from<br />
&nbsp; &nbsp; &nbsp; &nbsp; (select /*+ FIRST_ROWS(n) */ a.*,<br />
&nbsp; &nbsp; &nbsp; &nbsp; ROWNUM rnum<br />
&nbsp; &nbsp; &nbsp; &nbsp; from (your_query_goes_here, with order by) a<br />
&nbsp; &nbsp; &nbsp; &nbsp; where ROWNUM &lt;=<br />
&nbsp; &nbsp; &nbsp; &nbsp; :MAX_ROW_TO_FETCH )<br />
where rnum &gt;= :MIN_ROW_TO_FETCH;<br />
FIRST_ROWS(N)使优化器考虑最短时间获得前N条记录.<br />
:MAX_ROW_TO_FETCH 某一页中结果集的最后一行。如果你每页显示10行，要显示第6页,那么此值取60。<br />
:MIN_ROW_TO_FETCH 某一页中结果集的第一行。如果你每页显示10行，要显示第6页,那么此值取50。</p>
<p><strong>ROWNUM对性能的影响<br />
</strong>ROWNUM可以避免oracle在磁盘上进行排序。rownum无法避免全表扫描的发生，但是它可以避免对整个表数据的排序操作，在指定了rownum后，排序操作在内存中可以轻松完成。</p>
<img src ="http://www.blogjava.net/tomjamescn/aggbug/293168.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tomjamescn/" target="_blank">tomjamescn</a> 2009-08-30 11:56 <a href="http://www.blogjava.net/tomjamescn/archive/2009/08/30/293168.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]oracle sequence的概念及作用</title><link>http://www.blogjava.net/tomjamescn/archive/2009/08/30/293167.html</link><dc:creator>tomjamescn</dc:creator><author>tomjamescn</author><pubDate>Sun, 30 Aug 2009 03:52:00 GMT</pubDate><guid>http://www.blogjava.net/tomjamescn/archive/2009/08/30/293167.html</guid><wfw:comment>http://www.blogjava.net/tomjamescn/comments/293167.html</wfw:comment><comments>http://www.blogjava.net/tomjamescn/archive/2009/08/30/293167.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tomjamescn/comments/commentRss/293167.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tomjamescn/services/trackbacks/293167.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; sequence是用来在多用户环境下产生唯一整数的数据库对象。序列产生器顺序生成数字，它可用于自动生成主键值，并能协调多行或者多表的主键操
作。没有sequence，顺序的值只能靠编写程序来生成。先找出最近产生的值然后自增长。这种方法要求一个事务级别的锁，这将导致在多用户并发操作的环
境下，必须有人等待下一个主键值的产生。而且此方法很容易产生主键冲突的错误，如下图：<br />
time a......trans1 begin.........................................................<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;取max value=5&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br />
time b......&nbsp;max value+1=6........trans2 begin.....................<br />
&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; |<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; other action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max value=5<br />
&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; |<br />
time c.....&nbsp;commit;&nbsp;&nbsp;...................max value+1=6................<br />
&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;&nbsp;&nbsp; |<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; commt(ora-00001)
<p><br />
如上图，事务2会报主键冲突的错误，而再刷新一下页面（再执行一边程序），可能就正常了。<br />
还有一个问题，那就是完成生成主键的程序
（一般情况包含plsql块）本身对于并发调用也是一个瓶颈，因为这样的程序段往往是提供给好多程序去调用，如果代码端写的不够优化（比如没有使用邦定变
量等等），或者此代码段存在问题，那么它所影响的是系统的全局。我们应该提倡开发人员使用sequence。sequence消除了序列化问题，而且改善
了应用的并发能力。</p>
<h3>创建sequence</h3>
<p><br />
sequence的命名最重要的是要统一，命名规则是次要的。<br />
&nbsp;CREATE SEQUENCE emp_sequence<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INCREMENT BY 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; START WITH 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NOMAXVALUE<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NOCYCLE<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CACHE 10;<br />
这
里需要重点说明的是cache参数，它是为了应对并发访问的。cache参数告诉oracle预先分配一个sequence
numbers的集合，并且保留在内存中，以便sequence
number能够被快速的访问。这个内存的大小就是cache所指定的大小，当多个用户同时访问一个sequence的时候，是在oracle
SGA中读取sequence当前的合理数值，如果并发访问太大，cache的大小不够，那么就会产生sequence
cache相关的等待（enq: SQ - contention），影响系统性能。<br />
既然cache涉及到了内存，那么就会想到oracle实例恢复的问题。如果数据库shutdown abort，sequence会如何呢？当然会有问题，sequence number保存在内存里的但是没有被应用到表中的会丢失！</p>
<h3>修改sequence</h3>
<p><br />
除了修改sequence的starting number，你什么都能改，如果想改starting number，只能先drop然后create。<br />
ALTER SEQUENCE emp_sequence<br />
&nbsp;&nbsp;&nbsp; INCREMENT BY 10<br />
&nbsp;&nbsp;&nbsp; MAXVALUE 10000<br />
&nbsp;&nbsp;&nbsp; CYCLE<br />
&nbsp;&nbsp;&nbsp; CACHE 20;<br />
修
改很有用，最典型的情况是&#8220;需要把sequence 的current value改大一点，避免程序报错！&#8221;。你就可以看看current
value是多少，然后修改increment by 足够大的值，然后执行.nextval，最后别忘了再将increnent
by改成原来的值，还要注意做这些工作的前提是当前没有人用此sequence。</p>
<h3>使用 sequence</h3>
<p><br />
CURRVAL 和 NEXTVAL 能够在以下情况使用:<br />
insert的values字句、select中的select列表、update中的set字句</p>
<p>CURRVAL 和 NEXTVAL 不能够在以下情况使用:<br />
子查询、视图和实体化视图的查询、带distinct的select语句、带
group by和order
by的select语句、带union或intersect或minus的select语句、select中的where字句、create
table与alter table中的default值、check约束条件。</p>
<h3>删除sequence</h3>
<p><br />
drop sequence seq_a;<br />
当删除sequence后，对应它的同义词会被保留，但是引用时会报错。</p>
<h3>oracle rac环境中的sequence</h3>
<p><br />
oracle为了在rac环境下为了sequence的一致性，使用了三种锁：row cache lock、SQ锁、SV锁。<br />
row cache lock的目的是在sequence指定nocache的情况下调用sequence.nextval过程中保证序列的顺序性；<br />
SQ锁是应用于指定了cache+noorder的情况下调用sequence.nextval过程中。<br />
SV
锁（dfs lock handel) 是调用sequence.nextval期间拥有的锁。前提是创建sequence时指定了cache
和order属性 (cache+order)。order参数的目的是为了在RAC上节点之间生成sequence的顺序得到保障。</p>
<p>创建sequence赋予的cache值较小时，有enq:sq-contention等待增加的趋势。<br />
cache的缺省值是20.因此创建并发访问多的sequence时，cacheh值应取大一些。否则会发生enq:sq-contention等待事件。</p>
<p>rac上创建sequence时，如果指定了cache大小而赋予noorder属性，则各节点将会把不同范围的sequence值cache到内
存上。若两个节点之间都必须通过依次递增方式使用sequence，必须赋予如下的order属性（一般不需要这样做）"sql&gt; create
sequence seq_b cache 100
order"。如果是已赋予了cache+order属性的sequence，oracle使用SV锁进行同步。SV锁争用问题发生时的解决方法与sq锁
的情况相同，就是将cache 值进行适当调整。</p>
<p>在RAC多节点环境下，Sequence的Cache属性对性能的影响很大。应该尽量赋予cache+noorder属性，并要给予足够的
cache值。如果需要保障顺序，必须赋予cache+order属性。但这时为了保障顺序，实例之间需要不断的交换数据。因此性能稍差。</p>
<img src ="http://www.blogjava.net/tomjamescn/aggbug/293167.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tomjamescn/" target="_blank">tomjamescn</a> 2009-08-30 11:52 <a href="http://www.blogjava.net/tomjamescn/archive/2009/08/30/293167.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]理解ORACLE数据库字符集</title><link>http://www.blogjava.net/tomjamescn/archive/2009/08/19/291747.html</link><dc:creator>tomjamescn</dc:creator><author>tomjamescn</author><pubDate>Wed, 19 Aug 2009 02:12:00 GMT</pubDate><guid>http://www.blogjava.net/tomjamescn/archive/2009/08/19/291747.html</guid><wfw:comment>http://www.blogjava.net/tomjamescn/comments/291747.html</wfw:comment><comments>http://www.blogjava.net/tomjamescn/archive/2009/08/19/291747.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tomjamescn/comments/commentRss/291747.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tomjamescn/services/trackbacks/291747.html</trackback:ping><description><![CDATA[<p><strong><font size="3">来自：</font></strong><span style="color: red;">http://silverw0396.javaeye.com/blog/90554<strong><font size="3"></font></strong></span><strong><font size="3"><br />
</font></strong></p>
<p><strong><font size="3">一．引言</font></strong></p>
<p><font size="3"><strong>&nbsp;&nbsp;&nbsp; </strong>ORACLE数据库字符集，即Oracle全球化支持(Globalization Support)，或即国家语言支持（NLS）其作用是用本国语言和格式来存储、处理和检索数据。利用全球化支持，ORACLE为用户提供自己熟悉的数据库母语环境，诸如日期格式、数字格式和存储序列等。Oracle可以支持多种语言及字符集，其中oracle8i支持48种语言、76个国家地域、229种字符集，而oracle9i则支持57种语言、88个国家地域、235种字符集。由于oracle字符集种类多，且在存储、检索、迁移oracle数据时多个环节与字符集的设置密切相关，因此在实际的应用中，数据库开发和管理人员经常会遇到有关oracle字符集方面的问题。本文通过以下几个方面阐述，对oracle字符集做简要分析</font></p>
<p><strong><font size="3">二．字符集基本知识</font></strong></p>
<p><strong><font size="3">2.1字符集</font></strong><strong><br />
</strong><font size="3">&nbsp;&nbsp;&nbsp; 实质就是按照一定的字符编码方案，对一组特定的符号，分别赋予不同数值编码的集合。Oracle数据库最早支持的编码方案是US7ASCII。</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; Oracle</font><font size="3">的字符集命名遵循以下命名规则</font><font size="3">:<br />
&nbsp;&nbsp;&nbsp; &lt;Language&gt;&lt;bit size&gt;&lt;encoding&gt;<br />
&nbsp;&nbsp;&nbsp; 即:&nbsp; &lt;语言&gt;&lt;比特位数&gt;&lt;编码</font><font size="3">&gt;<br />
&nbsp;&nbsp;&nbsp; 比如: ZHS16GBK表示采用GBK编码格式、16位（两个字节）简体中文字符集</font></p>
<p><strong><font size="3">2.2字符编码方案</font></strong><strong><br />
</strong><font size="3">2.2.1 单字节编码</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（1）单字节7位字符集，可以定义128个字符，最常用的字符集为</font><font size="3">US7ASCII</font></p>
<p><font size="3">
&nbsp;&nbsp;&nbsp; （2）单字节8位字符集，可以定义256个字符，适合于欧洲大部分国家</font><br />
<font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="3">例如：WE8ISO8859P1(西欧、8位、ISO标准8859P1编码</font><font size="3">)</font></p>
<p><font size="3">
2.2.2 多字节编码</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（1）变长多字节编码</font><br />
<font size="3">&nbsp;&nbsp;&nbsp;&nbsp;</font><font size="3">某些字符用一个字节表示，其它字符用两个或多个字符表示，变长多字节编码常用于对亚洲语言的支持，例如日语、汉语、印地语等</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">例如：AL32UTF8（其中AL代表ALL,指适用于所有语言）、</font><font size="3">zhs16cgb231280</font></p>
<p><font size="3">
&nbsp;&nbsp;&nbsp; （2）定长多字节编码</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">每一个字符都使用固定长度字节的编码方案，目前oracle唯一支持的定长多字节编码是AF16UTF16，也是仅用于国家字符集</font></p>
<p><br />
<font size="3">2.2.3 unicode</font><font size="3">编码</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; Unicode</font><font size="3">是一个涵盖了目前全世界使用的所有已知字符的单一编码方案，也就是说Unicode为每一个字符提供唯一的编码。UTF-16是unicode的16位编码方式，是一种定长多字节编码，用2个字节表示一个unicode字符，AF16UTF16是UTF-16编码字符集。</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; UTF-8</font><font size="3">是unicode的8位编码方式，是一种变长多字节编码，这种编码可以用1、2、3个字节表示一个unicode字符，AL32UTF8，UTF8、UTFE是UTF-8编码字符集</font></p>
<p><strong><font size="3">2.3 字符集超级</font></strong><strong><br />
</strong><font size="3">&nbsp;&nbsp;&nbsp; 当一种字符集（字符集A）的编码数值包含所有另一种字符集（字符集B）的编码数值，并且两种字符集相同编码数值代表相同的字符时，则字符集A是字符集B的超级，或称字符集B是字符集A的子集。</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; Oracle8i</font><font size="3">和oracle9i官方文档资料中备有子集-超级对照表（subset-superset pairs），例如：WE8ISO8859P1是WE8MSWIN1252的子集。由于US7ASCII是最早的Oracle数据库编码格式，因此有许多字符集是US7ASCII的超集，例如WE8ISO8859P1、ZHS16CGB231280、ZHS16GBK都是US7ASCII的超集。</font></p>
<p><strong><font size="3">2.4 数据库字符集（oracle服务器端字符集）</font></strong><strong><br />
</strong><font size="3">&nbsp;&nbsp;&nbsp; 数据库字符集在创建数据库时指定，在创建后通常不能更改。在创建数据库时，可以指定字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。</font><br />
<font size="3">2.4.1</font> <font size="3">字符集</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; (1)</font><font size="3">用来存储CHAR, VARCHAR2, CLOB, LONG等类型数据</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; (2)</font><font size="3">用来标示诸如表名、列名以及PL/SQL变量等</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; (3)</font><font size="3">用来存储SQL和PL/SQL程序单元等</font></p>
<p><br />
<font size="3">2.4.2</font><font size="3"> 国家字符集：</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; (1)</font><font size="3">用以存储NCHAR, NVARCHAR2, NCLOB等类型数据</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; (2)</font><font size="3">国家字符集实质上是为oracle选择的附加字符集，主要作用是为了增强oracle的字符处理能力，因为NCHAR数据类型可以提供对亚洲使用定长多字节编码的支持，而数据库字符集则不能。国家字符集在oracle9i中进行了重新定义，只能在unicode编码中的AF16UTF16和UTF8中选择，默认值是</font><font size="3">AF16UTF16</font></p>
<p><font size="3">
2.4.3查询字符集参数</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">可以查询以下数据字典或视图查看字符集设置情况</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; nls_database_parameters</font><font size="3">、props$、</font><font size="3">v$nls_parameters<br />
&nbsp;&nbsp;&nbsp; 查询结果中NLS_CHARACTERSET表示字符集，NLS_NCHAR_CHARACTERSET表示国家字符集</font></p>
<p><br />
<font size="3">2.4.4</font><font size="3">修改数据库字符集</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">按照上文所说，数据库字符集在创建后原则上不能更改。如果需要修改字符集，通常需要导出数据库数据，重建数据库，再导入数据库数据的方式来转换，或通过ALTER DATABASE CHARACTER SET语句修改字符集，但创建数据库后修改字符集是有限制的，只有新的字符集是当前字符集的超集时才能修改数据库字符集，例如UTF8是US7ASCII的超集，修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8。</font></p>
<p><strong><font size="3">2.5 客户端字符集（NLS_LANG参数）</font></strong><br />
<font size="3">2.5.1 </font><font size="3">客户端字符集含义</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">客户端字符集定义了客户端字符数据的编码方式，任何发自或发往客户端的字符数据均使用客户端定义的字符集编码,客户端可以看作是能与数据库直接连接的各种应用，例如sqlplus,exp/imp等。客户端字符集是通过设置NLS_LANG参数来设定的。</font><br />
<font size="3">2.5.2 NLS_LANG</font><font size="3">参数格式</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; NLS_LANG=&lt;language&gt;_&lt;territory&gt;.&lt;client character set&gt; <br />
&nbsp;&nbsp;&nbsp; Language:</font><font size="3">显示oracle消息,校验，日期命名</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; Territory</font><font size="3">：指定默认日期、数字、货币等格式</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; Client character set</font><font size="3">：指定客户端将使用的字符集</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">例如：</font><font size="3">NLS_LANG=AMERICAN_AMERICA.US7ASCII&nbsp; <br />
&nbsp;&nbsp;&nbsp; AMERICAN是语言，AMERICA是地区，US7ASCII是客户端字符集</font><br />
<font size="3">2.5.3</font><font size="3">客户端字符集设置方法</font><br />
<font size="3">&nbsp;&nbsp;&nbsp;&nbsp; 1)UNIX</font><font size="3">环境</font><br />
<font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $NLS_LANG=&#8220;simplified chinese&#8221;_china.zhs16gbk<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $export NLS_LANG<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="3">编辑oracle用户的profile文件</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; 2)Windows</font><font size="3">环境</font><br />
<font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="3">编辑注册表</font><br />
<font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Regedit.exe---HKEY_LOCAL_MACHINE---SOFTWARE---ORACLE—HOME0<br />
2.5.4 NLS</font><font size="3">参数查询</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; Oracle</font><font size="3">提供若干NLS参数定制数据库和用户机以适应本地格式，例如有NLS_LANGUAGE,NLS_DATE_FORMAT,NLS_CALENDER等，可以通过查询以下数据字典或v$视图查看。</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; NLS_DATABASE_PARAMETERS--</font><font size="3">显示数据库当前NLS参数取值，包括数据库字符集取值</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; NLS_SESSION_PARAMETERS--</font><font size="3">显示由NLS_LANG 设置的参数，或经过alter session 改变后的参数值（不包括由NLS_LANG 设置的客户端字符集）</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; NLS_INSTANCE_PARAMETE--</font><font size="3">显示由参数文件init&lt;SID&gt;.ora 定义的参数V$NLS_PARAMETERS--显示数据库当前NLS参数取值</font><br />
<font size="3">2.5.5</font><font size="3">修改NLS参数</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">使用下列方法可以修改NLS参数</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（1）修改实例启动时使用的初始化参数文件</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（2）修改环境变量</font><font size="3">NLS_LANG<br />
&nbsp;&nbsp;&nbsp; （3）使用ALTER SESSION语句，在oracle会话中修改</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（4）使用某些SQL函数</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; NLS</font><font size="3">作用优先级别：Sql function&gt;alter session&gt;环境变量或注册表&gt;参数文件&gt;数据库默认参数</font></p>
<p><strong><font size="3">三．导入/导出与字符集转换</font></strong></p>
<p><strong><font size="3">3.1 EXP/IMP</font></strong><strong><br />
</strong><font size="3">&nbsp;&nbsp;&nbsp; Export 和 Import 是一对读写Oracle数据的工具。Export 将 Oracle 数据库中的数据输出到操作系统文件中, Import 把这些文件中的数据读到Oracle 数据库中，由于使用exp/imp进行数据迁移时，数据从源数据库到目标数据库的过程中有四个环节涉及到字符集，如果这四个环节的字符集不一致，将会发生字符集转换。</font></p>
<p><font size="3">EXP<br />
&nbsp;&nbsp;&nbsp;&nbsp; ____________&nbsp; &nbsp;_________________&nbsp; _____________<br />
&nbsp;&nbsp;&nbsp;&nbsp; |imp导入文件|&lt;-|环境变量NLS_LANG|&lt;-|数据库字符集|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;------------&nbsp;&nbsp; -----------------&nbsp;&nbsp;-------------</font></p>
<p><font size="3">IMP&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; ____________&nbsp; &nbsp;_________________&nbsp; _____________<br />
&nbsp;&nbsp;&nbsp;&nbsp; |imp导入文件|-&gt;|环境变量NLS_LANG|-&gt;|数据库字符集|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;------------&nbsp;&nbsp; -----------------&nbsp;&nbsp;-------------</font></p>
<p><font size="3">&nbsp;&nbsp;&nbsp; 四个字符集是</font><br />
<font size="3">&nbsp;&nbsp; </font><font size="3">（1）源数据库字符集 </font><br />
<font size="3">&nbsp;&nbsp; </font><font size="3">（2）Export过程中用户会话字符集（通过NLS_LANG设定）</font><br />
<font size="3">&nbsp;&nbsp; </font><font size="3">（3）Import过程中用户会话字符集（通过NLS_LANG设定）</font><br />
<font size="3">&nbsp;&nbsp; </font><font size="3">（4）目标数据库字符集</font></p>
<p><strong><font size="3">3.2导出的转换过程</font></strong><strong><br />
</strong><font size="3">&nbsp;&nbsp;&nbsp; 在Export过程中，如果源数据库字符集与Export用户会话字符集不一致，会发生字符集转换，并在导出文件的头部几个字节中存储Export用户会话字符集的ID号。在这个转换过程中可能发生数据的丢失。</font><br />
<font size="3">例:如果源数据库使用ZHS16GBK，而Export用户会话字符集使用US7ASCII，由于ZHS16GBK是16位字符集,而US7ASCII是7位字符集，这个转换过程中，中文字符在US7ASCII中不能够找到对等的字符，所以所有中文字符都会丢失而变成&#8220;?? &#8221;形式，这样转换后生成的Dmp文件已经发生了数据丢失。</font><br />
<font size="3">因此如果想正确导出源数据库数据，则Export过程中用户会话字符集应等于源数据库字符集或是源数据库字符集的超集</font></p>
<p><strong><font size="3">3.3导入的转换过程</font></strong><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（1）确定导出数据库字符集环境</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">通过读取导出文件头，可以获得导出文件的字符集设置</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（2）确定导入session的字符集，即导入Session使用的NLS_LANG环境变量</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（3）IMP读取导出文件</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">读取导出文件字符集ID，和导入进程的NLS_LANG进行比较</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（4）如果导出文件字符集和导入Session字符集相同，那么在这一步骤内就不需要转换，如果不同，就需要把数据转换为导入Session使用的字符集。可以看出，导入数据到数据库过程中发生两次字符集转换</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">第一次:导入文件字符集与导入Session使用的字符集之间的转换，如果这个转换过程不能正确完成，Import向目标数据库的导入过程也就不能完成。</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">第二次:导入Session字符集与数据库字符集之间的转换。</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">然而,oracle8i的这种转换只能在单字节字符集之间进行,oracle8i导入Session不支持多字节字符集之间的转换，因此为了避免第一次转换，导入Session使用的NLS_LANG与导出文件字符集相同，第二次转换（通过SQL*Net）支持任何两种字符集。以上情况在Oracle9i中略有不同</font></p>
<p><strong><font size="3">四．乱码问题</font></strong></p>
<p><font size="3">&nbsp;&nbsp;&nbsp; oracle在数据存储、迁移过程中经常发生字符乱码问题，归根到底是由于字符集使用不当引起。下面以使用客户端sqlplus向数据库插入数据和导入/导出（EXP/IMP）过程为例，说明乱码产生的原因。</font></p>
<p><strong><font size="3">4.1使用客户端sqlplus向数据库存储数据</font></strong><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">这个过程存在3个字符集设置</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（1）客户端应用字符集</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（2）客户端NLS_LANG参数设置</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（3）服务器端数据库字符集(Character Set)设置</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">客户端应用sqlplus中能够显示什么样的字符取决于客户端操作系统语言环境(客户端应用字符集)，但在应用中录入这些字符后，这些字符能否在数据库中正常存储，还与另外两个字符集设置紧密相关，其中客户端NLS_LANG参数主要用于字符数据传输过程中的转换判断。常见的乱码大致有两种情形：</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（1）汉字变成问号&#8220;？&#8221;；</font><br />
<font size="3">当从字符集A 转换成字符集B时，如果转换字符之间不存在对应关系，NLS_LANG使用替代字符&#8220;？&#8221;替代无法映射的字符</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（2）汉字变成未知字符（虽然有些是汉字，但与原字符含义不同）</font><br />
<font size="3">转换存在对应关系，但字符集A 中的字符编码与字符集B 中的字符编码代表不同含义</font></p>
<p><strong><font size="3">4.2发生乱码原因</font></strong><font size="3">&nbsp;<br />
&nbsp;&nbsp; &nbsp;乱码产生是由于几个字符集之间转换不匹配造成，分以下几种情况：</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">（注：字符集之间如果不存在子集、超集对应关系时的情况不予考虑，因为这种情况下字符集之间转换必产生乱码）</font><font size="3">&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; 1）服务器端数据库字符集与客户端应用字符集相同，与客户端NLS_LANG参数设置不同</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">如果客户端NLS_LANG字符集是其它两种字符集的子集，转换过程将出现乱码。</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">解决方法：将三种字符集设置成同一字符集，或NLS_LANG字符集是其它两种字符集的超集</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; 2</font><font size="3">）服务器端数据库字符集与客户端NLS_LANG参数设置相同，与客户端应用字符集不同</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">如果客户端应用字符集是其它两种字符集的超集时，转换过程将出现乱码，但对于单字节编码存储中文问题，可参看本文第5章节的分析</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; 3</font><font size="3">）客户端应用字符集、客户端NLS_LANG参数设置、服务器端数据库字符集互不相同</font><br />
<font size="3">&nbsp;&nbsp; &nbsp;</font><font size="3">此种情况较为复杂，但三种字符集之间只要有不能转换的字符，则必产生乱码</font></p>
<p><strong><font size="3">4.3导入/导出过程出现乱码原因</font></strong><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">这个过程存在4个字符集设置，在3.1章节中已分析</font><br />
<font size="3">&nbsp;&nbsp; </font><font size="3">（1）源数据库字符集</font><br />
<font size="3">&nbsp;&nbsp; </font><font size="3">（2）EXP过程中NLS_LANG参数 </font><br />
<font size="3">&nbsp;&nbsp; </font><font size="3">（3）IMP过程中NLS_LANG参数</font><br />
<font size="3">&nbsp;&nbsp; </font><font size="3">（4）目标数据库字符集</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">出现乱码原因</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; 1</font><font size="3">）当源数据库字符集不等于EXP过程中NLS_LANG参数，且源数据库字符集是EXP过程中NLS_LANG的子集，才能保证导出文件正确，其他情况则导出文件字符乱码</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; 2</font><font size="3">）EXP过程中NLS_LANG字符集不等于IMP过程中NLS_LANG字符集，且EXP过程中NLS_LANG字符集是IMP过程中NLS_LANG字符集的子级, 才能保证第一次转换正常，否则第一次转换中出现乱码。</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; 3</font><font size="3">）如果第一次转换正常，IMP过程中NLS_LANG字符集是目标数据库字符集的子集或相同，才能保证第二次转换正常，否则则第二次转换中出现乱码</font></p>
<p><strong><font size="3">五．单字节编码存储中文问题</font></strong></p>
<p><font size="3"><strong>&nbsp;&nbsp;&nbsp; </strong>由于历史的原因，早期的oracle没有中文字符集（如oracle6、oracle7、oracle7.1）,但有的用户从那时起就使用数据库了，并用US7ASCII字符集存储了中文，或是有的用户在创建数据库时，不考虑清楚，随意选择一个默认的字符集，如WE8ISO8859P1或US7ASCII，而这两个字符集都没有汉字编码，虽然有些时候选用这种字符集好象也能正常使用，但用这种字符集存储汉字信息从原则上说就是错误的，它会给数据库的使用与维护带来一系列的麻烦。</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">正常情况下，要将汉字存入数据库，数据库字符集必须支持中文，而将数据库字符集设置为US7ASCII等单字节字符集是不合适的。US7ASCII字符集只定义了128个符号，并不支持汉字。另外，如果在SQL*PLUS中能够输入中文，操作系统缺省应该是支持中文的，但如果在NLS_LANG中的字符集设置为US7ASCII，显然也是不正确的，它没有反映客户端的实际情况。但在实际应用中汉字显示却是正确的，这主要是因为Oracle检查数据库与客户端的字符集设置是同样的，那么数据在客户与数据库之间的存取过程中将不发生任何转换，但是这实际上导致了数据库标识的字符集与实际存入的内容是不相符的。而在SELECT的过程中，Oracle同样检查发现数据库与客户端的字符集设置是相同的，所以它也将存入的内容原封不动地传送到客户端，而客户端操作系统识别出这是汉字编码所以能够正确显示。</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">在这个例子中，数据库与客户端都没有设置成中文字符集，但却能正常显示中文，从应用的角度看好象没问题。然而这里面却存在着极大的隐患，比如在应用length或substr等字符串函数时，就可能得到意外的结果。</font><br />
<font size="3">&nbsp;&nbsp;&nbsp; </font><font size="3">对于早期使用US7ASCII字符集数据库的数据迁移到oracle8i/9i中（使用zhs16gbk），由于原始数据已经按照US7ASCII格式存储，对于这种情况，可以通过使用Oracle8i的导出工具，设置导出字符集为US7ASCII，导出后使用UltraEdit等工具打开dmp文件，修改第二、三字符，修改 0001 为0354,这样就可以将US7ASCII字符集的数据正确导入到ZHS16GBK的数据库中。</font></p>
<p><strong><font size="3">六．结束语</font></strong></p>
<p><font size="3">&nbsp;&nbsp;&nbsp; 为了避免在数据库迁移过程中由于字符集不同导致的数据损失，oracle提供了字符集扫描工具（character set scanner），通过这个工具我们可以测试在数据迁移过程中由于字符集转换可能带来的问题，然后根据测试结果，确定数据迁移过程中最佳字符集解决方案。</font></p>
<br />
<strong><font size="3">参考文献</font></strong><br />
<font size="3">[1]Biju Thomas , Bob Bryla</font><font size="3">《oracle9i DBA基础I 学习指南》电子工业出版社</font><font size="3"> 2002</font>
<img src ="http://www.blogjava.net/tomjamescn/aggbug/291747.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tomjamescn/" target="_blank">tomjamescn</a> 2009-08-19 10:12 <a href="http://www.blogjava.net/tomjamescn/archive/2009/08/19/291747.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]数据库设计建议，范式以及进一步</title><link>http://www.blogjava.net/tomjamescn/archive/2009/08/02/289448.html</link><dc:creator>tomjamescn</dc:creator><author>tomjamescn</author><pubDate>Sun, 02 Aug 2009 03:26:00 GMT</pubDate><guid>http://www.blogjava.net/tomjamescn/archive/2009/08/02/289448.html</guid><wfw:comment>http://www.blogjava.net/tomjamescn/comments/289448.html</wfw:comment><comments>http://www.blogjava.net/tomjamescn/archive/2009/08/02/289448.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tomjamescn/comments/commentRss/289448.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tomjamescn/services/trackbacks/289448.html</trackback:ping><description><![CDATA[<br />
<br />
&nbsp;&nbsp;&nbsp; <strong>转自：http://blog.csdn.net/ccat/archive/2009/05/14/4180765.aspx</strong><br />
&nbsp;&nbsp;&nbsp; 几乎每一个新人在初学关系型数据库设计的时候，都会接触到关系范式。但是，我还是见到了大量很离谱的设计。客观的说，背下关系范式，离一个合格的数据库设
计师还差很远。设计工作总是在理想与现实之，规范与工艺之间妥协。建筑如是，造船如是，操作系统设计如是，数据库设计亦如是。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
是的，你记得范式，你还记得反范式建议。你知道范式减少冗余，提高一致性；你还知道反范式可以方便编程。不幸的是，最终的结果总是遵守范式的做法使自己的应用层代码混乱，而反范式的企图使得数据库也陷入混乱。<br />
这是谁的错？<br />
&nbsp;&nbsp;&nbsp;&nbsp;
不必太自责，设计工作是一个经验的积累过程。没有人天生就会做设计。天才与勤奋，是乘法关系。并不是你笨，只是天才对面的那个系数还不够大而已。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
以下的一些经验，或许在你读完关系范式以后，可以抽空看一看 。世上没有魔法，读完这篇文章，并不会立即让你拥有多年设计经验。但是，这些在设计工作中积累的经验教训，应该可以帮助你少走一些弯路。<br />
<br />
<span style="font-weight: bold;">关于范式</span>
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;
关系范式并不邪恶，也不要把它想得太神秘，如果书本上的定义不能让你很快理解，不妨试着回答以下的问题：<br />
&nbsp;&nbsp;&nbsp;&nbsp;
字段还可以再分吗？分成两个或更多的字段以后，还能不能表达完整的含义？<br />
&nbsp;&nbsp;&nbsp;&nbsp;
字段的值是不是有限的几个离散的状态？<br />
&nbsp;&nbsp;&nbsp;&nbsp;
两个或若干个字段，能不能提取出来建立为一个数据字典？<br />
&nbsp;&nbsp;&nbsp;&nbsp;
如果表中某个字段依赖其他表，被依赖的字段是不是唯一的（最好是主键）？<br />
&nbsp;&nbsp;&nbsp;&nbsp;
查询中是否会出现超过两个表的Join？<br />
<br />
<span style="font-weight: bold;">将数据库设计与系统设计结合起来</span>
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;
数据库设计并不是一个孤立的过程，整个软件生命期中，各方面的工作应该有机结合。这方面我觉得ACCP过去的教材讲得还不错，至少思路是对的：<br />
&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-weight: bold;">在做需求分析的时候，做Use Case。</span>
此时可以分析出应用层的功能接口，对于数据库的实体分类可以有一个大概的划定。例如，这个项目会需要一个工作流，这个项目会需要一个订单系统，或者一个文档库，等等。通常，每个子系统可以对应一个<br />
&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-weight: bold;">在做概要设计的时候，出类关系和ER简图。</span>
通常来说，此时不能确定所有的字段，但是会有哪些表，有哪些主外键依赖，有哪些地方应该需要存储过程和触发器的辅助，等等。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-weight: bold;">详细设计时尽可能将数据库结构完全固定。</span>
尽管现代开发工具不断提升XP能力，重构越来越简单。数据库的重构仍然是一件牵一发而动全身的事情，毕竟数据库是信息存储的根本。大厦楼顶加个小花园容易，把地基下面的承重柱子拔出来换两根试试？<br />
<br />
<span style="font-weight: bold;">重视SQL</span>
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;
近年来ORM发展很快，几乎每个框架都要提供这个功能，以至于会有些菜鸟认为&#8220;ORM&#8221;会淘汰SQL语言。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
这是一块试金石，如果你有这样的感觉，应该考虑认真评估一下自己在这个领域是不是太菜了。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
SQL不是一种编程语言这么简单，SQL代表的是一种与应用开发语言完全不同的思想。面向集合，过程无关，着眼于规则定义。可以说，SQL是FP High Order计算的最成功应用，也可以说，SQL是一种静态强类型的MapReduce语言。<br />
看，换上时髦的名词，会不会让你觉得它上等起来了？<br />
&nbsp;&nbsp;&nbsp;&nbsp;
在应用层语言惨烈竞争的同时，SQL语言压倒了同时代出现的其他关系型数据库操作语言，在这个拥有巨大利润的领域占据了绝对统治地位。即使桀骜不驯的
Postgres，也在1995年变身为PostgrSQL。这一过程，并非像VC淘汰BC那么多盘外招，而是长时间争议与选择的结果。<br />
对于信息操作规则定义，SQL几乎是最好的表达方式。接近自然语言，高度可读，并且非常利于优化。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
打个比方，一个基于过程语言的上帝，这样说：<br />
&nbsp;&nbsp;&nbsp;&nbsp;
* 构造一个光源对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;
* 构造一个能源对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;
* 调用光源对象方法，设置能源<br />
&nbsp;&nbsp;&nbsp;&nbsp;
* 调用光源对象的发光方法，传入照明范围内的对象列表<br />
&nbsp;&nbsp;&nbsp;&nbsp;
基于SQL的上帝说，要有光。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
当然，在这位老兄背后，要有打杂的小弟去完成插电点灯的事情，但是作为上帝，什么活都自己做了，要天使干什么？<br />
&nbsp;&nbsp;&nbsp;&nbsp;
看看那些应用层语言的list comprehensions（列表推导式）。不止一次我想要为Python实现一个基于存储层的列表推导式实现，都可耻的失败了。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
当然，我承认这跟跟人能力有关，我不是Gudio。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
看看LINQ，不管如何吹嘘，它就是一个抽象出I/O的SQL。我见过一些人激烈的贬低SQL，抬高ORM，同时又对LINQ顶礼膜拜，这可真够分裂的。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
ORM对应用层编程效率的提升是客观的，无需回避。但是随着你数据操作越来越精细和复杂，就越来越需要通过规则定义来抽象High Order I/O过程。当你转了一圈儿回来，会发现自己又在写SQL。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
想想Hibernate的HQL，想想C#的LINQ。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
计算机不会变魔术。想让它做事更聪明，就需要你这个驭者更加聪明才行。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
好的工具和方法可以给你带来更高的能力系数，但是记住，一个乘法计算，仅有一头大是不够的。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
不懂SQL的人，是不能驾驭好ORM的。<br />
<br />
<span style="font-weight: bold;">与ORM做朋友</span>
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;
ORM对于开发工作，无疑是有好处的。我的朋友沈葳说，人脑能组织和分析的事务是有限的，所以代码越短，越有利于提高代码质量。从这个角度讲，ORM是非常重要的开发工具，其意义不亚于C API 函数集到GUI 框架的进步。<br />
要想让ORM充分发挥威力，有时候需要从数据库设计时就做出一定妥协。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
例如，你往往会需要加入自增标识列，会放弃一些精巧但是不利于ORM访问的依赖设定，甚至要放弃一些漂亮的命名（它们在应用层语言中是保留字，但是你用的ORM不懂如何规避）。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
但是，这往往是必要的。就像建筑师向气候和建筑材料妥协一样。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
在ORM默认的自增字段外，也许你还需要基于业务规则的唯一约束，那么额外加索引。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
好的ORM会帮助你方便的查询数据字典，生成对象映射，跟踪数据变更，提供数据完整性的应用层检查，构造两阶段提交事务，减少不必要的I/O。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
同样，不懂得运用ORM，也可能会破坏数据完整性，降低数据访问速度，甚至造成数据库死锁。作为项目开发人员，应该将ORM视为朋友而不是负担。<br />
<br />
<span style="font-weight: bold;">合理分层</span>
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;
过去，流行使用复杂的数据库设计，将业务规则存储于数据库的存储过程。现在，又流行抛弃数据层的一切约束，所有的规则都放在应用层。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
这两者都不合理，除了应用需求的影响，前者与Oracle的广告部宣传有关，后者与MySQL阵营的鼓动有关。背后都有一些不合理的力量推动。<br />
每一层应该保证自己的完整性，这才是分层的意义。那么，在数据库层，应该保证数据的完整性。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
数据库备份出来，再恢复进去，应该可以得到所有的业务信息。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
直接向数据库导入数据，应该可以有完整的数据规则保护。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
数据库里保存的，不仅仅是表和记录，应该是完整的持久性信息。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
从这个角度讲，配置文件和应用层代码中不应该有任何业务数据定义，这些信息都应该是数据字典表。如果出现了这种配置文件，大多数情况下都是愚蠢的错误。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
实际上，包括Web网站常见的附件上传，都应该保存在数据库中。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
独立的I/O文件存储、包括将外键约束转移到应用层，往往是因为对性能的妥协。以及，这里面确实存在MySQL阵营在推广过程中的一些不道德的宣传。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
有效利用数据库功能，可以提高应用层的开发速度，简化代码结构，使得数据存储更安全。这通常仰赖与设计人员的经验，根据项目的具体需求进行调整。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
基于这个原则，合理利用数据库功能，编写存储过程，触发器，调校索引，都是必要的。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
我敢打赌，随着MySQL实现越来越多的功能，它的宣传材料上会越来越多的出现以前被MySQL所摒弃的复杂设计理念，并且宣称这是MySQL所独创或一贯倡导的。<br />
<br />
<span style="font-weight: bold;">收集整理常见的模式</span>
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;
在设计模式提出这么多年，在关系型数据库问世如此之久后，我很惊讶的一件事就是数据库设计模式仍然是一个相当冷门的领域。实际上，关系数据库的模式也有很多
可循之规。例如用户信息（HR或CRM）、工作流，权限管理（如RBAC），订单等等，都有相当成熟的行业经验和时间，往往只要修改一些字段名，或者在关
键架构的基础上加以扩展，就可以很好的用于实践。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
每一个有志于成为高水平设计人员的开发者，都应该积极的收集自己体会到的数据库设计模式，积极的与同行交流。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
这方面，Oracle的示例Schema，Postgres的示例数据库项目（在Soureforge上可以找到），都是很好的例子。相对来说，微软在MSSQL和Access中提供的示例库更为轻量和简单，也是作为入门的不错借鉴。
<br />
<br />
<img src ="http://www.blogjava.net/tomjamescn/aggbug/289448.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tomjamescn/" target="_blank">tomjamescn</a> 2009-08-02 11:26 <a href="http://www.blogjava.net/tomjamescn/archive/2009/08/02/289448.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]数据库已死——让人醍醐灌顶的一片文章</title><link>http://www.blogjava.net/tomjamescn/archive/2009/08/02/289445.html</link><dc:creator>tomjamescn</dc:creator><author>tomjamescn</author><pubDate>Sun, 02 Aug 2009 03:02:00 GMT</pubDate><guid>http://www.blogjava.net/tomjamescn/archive/2009/08/02/289445.html</guid><wfw:comment>http://www.blogjava.net/tomjamescn/comments/289445.html</wfw:comment><comments>http://www.blogjava.net/tomjamescn/archive/2009/08/02/289445.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tomjamescn/comments/commentRss/289445.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tomjamescn/services/trackbacks/289445.html</trackback:ping><description><![CDATA[<br />
<p>&nbsp;&nbsp;&nbsp; <strong><span style="color: #ff0000;">来自J道Banq http://www.jdon.com/artichect/dbdead.htm</span></strong></p>
<br />
&nbsp;&nbsp;&nbsp; 现代软件和以往传统软件主要区别在于：现代软件基于internet互联网技术，运行于开放的网络环境，不象传统软件只是运行在封闭的局域网，运行环境的区别就决定了软件操作用户的多少，在一个开放互联网环境，
你的软件系统用户是不断增长，特别是那些对所有人群开放的社区网站系统，更是承受前所未有的访问负载。那么，这些软件系统承受的压力主要会集中在软件的哪个环节呢？如果你使用传统软件的设计思路，那么无疑压力都集中在数据库上。
<p>  随着用户的爆发量增长，在某个凌晨醒来时，你发现：数据库已死。</p>
<p>  传统软件系统实则应该叫数据库软件系统，是一个数据库系统，开发这样的系统非常简单，成本
也非常低廉，只要根据需求先设计好数据表结构，然后，就找一些大学毕业生写大量SQL语句，虽然还使用
JAVA/PHP/.NET等语言，但实际上这些语言只是将SQL送往数据库执行的运输工，没有什么价值和地位。</p>
<p>
所以，这样的系统运行在互联网环境下以后，主要负载就集中在数据库的SQL运行上，也就是说：整个软件系统性能关键点就集中在数据库上了，数据库是性能
主角，是王者；虽然你购置了昂贵的Websphere/weblogic等应用服务器，但是由于Java只是运输工，根本起不到性能上负载分担的作用。</p>
<p>  著名的社区网站MySpace就是因为一个好的idea，用户疯狂增长，但是系统却不能平滑承受增长的用户访问，这些用户访问网站缓慢、无法访问甚至丢失数据，他们经过几次伤筋动骨的架构升级，在微软SQLServer直接技术支持下，
好容易才勉强应付过去。看看他们痛苦经历，你是否也愿意再来一次呢？详细情况：                    <a href="http://www.jdon.com/jivejdon/thread/34601.html" target="_blank">http://www.jdon.com/jivejdon/thread/34601.html</a></p>
<p>  从中可以看出，数据库性能微调和挖潜总是有限度的，对数据库性能优化提高性能的步伐永远赶不上用户增长量，
有人也提出数据库集群的概念，其实数据库集群是一个骗人概念，一般只是备份，在集群数量和failover上有制约，
否则，数据库巨头Oracle不会跑到JavaEE阵营摇旗呐喊，还最早推出EJB3服务器，并扬言要收购JavaEE过去老大
Bea Weblogic。</p>
<p>  很显然，数据库成已经为软件系统的主要性能瓶颈了，单纯依靠数据库自救的方式已经行不通，是宣布数据库退出主角时候了，那么由谁来宣布：教皇数据库已死？无疑是Java。</p>
<p>  Java社区早在本世纪初就提出中间件概念，用以取代数据库地位，实则就是将软件系统主要负载从数据库上转移到中间件服务器上，分担负载。
也就是说：Java社区提出：既然数据库已经成为瓶颈，修修补补也无济于事，不如放弃它，不再依赖它。</p>
<p>  也就是说：Java不再做SQL的运输工，不再是跑龙套的了，而是主角，那么如何让Java成为主角呢？那必须依赖<a href="http://www.jdon.com/jivejdon/query/searchThreadAction.shtml?query=%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1&amp;useGBK=on" target="_blank">对象</a>这个概念，对象是生活在中间件服务器内存中，它又是数据库数据的业务封装，它和数据库有着
千丝万缕的关系，但是它又和<a href="http://www.jdon.com/jivejdon/query/searchThreadAction.shtml?query=%E9%98%BB%E6%8A%97&amp;useGBK=on" target="_blank">关系数据库存在天然矛盾</a>，两者水火不容。</p>
<p>  过去，我们是将业务逻辑写成SQL送往数据库执行，导致数据库成为业务逻辑主要运行瓶颈，那么，如果我们将
业务逻辑用对象概念表达，而不是SQL，那么我们的业务逻辑就围绕内存中的对象反复计算，这样，负载不是集中在
对象运行的中间件服务器上（也就是应用服务器Weblogic/websphere/JBoss/Tomcat）？而对象/中间件都是用Java
语言表达的，无疑，这样的架构，Java才成为主角。</p>
<p>  再进一步想想：如果我们从软件系统开始之初，就使用对象分析设计，不与数据库沾边，整个流程就完全OO，分析设计直至代码都摆脱了数据库影响，这个流程如下：<br />
</p>
<p>  分析建模 细化设计(通过<a href="http://www.jdon.com/jivejdon/key/ddd" target="_blank"><strong>Evans DDD</strong></a>) 架构设计  代码实现 调试测试 部署运行。<br />
<br />
那么数据库在什么时候建立呢？数据库表结构的创建可以延缓到部署运行时，由Hibernate/EJB CMP/JPA等ORM技术自动实现。这样，
整个上游环节就不涉及数据库技术，而是使用更符合自然的表达OO方式，软件质量就更高了。我在J道网站已经大量阐述了如何从OO分析
到OO实现的过程，包括我的Jdon框架也直接支持这样一个自然方式。</p>
<p>  现在，很多人已经理解，分析设计要用OO，但是数据库是运行阶段缺少不了的，确实，这是正确观点，我们夺取数据库的王位，不是将它打倒，只是理性和平移交权力重心而已，数据库退出主角地位，让位于Java中间件，也预示着过去数据库为王的时代的结束，
但是数据库会和操作系统一样，成为我们现代软件系统一个不可缺少重要的基础环节。</p>
<p>  正是基于这样事实，虽然我早在2005年喊出&#8220;<a href="http://www.jdon.com/artichect/dbover.htm" target="_blank">数据库时代的终结</a>一文，回帖长达几百贴，
大部分是怀疑论，不信论，其实2003年国外TSS就有一篇&#8220;<a href="http://www.jdon.com/jivejdon/thread/10351.html" target="_blank">给数据库休息吧</a>&#8221;
（休息不代表退休，而是退居幕后，就象操作系统作用一样），由此可见，由于传统观点影响和不及时与国际新思想同步，国内数据库保皇派还是有相当人数的。我
BanQ人微言轻，抛出这些观点被保皇派讥讽为所疯话，那么看看，著名ORM框架Hibernate和SEAM框架创始人Gavin
King的一段观点：<br />
</p>
<p>  In
almost all enterprise applications, the database is the primary
bottleneck, and the least scalable tier of the runtime environment.
数据库成为了大多数企业应用的主要瓶颈，也成为了运行环境中最不具伸缩性的层。... PHP/Ruby的用户会说什么都不共享（share
nothing）的架构照样具有很好的伸缩性，.... 这些傻瓜真正想的是&#8220;除了数据库以外什么都不共享(Share nothing except
for the database)&#8221;的架构。更多<a href="http://www.jdon.com/jivejdon/forum/messageList.shtml?thread=34551&amp;message=23116480#23116480" target="_blank">参看这里</a></p>
<p>
所谓伸缩性，就是弹性，整个软件架构既支持小负载运行，也支持大负载支持，只要增加服务器即可；
由于软件系统负载已经从SQL转移到内存中的对象上，那么我们就可以通过增加这些应用服务器数量，通过分布式计算甚至云计算，达到业务对象在多台应用服务
器之间传递共享，而不必通过数据库这个环节，既减轻数据库负载，又能轻松扩充性能，不必走
集中试大型主机之路，只要添置低廉PC服务器即可。经过权威测试：websphere/weblogic的20台PC服务器<a href="javascript:window.location.href=encodeURI('http://www.jdon.com/jivejdon/query/searchThreadAction.shtml?query=%E9%9B%86%E7%BE%A4')" target="_blank">集群</a>性能不亚于一台SUN/IBM的中型机，性价比已经一目了然了。</p>
<p>  JavaEE的服务器的<a href="javascript:window.location.href=encodeURI('http://www.jdon.com/jivejdon/query/searchThreadAction.shtml?query=%E9%9B%86%E7%BE%A4')">集群</a>相对于Linux等操作系统<a href="javascript:window.location.href=encodeURI('http://www.jdon.com/jivejdon/query/searchThreadAction.shtml?query=%E9%9B%86%E7%BE%A4')" target="_blank">集群</a>的好处在于：<a href="javascript:window.location.href=encodeURI('http://www.jdon.com/jivejdon/query/searchThreadAction.shtml?query=%E9%9B%86%E7%BE%A4')" target="_blank">JavaEE集群</a>能够针对某个繁忙负载大的具体业务功能进行集群，换句话说：
就是做到精确制导，精确解决问题，而显然，Linux操作系统的集群则无法直至业务核心的。</p>
<p>  从另外一个方面看：虽然现在PHP号称走上对象路线，Ruby的铁轨开始铺进企业，但是他们的运行环境实则依赖数据库的，
特别是Ruby On Rails还是最适合<a href="http://www.jdon.com/jivejdon/key/ddd" target="_blank"><strong>Evans DDD</strong></a>对象建模路线，但是目前来讲还是"披着羊皮的狼"，批着DDD，实则是以数据库中心。当然相信
ROR等将来会提供分布式计算环境，但是JavaEE在2002年时就通过EJB以及<a href="javascript:window.location.href=encodeURI('http://www.jdon.com/jivejdon/query/searchThreadAction.shtml?query=%E5%88%86%E5%B8%83%E5%BC%8F%E7%BC%93%E5%AD%98')" target="_blank">分布式缓存</a>成熟稳定地提供分布式计算的中间件，并且已经大量成熟应用。</p>
<p>  本文结束以前，我相信大家明白，在众多语言平台竞争中，为什么Java能够击败过去拳王数据库，夺得新的拳王冠军，以及他的特点所在。有人可能会说：你忘记谈.NET了，这个不用我回答你，用微软中国董事长张亚勤的话回答：<a href="http://www.jdon.com/jivejdon/forum/messageList.shtml?thread=33890&amp;message=23114056#23114056" target="_blank">8年前.NET战略很天真</a>，
你会将你的重要业务企业计算依赖一个很天真不成熟的技术吗？除非你自己也很天真:)。</p>
<img src ="http://www.blogjava.net/tomjamescn/aggbug/289445.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tomjamescn/" target="_blank">tomjamescn</a> 2009-08-02 11:02 <a href="http://www.blogjava.net/tomjamescn/archive/2009/08/02/289445.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转】SQL连接查询</title><link>http://www.blogjava.net/tomjamescn/archive/2009/08/01/289340.html</link><dc:creator>tomjamescn</dc:creator><author>tomjamescn</author><pubDate>Sat, 01 Aug 2009 01:35:00 GMT</pubDate><guid>http://www.blogjava.net/tomjamescn/archive/2009/08/01/289340.html</guid><wfw:comment>http://www.blogjava.net/tomjamescn/comments/289340.html</wfw:comment><comments>http://www.blogjava.net/tomjamescn/archive/2009/08/01/289340.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tomjamescn/comments/commentRss/289340.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tomjamescn/services/trackbacks/289340.html</trackback:ping><description><![CDATA[&nbsp; 原作者有版权声明，只能链接到他的页面了。<br />
&nbsp; 这篇博文对SQL的连接查询进行了实例化的讲解，适合入门和回顾SQL连接的相关知识...<br />
&nbsp; <a href="http://lavasoft.blog.51cto.com/62575/38929">http://lavasoft.blog.51cto.com/62575/38929</a><br />
<img src ="http://www.blogjava.net/tomjamescn/aggbug/289340.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tomjamescn/" target="_blank">tomjamescn</a> 2009-08-01 09:35 <a href="http://www.blogjava.net/tomjamescn/archive/2009/08/01/289340.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[原创]解决Oracle9i下表空间引起的导入失败</title><link>http://www.blogjava.net/tomjamescn/archive/2009/07/22/287905.html</link><dc:creator>tomjamescn</dc:creator><author>tomjamescn</author><pubDate>Wed, 22 Jul 2009 12:25:00 GMT</pubDate><guid>http://www.blogjava.net/tomjamescn/archive/2009/07/22/287905.html</guid><wfw:comment>http://www.blogjava.net/tomjamescn/comments/287905.html</wfw:comment><comments>http://www.blogjava.net/tomjamescn/archive/2009/07/22/287905.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tomjamescn/comments/commentRss/287905.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tomjamescn/services/trackbacks/287905.html</trackback:ping><description><![CDATA[&nbsp; 用exp命令导出了一个dmp文件，在导入时遇到了问题，提示说表空间不存在。在网上搜索的方法太复杂，其实，如果需要导入的表比较少，可以直接用二进制编辑器，如UltraEdit32直接编辑dmp文件。把里面的表空间字符串改为被导入的表空间即可。<br />
<img src ="http://www.blogjava.net/tomjamescn/aggbug/287905.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tomjamescn/" target="_blank">tomjamescn</a> 2009-07-22 20:25 <a href="http://www.blogjava.net/tomjamescn/archive/2009/07/22/287905.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>