|
原代碼:http://www.tkk7.com/Files/Good-Game/myAnt.rar
對一般開發 使用的ant <?xml?version="1.0"?> <project?name="general"?default="doc">
<!--?使用說明: ?????需要設置的參數?:?src.dir?、?classes.dir -->
<!--?properies?--> ????<property?name="src.dir"?value="src"?/> ????<property?name="lib.dir"?value="lib"?/> ???? ????<property?name="report.dir"?value="report"?/> ????<property?name="classes.dir"?value="bin"?/> ????<property?name="dist.dir"?value="dist"?/> ????<property?name="doc.dir"?value="doc"/>
<!--???定義classpath?--> <path?id="master-classpath"> ????<fileset?file="${lib.dir}/*.jar"?/> ????<pathelement?path="${classes.dir}"/> </path>
<!--?初始化任務?--> <target?name="init"> ????<copy?todir?="${classes.dir}">?? ???????<fileset?dir?="${src.dir}">? ?????????????<exclude?name="**/build.xml"/> ?????????????<exclude?name="**/*.java"?/> ??????????</fileset?>?? ???????</copy?>?? </target>
<!--?編譯?--> <target?name="compile"?depends="init"?description="compile?the?source?files"> ????<mkdir?dir="${classes.dir}"/> ????<javac?srcdir="${src.dir}"?destdir="${classes.dir}"?target="1.4"> ????????<classpath?refid="master-classpath"/> ????</javac> </target>
<!--?測試?--> <target?name="test"?depends="compile"?description="run?junit?test"> ????<mkdir?dir="${report.dir}"/> ????<junit?????printsummary="on" ????????????haltonfailure="false" ????????????failureproperty="tests.failed" ????????????showoutput="true"> ????????<classpath?refid="master-classpath"?/> ????????<formatter?type="plain"/> ????????<batchtest?todir="${report.dir}"> ????????<fileset?dir="${classes.dir}"> ????????????<include?name="**/Test*"/> ????????</fileset> ????????</batchtest> ????</junit> <fail?if="tests.failed"> *********************************************************** ****?One?or?more?tests?failed!?Check?the?output? ?**** *********************************************************** </fail> </target>
<!--?打包成jar?--> <target?name="pack"?depends="test"?description="make?.jar?file"> ????<mkdir?dir="${dist.dir}"?/> ????<jar?destfile="${dist.dir}/hello.jar"?basedir="${classes.dir}"> ????????<exclude?name="**/*Test.*"?/> ????????<exclude?name="**/Test*.*"?/> ????</jar> </target>
<!--?輸出api文檔?--> <target?name="doc"?depends="pack"?description="create?api?doc"> ????<mkdir?dir="${doc.dir}"?/> ??????<javadoc ???????????destdir="${doc.dir}" ???????????author="true" ???????????version="true" ???????????use="true" ???????????windowtitle="Test?API"> ????<fileset?dir="src"?defaultexcludes="yes"> ????????<include?name="**/**.java"/> ????????<exclude?name="**/*Test.java"?/> ????????<exclude?name="**/Test*.*"?/> ????</fileset> ???</javadoc> </target>
<!--?clean?doc?--> <target?name="clean_doc"?description="create?api?doc"> ?????<delete?includeEmptyDirs?=?"true"> ????????<fileset?dir="${doc.dir}"/> ?????</delete?> </target> <!--?clean?class?and?lib?--> <target?name="clean_class_dist"??description="create?class?dist"> ?????<delete> ????????<fileset?dir="${classes.dir}"/> ????????<fileset?dir="${dist.dir}"/>??????? ?????</delete?> </target>
</project> ant XDoclet Generation <?xml?version="1.0"?encoding="UTF-8"?> <project?name="ant?XDoclet?Generation"?default="_xdoclet_generation_"> <property?file="xdoclet-build.properties"/> <!--?使用說明: ?????需要設置的參數?:?java.home?、?xdoclet.home? --> <property?environment="env"/> ????<property?name="java.home"?value="${env.JAVA_HOME}"/>? ????<property?????name="xdoclet.home"? ????????????value="D:\hbn\hibernate-3.2\xdoclet-1.2.3"/> ???? <path?id="xdoclet.classpath"> ????<pathelement?location="${java.home}/**/*.jar"/> ????<fileset?dir="${xdoclet.home}"> ????????<include?name="**/*.jar"/> ????</fileset> </path>
<target?name="_xdoclet_generation_"?depends="N10004"/> <target?name="N10004"?description="Standard?Hibernate"> <taskdef?classpathref="xdoclet.classpath"? ?????????classname="xdoclet.modules.hibernate.HibernateDocletTask"? ?????????name="hibernatedoclet"/> ? <hibernatedoclet?excludedTags="@version,@author,@todo,@see"?? ?????????????????destDir="src"?? ?????????????????addedTags="@xdoclet-generated?at?${TODAY},@copyright?The?XDoclet?Team,@author?XDoclet,@version?${version}"?> ????<fileset?dir="src"??includes="**/*.java"?> ????</fileset> ????<hibernate> ????</hibernate> </hibernatedoclet> </target> </project>
對hbn深入過程中,發現開發和設計持久層 到項目后期,越來越困難。在次仔細查分析。特總結一種開發方法。留下與大家分享,歡迎拍磚。 開發過程描述:1.使用 MyEclipes -> uml? 創建類圖 2.用 Generate java Code 根據類圖生成 java文件 3.使用 Xdoclet 添加 Hbn 標簽 4.配置myEclipes -> XDoclet 自動生成 mapping.hbn.xml 5.使用myEclipes 把項目轉化成 hibernate? 項目 6.使用 org.hibernate.tool.hbm2ddl.SchemaExport 建表 開發過程好處:1)完全是面向對象,不需要寫xml配置文件(XDoclet); 2)項目后期修改容易面對uml 3)用myEclipes 這些都不用去找,直接拿來用(uml,XDoclet,hibernate ..) 下面就來個 小例把
1.MyEclipes 使用 uml 參考-> MyEclipse 5.5 UML 入門視頻 ( 作者:BeanSoft)  2.由uml生成類文件  3.先使用 eclipes的 快鍵方法寫 get/set 方法, 類文件文件添加 hbn XDoclet的注解 package?bean;
/**? ?*?@hibernate.class?table="t1oo" ?*/ public?class?T1oo?{
??public?int?id; ??public?String?name; ??public?int?avg; ?? ??/**? ???*?@hibernate.property? ???*?column="avg" ???*?length="4" ???*?not-null="true" ???*/ public?int?getAvg()?{ ????return?avg; } public?void?setAvg(int?avg)?{ ????this.avg?=?avg; } /** ?*?@hibernate.id? ?*?column="id" ?*?generator-class="hilo" ?*/ public?int?getId()?{ ????return?id; } public?void?setId(int?id)?{ ????this.id?=?id; } /** ?*?@hibernate.property? ?*?column="name" ?*?not-null="true"? ?*?@return ?*/ public?String?getName()?{ ????return?name; } public?void?setName(String?name)?{ ????this.name?=?name; } ??
} 4.用myEclipes 生成 XDoclet 在項目點右鍵-> properties -> MyEclipse-XDoclet -> 在Configuration 空白初點右鍵 選 add standard -> ... hbn 后面不太好描述 可以查下很簡單的 。配置好了運行后就可以看見 多了 個 T1oo.hbm.xml 文件; 5.myEclipes + hbn 就不多說了 6. hbn2java: ????public?void?testCreateTable()throws?Exception{ ?????????HibernateSessionFactory.currentSession(); ?????????HibernateSessionFactory.closeSession(); ????????? ?????????Field[]?ff?=?HibernateSessionFactory.class.getDeclaredFields(); ?????????Field?fie?=?null?; ?????????for(int?i=0;i<ff.length;i++){ ?????????????if(?ff[i].getType().equals(?Configuration.class?)?){ ?????????????????fie?=?ff[i]; ?????????????} ?????????} ?????????fie.setAccessible(true); ?????????Configuration?cfg?=?(Configuration)fie.get(HibernateSessionFactory.class); ?????????cfg.addInputStream(?this.getClass().getResourceAsStream("/bean/T1oo.hbm.xml")?); ???????? //建表 ??????????SchemaExport?dbExport?=?new?SchemaExport(cfg); ??????????dbExport.setOutputFile("c:\\db\\test.txt"); ??????????dbExport.create(true,?true);? ????} sql: drop table if exists t1oo drop table if exists hibernate_unique_key create table t1oo ( ??? id integer not null, ??? avg integer not null, ??? name varchar(255) not null, ??? primary key (id) ) create table hibernate_unique_key ( ???? next_hi integer ) insert into hibernate_unique_key values ( 0 )
效果: mysql> show tables; +----------------------+ | Tables_in_hbn??????? | +----------------------+ | hibernate_unique_key | | t1oo???????????????? | +----------------------+ 2 rows in set (0.00 sec)
表關系 T1oo ->ont-to-many-> T2oo (t1oo.id-t2oo.aid) 1.單條select延遲加載 ????????Iterator?it?=?session.createQuery("from?T1oo?").iterate(); ????????while(it.hasNext()){ ????????????T1oo?t1?=?(T1oo)it.next(); ????????????t1.getName(); ????????} /*運行語句?n+1 這就只加載 id Hibernate:?select?t1oo0_.id?as?col_0_0_?from?t1oo t1oo0_ 此是在 t1.getName(); 延遲加載的 Hibernate:?select?t1oo0_.id?as?id0_,?t1oo0_.name?as?name0_0_?from?t1oo?t1oo0_?where?t1oo0_.id=? Hibernate:?select?t1oo0_.id?as?id0_,?t1oo0_.name?as?name0_0_?from?t1oo?t1oo0_?where?t1oo0_.id=? */ 2.級連查詢: 1)set排序? <set ... order-by="avg desc" ...> 從大到小 2)batch-size="10" 用法是 ??? select * from t2oo? where aid in (?,?,?....) 3) 如果想忽略延遲,并有一定邏輯全部加載,這有兩中解決辦法: 1).內連 mysql>?select???* ????->?from?t1oo?t1oo0_?inner?join?t2oo?t2ooset1_?on?t1oo0_.id=t2ooset1_.aid; +----+-----------+----+-----+------+---------+ | id | name????? | id | avg | aid? | version | +----+-----------+----+-----+------+---------+ |? 1 | liukaiyi? |? 1 |? 23 |??? 1 |?????? 1 | |? 1 | liukaiyi? |? 2 |? 24 |??? 1 |?????? 1 | |? 1 | liukaiyi? |? 3 |? 25 |??? 1 |?????? 1 | |? 2 | liukaiyi2 |? 4 |? 26 |??? 2 |?????? 0 | +----+-----------+----+-----+------+---------+
? ? ? ? ? Iterator?it?=?new?HashSet(session.createQuery("from?T1oo?t1?inner?join?fetch?t1.t2ooSet?t2where t2.id<=3").list()).iterator(); ????????while(it.hasNext()){ ????????????T1oo?t1?=?(T1oo)it.next(); ????????????System.out.println(t1.getName()); ???????????? ????????????for(Iterator?itr=t1.getT2ooSet().iterator();itr.hasNext();?){ ????????????????T2oo?t2?=?(T2oo)itr.next(); ????????????????System.out.println("??"+?t2.getAvg()?); ????????????} ????????} 結果是: Hibernate:?select?t1oo0_.id?as?id0_,?t2ooset1_.id?as?id1_,?t1oo0_.name?as?name0_0_,?t2ooset1_.version?as?version1_1_,?t2ooset1_.avg?as?avg1_1_,?t2ooset1_.aid?as?aid1_1_,?t2ooset1_.aid?as?aid0__,?t2ooset1_.id?as?id0__?from?t1oo?t1oo0_?inner?join?t2oo?t2ooset1_?on?t1oo0_.id=t2ooset1_.aid?where?t2ooset1_.id<=3 liukaiyi ??24 ??23 ??25
在hibernate.cfg.xml 中添加緩存? t1oo 一對多 t2oo (t2ooSet) ????<property?name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> ????<property?name="hibernate.cache.use_query_cache">true</property>
????<mapping?resource="hbn/bean/T1oo.hbm.xml"?/> ????<mapping?resource="hbn/bean/T2oo.hbm.xml"?/>
????<class-cache?class="hbn.bean.T1oo"?usage="read-only"?/> ????<collection-cache?collection="hbn.bean.T1oo.t2ooSet"?usage="read-only"?/> ????<class-cache?class="hbn.bean.T2oo"?usage="read-only"?/> 在src根目錄下 ehcache.xml <?xml?version="1.0"?encoding="UTF-8"?> <ehcache> ????<diskStore?path="java.io.tmpdir"/> ????<defaultCache ????????maxElementsInMemory="10000" //最大緩存數目 ????????eternal="false"<!-- 緩存是否持久 --> ????????timeToIdleSeconds="120" <!-- 當緩存閑置n秒后銷毀 --> ????????timeToLiveSeconds="120"<!-- 當緩存存活n秒后銷毀--> ????????overflowToDisk="true"<!-- 是否保存到磁盤,當系統當機時--> ????????diskPersistent="false" ????????diskExpiryThreadIntervalSeconds="120"/>
????<cache ?????name="hbn.bean.T1oo" ?????maxElementsInMemory="450" ?????eternal="false" ?????timeToLiveSeconds="600" ?????overflowToDisk="true"/>
</ehcache> 測試: ????public?void?testCa()throws?Exception{ ????????System.out.println( getT1ooAll()?); ???????? ????????Thread.sleep(2*1000); ???????? ????????System.out.println( getT1ooAll()?); ????} 控制臺輸出 Hibernate:?select?t1oo0_.id?as?id,?t1oo0_.name?as?name0_?from?t1oo?t1oo0_?limit??
Hibernate:?select?t2ooset0_.aid?as?aid1_,?t2ooset0_.id?as?id1_,?t2ooset0_.id?as?id0_,?t2ooset0_.version?as?version1_0_,?t2ooset0_.avg?as?avg1_0_,?t2ooset0_.aid?as?aid1_0_?from?t2oo?t2ooset0_?where?t2ooset0_.aid=? Hibernate:?select?t2ooset0_.aid?as?aid1_,?t2ooset0_.id?as?id1_,?t2ooset0_.id?as?id0_,?t2ooset0_.version?as?version1_0_,?t2ooset0_.avg?as?avg1_0_,?t2ooset0_.aid?as?aid1_0_?from?t2oo?t2ooset0_?where?t2ooset0_.aid=? 24?:?23?:?25?:?2
//在這緩存成功 沒向數據庫提交 sql語句 24?:?23?:?25?:?2
在此特別感謝:sql技術群主 ☆藍藍心情★ 謝謝在中午遠程教我 EJB 原理參考:EJB原理學習_RMIC 這可能是我第一個EJB 和大家分享: 環境:jboss+ejb+jdk5.0
需要jar包
注:Client中 Test.jar 就是 EJBTest(服務器打的包)
EJB組件: 接口
package
?org.test;
import
?javax.ejb.Remote;
//在我的EJB原理中介紹 //是可以被
rmic 的接口
@Remote
public
?
interface
?IHello?{ ????
public
?String?sayHello(String?name); }
實現類
package
?org.test;
import
?javax.ejb.Stateless;
import
?org.jboss.annotation.ejb.RemoteBinding;
@Stateless //設置遠程JNDI名字(設置遠程JNDI名字,客戶端在通過JNDI lookup的時候,用的就是這個名字) //不同中間件的實現,默認JNDI名字是不一樣的,所以不一定是***/Remote或***/Local //RemoteBinding是 jboss特有的 @RemoteBinding(jndiBinding
=
"
MclarenEJB
"
)
public
?
class
?Hello?
implements
?IHello?{ ????
public
?String?sayHello(String?name)?{ ????????
return
?
"
Hello?
"
+
name; ????} }
jdk編輯+打包成jar后熱部署到%JBOSS_HOME%\server\default\deploy
客戶端:
import
?java.util.Properties;
import
?javax.naming.Context;
import
?javax.naming.InitialContext;
import
?org.test.IHello;
public
?
class
?Client?{
????
public
?
static
?
void
?main(String[]?args)?{ ????????
try
?{
?????????Properties?props?
=
?
new
?Properties(); ?????????props.put(
"
java.naming.factory.initial
"
,?
"
org.jnp.interfaces.NamingContextFactory
"
); ?????????props.put(
"
java.naming.provider.url
"
,?
"
jnp://localhost:1099
"
); ?????????props.put(
"
java.naming.factory.url.pkgs
"
,?
"
org.jboss.naming:org.jnp.interfaces
"
);
?????????Context?context?
=
?
new
?InitialContext(props);
?????????IHello?h?
=
?(IHello)?context.lookup(
"
MclarenEJB
"
); ?????????System.out.println(h.sayHello(
"
EJB?3.0?Test
"
)); ????????}?
catch
(Exception?e)?{ ????????????e.printStackTrace(); ????????} ????}
}
結果是: Hello EJB 3.0 Test
EJB原理,有幸在 Q群上‘☆藍藍心情★’ 得以一教; 特在次鄭重的道一聲 謝謝了.大哥
在次我就分享給大家,本人語言組織能力有限,說的不好可別怪我大哥啊。(呵呵)
EJB技術對傳輸上進行封裝,使程序員不需要關心太多網絡問題。服務器都基于統一javabean操作的 在這就是基于 rmic 命令,和 rmiregistry 端口 來實現的。 rmic 和 rmiregistry 這些都在%JAVA_HOME%/bin下可以找到。 下面我就用大哥給寫的一段 沒用EJB容器 的代碼來和大家分享EJB原理:
1.rmic命令介紹: 引用:? http://www.iplab.cs.tsukuba.ac.jp/liuxj/jdk1.2/zh/docs/tooldocs/solaris/rmic.html rmic 編譯器根據編譯后的 Java 類(含有遠程對象實現)名,為遠程對象生成 stub 和 skeleton(遠程對象是指實現 java.rmi.Remote 接口的對象)。 在 rmic 命令中所給的類必須是經 javac 命令成功編譯且是完全包限定的類。例如,按如下所示對類文件名 HelloImpl 運行 rmic:
2.EJB組建(服務器端)接口:
package?org.rmi.test;
import?java.rmi.Remote; import?java.rmi.RemoteException;
public?interface?IHello?extends?Remote?{ ????public?String?sayHello(String?name)?throws?RemoteException; }
實現類:
package?org.rmi.test;
import?java.rmi.Naming; import?java.rmi.RemoteException; import?java.rmi.server.UnicastRemoteObject; //取消顯示指定的編譯器警告! //參考 : http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/SuppressWarnings.html @SuppressWarnings("serial") public?class?Hello?extends?UnicastRemoteObject?implements?IHello?{ ????public?Hello()?throws?RemoteException?{ ????????super(); ????} ???? ????public?void?rebind(String?name)?{? ????????try?{ ????????????Naming.rebind(name,this); ????????????System.out.println("Server?is?running "); ????????}?catch(Exception?e)?{ ????????????e.printStackTrace(); ????????} ????} ????public?String?sayHello(String?name)?throws?RemoteException?{ ????????return?"Hello?"+name+"?This?is?processed?by?RMI"; ????}
}
上面的繼承 java.rmi.Remote 和可序列化的感覺是一樣的;在網絡中轉成流格式后,便與傳輸。
3. jdk1.5編譯和 rmic 編譯后 ?1)javac ..... ?2)rmic? rmic org.rmi.test.Hello(后得到 Hello_Stub.class)
4.服務器開啟: 在項目根目錄下加 rmi.policy
grant?{ ??Permission?java.security.AllPermission?"","connect,listen,accept"; }; 后運行:
package?org.rmi.test;
import?java.rmi.RMISecurityManager;
public?class?Start?{
????public?static?void?main(String[]?args)?{ ????????try?{ ????????????System.setSecurityManager(new?RMISecurityManager()); ??????????? //這里還不太明白 ????????????new?Hello().rebind("RMI/Mclaren"); ????????}?catch(Exception?e)?{ ????????????e.printStackTrace(); ????????} ????}
}
5.開端口: rmiregistry 1099? (開 端口) 客戶端:(另臺電腦也可以了)
import?java.rmi.Naming; import?org.rmi.test.IHello;
public?final?class?Client?{ ????public?static?void?main(String[]?args)?{ ????????try?{ ????????????IHello?hello?=?(IHello)Naming.lookup("rmi://localhost:1099/RMI/Mclaren"); ????????????System.out.println(hello.sayHello("Mclaren")); ????????}?catch(Exception?e)?{ ????????????e.printStackTrace(); ????????} ????}
}
結果是: Hello Mclaren This is processed by RMI
本文是本人實際開發中遇到,特留文記錄。在次我花了3天的時間解決,這個問題還是點難度的。 所用到知識點: 一般jdk |-私有屬性反射 |-序列化 |-正則表達使用 |-多線程使用 |-dom4j的xml讀取 |+hibernate ?? |-攔截器 ?? |-一個Session工廠同時連接不同數據庫(本文關鍵) ?? |-oracle Blob 存取
等........
需求功能介紹: ?為性能考慮,單一服務器改成集群(每太服務器數據允許在一定時間內保持相步),給出的修改時間短,不過代碼持久層比較統一(hibernate 感謝天還好是她! )。網絡連接不穩定(鐵路內網!)。
完成后效果: ? 當網絡連接成功時,多數據庫的同步。 ?? 當網絡連接失敗時,本地應用程序運用hibernate攔截器攔截正操作對象并記錄下操作動作,序列化到本地時局庫 z_jcyy_tb 表中。表數據屬性為:id,inputdate(記錄時間),object(序列對象),action(操作動作)。并安一定時間測試連接。如果成功,讀取 z_jcyy_tb 表中數據 反序列化 再同步到 其他數據庫中。
代碼說明: 1.新Session 建立 ?? hibernate.cfg.xml 在文件<session-factory>中添加
??? <property?name="connection.url_b">jdbc:oracle:thin:@192.168.1.114:1521:JCYY</property>
????<property?name="connection.username_b">jcyy</property> ????<property?name="connection.password_b">jcyy</property>
?? TBDao -> OpenSession()
????private?static?String?url_b?=?null?; ????private?static?String?use_b?=?null?; ????private?static?String?pass_b?=?null?; ????private?static?String?dirver_b?=?null?; ????static?{try?{ ??????? //取得hibernate.cfg.xml邏輯路徑,和原來程序關聯上? ????????Field?field???=???SessionManager.class.getDeclaredField("CONFIG_FILE_LOCATION"); ????????field.setAccessible(?true?); ????????String?path??=??(String)?field.get(SessionManager.?class?);
??????? //通過 dom4j 加載 配置文件? ? ????????Document?docT?=?new?SAXReader().read(?TBDao.class.getResourceAsStream(path)?);
??? ??? //正則+xpath讀取 在hbn文件中加入的<property?name="..._b"> 的屬性 ????????String?xpath?=?"/hibernate-configuration/session-factory/property[@name='XPATH_I']"?; ????????Pattern?p?=?Pattern.compile("(XPATH_I)"); ????????Matcher?ma?=?p.matcher(xpath); ????????url_b??=?DocumentHelper.createXPath(?ma.replaceAll("connection.url_b")?).selectSingleNode(docT).getText(); ????????use_b?=?DocumentHelper.createXPath(?ma.replaceAll("connection.username_b")).selectSingleNode(docT).getText(); ????????pass_b?=?DocumentHelper.createXPath(?ma.replaceAll("connection.password_b")).selectSingleNode(docT).getText(); ????????dirver_b?=?DocumentHelper.createXPath(?ma.replaceAll("connection.driver_class")).selectSingleNode(docT).getText(); ????}?catch?(Exception?e)?{e.printStackTrace();}} ??? ??? //利用hbn的SessionFactory得到 openSession(Connection); 打開異地數據庫連接。 ??? //利用私有反射得到 加載完成的SessionFactory ????public?Session?openSessionb(){ ????????try?{ ????????????Class.forName(dirver_b); ????????????Connection?conn?=??DriverManager.getConnection(url_b,use_b,pass_b); ???????????? ????????????Field[]?fields???=???SessionManager.class.getDeclaredFields(); ????????????Field?field?=?null?; ????????????for(int?i=0;i<fields.length;i++){ ????????????????if(?SessionFactory.class.equals(??fields[i].getType()?)??) ????????????????????field?=?fields[i]; ????????????} ????????????field.setAccessible(true); ????????????SessionFactory?sessionFactory??=??(SessionFactory)?field.get(SessionManager.class?); ????????????return?sessionFactory.openSession(conn); ????????}?catch?(Exception?e)?{ ????????????System.out.println("--沒有連接到總服務(openSessionb)--"); ????????????return?null?; ????????} ????}
? 2.異地數據同步失敗后動作? TBDao->save() 凍結狀態到數據庫
????public?void?save(Object?obj,String?action)?{ ????????Session?session?=?null?; ????????try?{ ????????????session?=?SessionManager.currentSession(null,null); ????????????Transaction?tr?=?session.beginTransaction(); ????????????ZJcyyTb?zj?=?new?ZJcyyTb(); ????????????zj.setAction(action); ????????????zj.setInputdate(new?Date()); ????????????session.save(zj); ????????????session.flush(); ????????????session.refresh(zj,LockMode.UPGRADE); ??????????? //oracle Blob數據持久 請參考-->序列化和反序列化對象到 數據庫??????????? zj.setObject(?new?ObjectConvert().ObjectToBlob(obj)?); ????????????tr.commit(); ????????}?catch?(Exception?e)?{ ????????????e.printStackTrace(); ????????}finally{ ????????????if(session!=null&&?session.isOpen()?)session.close(); ????????}
????}
3,失敗后又成功連接后 (線程實現) TBDao->action()
????public?int?isSql(){ ????????int?is_count?=?0?; ????????Session?session?=?null?; ????????try?{ ??????????? //得到本地Session 查看是否有連接失敗后序列動作被保存 ????????????session?=?SessionManager.currentSession(null,null); ????????????Transaction?tr?=??session.beginTransaction(); ????????????Connection?conn?=?session.connection(); ????????????Statement?stat?=?conn.createStatement(); ????????????ResultSet?rs?=?stat.executeQuery("select?count(*)?from?z_jcyy_tb"); ????????????rs.next(); ????????????is_count?=?rs.getInt(1); ????????????tr.commit(); ????????}?catch?(Exception?e)?{ ????????????e.printStackTrace(); ????????}finally{ ????????????if(session!=null&&?session.isOpen()?)session.close(); ????????} ????????return?is_count?; ????}
????public?boolean?action(){ ????????int?isSql?=?0?; ????????ObjectConvert?oc?=?new?ObjectConvert(); ????????Session?session?=?null?; ????????Session?session_b?=?null?; ???????? ????????try?{ ??????????? //有失敗連接動作后嘗試 遠程數據庫? ????????????if(?(isSql=isSql())>0?){ ????????????????session?=?SessionManager.currentSession(null,null); ??????????????? //遠程數據庫連接? ??????????????? //如果成功連接:z_jcyy_tb表中數據同步到其他數據庫中 ????????????????session_b?=?openSessionb(); ????????????????if(session_b!=null){ ????????????????????Transaction?tr_b?=?session_b.beginTransaction(); ????????????????????Transaction?tr?=?session.beginTransaction(); ???????????????????? ????????????????????Query?qu?=?session.createQuery("?from?ZJcyyTb?t?order?by?t.inputdate"); ????????????????????for(int?i=0;i<=isSql/10;i++){ ????????????????????????qu.setFirstResult(i*10); ????????????????????????qu.setMaxResults(10); ????????????????????????List?list?=?qu.list();???????????????? ????????????????????????for(Iterator?it=list.iterator();it.hasNext();){ ????????????????????????????ZJcyyTb?tb?=?(ZJcyyTb)it.next(); ????????????????????????????Object?obj?=?null?; ????????????????????????????obj?=?oc.BlobToObject(tb.getObject(),obj); ????????????????????????????if(obj!=null){ ????????????????????????????????String?action?=?tb.getAction(); ????????????????????????????????if(action.equals(?TBDao.DELETE?)){ ????????????????????????????????????session_b.delete(obj); ????????????????????????????????} ????????????????????????????????if(action.equals(?TBDao.INSERT?)){ ????????????????????????????????????session_b.save(obj); ????????????????????????????????} ????????????????????????????????if(action.equals(?TBDao.UPDATE?)){ ????????????????????????????????????session_b.update(obj); ????????????????????????????????} ????????????????????????????} ????????????????????????????session.delete(tb); ????????????????????????????tr.commit(); ????????????????????????} ????????????????????} ????????????????????tr_b.commit(); ????????????????} ????????????}????return?true?; ????????}?catch?(Exception?e)?{ ????????????System.out.println("--沒有連接到總服務(action)--"); ????????}finally{ ????????????if(session_b!=null&&session_b.isOpen())session_b.close(); ????????????if(session!=null&&?session.isOpen()?)session.close(); ????????????SessionManager.closeSession();???? ????????} ????????return?false?; ????} 4.hbn 攔截器 ->Interceptor
package?com.jjm.hibernate;
import?java.io.File; import?java.io.FileInputStream; import?java.io.InputStream; import?java.io.Serializable; import?java.lang.reflect.Field; import?java.sql.Connection; import?java.sql.DriverManager; import?java.util.HashSet; import?java.util.Iterator; import?java.util.Set;
import?org.dom4j.Document; import?org.dom4j.DocumentHelper; import?org.dom4j.XPath; import?org.dom4j.io.SAXReader; import?org.hibernate.CallbackException; import?org.hibernate.EntityMode; import?org.hibernate.Hibernate; import?org.hibernate.HibernateException; import?org.hibernate.Interceptor; import?org.hibernate.Session; import?org.hibernate.SessionFactory; import?org.hibernate.Transaction; import?org.hibernate.cfg.Configuration; import?org.hibernate.type.Type;
import?com.jjm.rlzy.dao.TBDao;
public?class?TestInterceptor?implements?Interceptor,Serializable{ ???? ????static?private?boolean?isConn_b?=?false?; ????static?private?TBDao?tb?=?new?TBDao(); ??? //線程 一分鐘 檢測連接失敗 同步 ????static{ ????????new?Thread(new?Runnable(){ ????????????public?void?run()?{ ????????????????while(true){ ????????????????????isConn_b?=?tb.action(); ????????????????????try?{ ????????????????????????Thread.sleep(60*1000); ????????????????????}?catch?(InterruptedException?e)?{e.printStackTrace();} ????????????????} ????????????} ????????}).start(); ????}
????public?boolean?onFlushDirty(Object?entity,?Serializable?id,?Object[]?currentState,?Object[]?previousState,?String[]?propertyNames,?Type[]?types)?throws?CallbackException?{ ????????Session?session?=?null?; ????????try?{ ????????????if(isConn_b){ ????????????????session?=??tb.openSessionb(); ????????????????Transaction?tr?=?session.beginTransaction(); ????????????????session.update(entity); ????????????????tr.commit(); ????????????}else{ ????????????????tb.save(entity,TBDao.UPDATE); ????????????} ????????}?catch?(Exception?e)?{ ????????????e.printStackTrace()?; ????????????tb.save(entity,TBDao.UPDATE); ????????????isConn_b?=?false?; ????????}finally{ ????????????if(session!=null)session.close(); // 攔截器中 絕對不能有這句 ->? SessionManager.closeSession(); ????????} ????????return?false; ????}
????public?boolean?onSave(Object?entity,?Serializable?id,?Object[]?state,?String[]?propertyNames,?Type[]?types)?throws?CallbackException?{ ????????Session?session?=?null?; ????????try?{ ????????????if(isConn_b){ ????????????????session?=??tb.openSessionb(); ????????????????Transaction?tr?=?session.beginTransaction(); ????????????????session.save(entity); ????????????????tr.commit(); ????????????}else{ ????????????????tb.save(entity,TBDao.INSERT); ????????????} ????????}?catch?(Exception?e)?{ ????????????e.printStackTrace()?; ????????????tb.save(entity,TBDao.INSERT); ????????????isConn_b?=?false?; ????????}finally{ ????????????if(session!=null)session.close(); ????????} ????????return?false; ????}
????public?void?onDelete(Object?entity,?Serializable?id,?Object[]?state,?String[]?propertyNames,?Type[]?types)?throws?CallbackException?{ ????????Session?session?=?null?; ????????try?{ ????????????if(isConn_b){ ????????????????session?=??tb.openSessionb(); ????????????????Transaction?tr?=?session.beginTransaction(); ????????????????session.delete(entity); ????????????????tr.commit(); ????????????}else{ ????????????????tb.save(entity,TBDao.DELETE); ????????????} ????????}?catch?(Exception?e)?{ ????????????e.printStackTrace()?; ????????????tb.save(entity,TBDao.DELETE); ????????????isConn_b?=?false?; ????????}finally{ ????????????if(session!=null)session.close(); ????????} ????}
? ................................
}
后記: 由于一些原因代碼寫的有些簡陋,但功能實現,表達的的意思也還可以(自己有點 ‘買瓜了’哈哈!)。我寫出來的目的希望大家能共同進步,這等大家拍磚了 :)
???? ???
????
/*
?????*?將對象轉化成java.sql.Blob? ?????*?要求?對象是序列化的 ?????
*/
????
public
?java.sql.Blob?ObjectToBlob(Object?obj)?
throws
?IOException{ ????????
try
?{ ????????????ByteArrayOutputStream?out?
=
?
new
?ByteArrayOutputStream(); ????????????ObjectOutputStream?outputStream?
=
?
new
?ObjectOutputStream(out); ????????????outputStream.writeObject(obj); ????????????
byte
[]?bytes?
=
?out.toByteArray(); ????????????outputStream.close(); ????????????
return
?Hibernate.createBlob(bytes); ????????}?
catch
?(Exception?e)?{ ????????????
//
?TODO:?handle?exception
????????????System.out.println(
"
ObjectToBlob
"
); ????????????
return
?
null
; ????????}???????? ????} ???? ???? ????
/*
?????*?將java.sql.Blob?轉化成?對象?相應對象 ?????*?要求?對象是序列化的 ?????
*/
???? ????
public
?Object?BlobToObject(java.sql.Blob?desblob,Object?obj)?
throws
?IOException{ ????????
try
?{ ????????????ObjectInputStream?in?
=
?
new
?ObjectInputStream(desblob.getBinaryStream()); ????????????obj?
=
??in.readObject(); ????????????in.close();???? ????????????
return
?obj; ????????}?
catch
?(Exception?e)?{ ????????????
//
?TODO:?handle?exception
????????????System.out.println(
"
BlobToObject
"
); ????????????e.printStackTrace(); ????????????
return
?
null
; ????????}???????? ????}???? ???? ????
攔截器
package
?hbn.test.supper.Interceptor;
import
?java.io.Serializable;
import
?java.util.HashSet;
import
?java.util.Iterator;
import
?java.util.Set;
import
?org.hibernate.CallbackException;
import
?org.hibernate.EntityMode;
import
?org.hibernate.Interceptor;
import
?org.hibernate.Transaction;
import
?org.hibernate.type.Type;
public
?
class
?TestInterceptor?
implements
?Interceptor,Serializable{
????
private
?Set?inserts?
=
?
new
?HashSet(); ????
private
?Set?updates?
=
?
new
?HashSet(); ???? ?? ?
//
Session初化一個持久對象 如果這方法中改變了對象屬性就返回true 否則null
????
public
?
boolean
?onLoad(Object?entity,?Serializable?id,?Object[]?state,?String[]?propertyNames,?Type[]?types)?
throws
?CallbackException?{ ????
???
return
?
false
; ????}
??? //
Session flush()中檢查到臟數據是調用 如:tr.commit() ....
????
public
?
boolean
?onFlushDirty(Object?entity,?Serializable?id,?Object[]?currentState,?Object[]?previousState,?String[]?propertyNames,?Type[]?types)?
throws
?CallbackException?{ ????????updates.add(entity); ????????
return
?
false
; ????} ???
//
Session Save() 當修改了對象屬性返回true
????
public
?
boolean
?onSave(Object?entity,?Serializable?id,?Object[]?state,?String[]?propertyNames,?Type[]?types)?
throws
?CallbackException?{ ???????? ????????inserts.add(entity); ????????
return
?
false
; ????} ????
//
delete
????
public
?
void
?onDelete(Object?entity,?Serializable?id,?Object[]?state,?String[]?propertyNames,?Type[]?types)?
throws
?CallbackException?{
????}
?
?? //flush() 之前調用
????
public
?
void
?preFlush(Iterator?entities)?
throws
?CallbackException?{
????} ????
//
flush() 執行SQL語句之后調用
????
public
?
void
?postFlush(Iterator?entities)?
throws
?CallbackException?{ ???????? ????????
try
?{ ????????????
for
(Iterator?it?
=
?updates.iterator();it.hasNext();){ ????????????????System.out.println(
"
update=
"
+
?it.next()?);???? ????????????} ????????????
for
(Iterator?it?
=
?inserts.iterator();it.hasNext();){ ????????????????System.out.println(
"
insert
"
+
?it.next()?);???? ????????????} ???????????? ????????}?
catch
?(Exception?e)?{ ????????????e.printStackTrace(); ????????} ???????? ????}
????
public
?Boolean?isTransient(Object?entity)?{ ????????
//
?TODO?Auto-generated?method?stub
????????
return
?
null
; ????}
?
? //決定Session中那些對象是臟數據 如果null Session使用默認處理臟數據
????
public
?
int
[]?findDirty(Object?entity,?Serializable?id,?Object[]?currentState,?Object[]?previousState,?String[]?propertyNames,?Type[]?types)?{
????????
return
?
null
; ????}
????
// 當Session構造實體類對象前調用
????
public
?Object?instantiate(String?entityName,?EntityMode?entityMode,?Serializable?id)?
throws
?CallbackException?{
????????
return
?
null
; ????}
????
public
?String?getEntityName(Object?object)?
throws
?CallbackException?{ ????????
//
?TODO?Auto-generated?method?stub
????????
return
?
null
; ????}
????
public
?Object?getEntity(String?entityName,?Serializable?id)?
throws
?CallbackException?{ ????????
//
?TODO?Auto-generated?method?stub
????????
return
?
null
; ????}
????
public
?
void
?afterTransactionBegin(Transaction?tx)?{ ????????
//
?TODO?Auto-generated?method?stub
???????? ????}
????
public
?
void
?beforeTransactionCompletion(Transaction?tx)?{ ????????
//
?TODO?Auto-generated?method?stub
???????? ????}
????
public
?
void
?afterTransactionCompletion(Transaction?tx)?{ ????????
//
?TODO?Auto-generated?method?stub
???????? ????}
}
測試
package
?hbn.test.supper.Interceptor;
import
?java.lang.reflect.Field;
import
?org.hibernate.Session;
import
?org.hibernate.SessionFactory;
import
?org.hibernate.Transaction;
import
?hbn.HibernateSessionFactory;
import
?hbn.bean.T2oo;
import
?junit.framework.TestCase;
public
?
class
?TestIC?
extends
?TestCase?{ ????
private
?SessionFactory?sessionFactory; ????
protected
?
void
?setUp()?
throws
?Exception?{ ????????
super
.setUp(); ????????
//
利用java反射得到?HibernateSessionFactory?-> ????????
//
private??static?org.hibernate.SessionFactory?sessionFactory; ????????
//
要模擬?并發?要?HibernateSessionFactory?得出的?有?threadLocal?不行?
????????HibernateSessionFactory.currentSession(); ????????HibernateSessionFactory.closeSession(); ????????Field?field?
=
?HibernateSessionFactory.
class
.getDeclaredField(
"
sessionFactory
"
); ????????field.setAccessible(
true
); ????????sessionFactory?
=
?(SessionFactory)?field.get(HibernateSessionFactory.
class
); ????} ???? ????
public
?
void
?testInc()?
throws
?Exception?{ ????????TestInterceptor?intx?
=
?
new
?TestInterceptor(); ????????
//
加載攔截器
????????Session?session?
=
?sessionFactory.openSession(intx); ???????? ????????Transaction?tr?
=
?session.beginTransaction(); ????????T2oo?t2?
=
?
new
?T2oo(
23
); ????????session.save(t2); ????????t2.setAvg(
new
?Integer(
99
)); ????????tr.commit(); ????} }
結果 Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?) Hibernate: update t2oo set version=?, avg=?, aid=? where id=? and version=? //攔截到的 update=hbn.bean.T2oo@277 inserthbn.bean.T2oo@277
test.xls 中內容 -> <?xml?version="1.0"?> <Workbook?xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet?ss:Name="xls1">
?<Table> ??<Row> ???<Cell><Data?ss:Type="String">cell?a1</Data></Cell> ???<Cell><Data?ss:Type="String">cell?b2</Data></Cell> ??</Row> ??<Row> ???<Cell><Data?ss:Type="String">cell?a2</Data></Cell> ???<Cell><Data?ss:Type="String">cell?b3</Data></Cell> ??</Row> ?</Table> </Worksheet>
</Workbook> 展現的樣子-> cell a1 | cell b2 | cell a2 | cell b3 |
|