Thursday, August 31, 2006

 

Generic CRUD DAO

這是參考Don't repeat the DAO!這篇文章前面一部分的note
單純運用Java 5.0 Generic、Spring、Hibernate
後面還有加入AOP的部份比較複雜
改天我再另外整理

這篇文章的程式碼
為Eclipse Project,需要的library都放好在裡面了,測試請以Unit Test執行PersonDaoTest.java


Generic CRUD DAO

Generic CRUD DAO只需要

GenericDao.java
package genericdao;

import java.io.Serializable;

public interface GenericDao<T, PK extends Serializable> {
   PK create(T newInstance);
   T read(PK id);
   void update(T transientObject);
   void delete(T persistentObject);
}
GenericDaoHibernateImpl.java
package genericdao.impl;

import genericdao.GenericDao;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.SessionFactoryUtils;

public class GenericDaoHibernateImpl<T, PK extends Serializable> implements GenericDao<T, PK> {
   private SessionFactory sessionFactory;

   private Class<T> type;

   public GenericDaoHibernateImpl(Class<T> type) {
      this.type = type;
   }

   public PK create(T o) {
      return (PK) getSession().save(o);
   }

   public T read(PK id) {
      return (T) getSession().get(type, id);
   }

   public void update(T o) {
      getSession().update(o);
   }

   public void delete(T o) {
      getSession().delete(o);
   }

   public Session getSession() {
      boolean allowCreate = true;
      return SessionFactoryUtils.getSession(sessionFactory, allowCreate);
   }

   public void setSessionFactory(SessionFactory sessionFactory) {
      this.sessionFactory = sessionFactory;
   }
}

Your DAO

使用Generic CRUD DAO來寫你自己的CRUD DAO你需要

Person.java (Your Domain Object)
package genericdaotest.domain;

import java.io.Serializable;

public class Person implements Serializable {
   private Long id;

   private String name;

   private Integer weight;

   public Person(String name, Integer weight) {
      this.name = name;
      this.weight = weight;
   }

   // Default constructor needed by Hibernate
   protected Person() {
   }

   public Long getId() {
      return id;
   }

   private void setId(Long id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   private void setName(String name) {
      this.name = name;
   }

   public Integer getWeight() {
      return weight;
   }

   public void setWeight(Integer weight) {
      this.weight = weight;
   }
}
Person.hbm.xml (Your Domain Object's Hibernate Mapping)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="genericdaotest.domain">
   <class name="Person">
      <id name="id">
         <generator class="native"></generator>
      </id>
      <property name="name" update="false" />
      <property name="weight" />
   </class>
</hibernate-mapping>

Use Your DAO

使用你的DAO需要

my-test.xml (Spring Configration File)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
   <bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName">
         <value>org.hsqldb.jdbcDriver</value>
      </property>
      <property name="url">
         <value>jdbc:hsqldb:file:db/data</value>
      </property>
      <property name="username">
         <value>sa</value>
      </property>
      <property name="password">
         <value></value>
      </property>
   </bean>

   <bean id="sessionFactory"
      class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
      
      <property name="mappingResources">
         <list>
            <value>genericdaotest/domain/Person.hbm.xml</value>
         </list>
      </property>
      <property name="hibernateProperties">
         <props>
            <prop key="hibernate.dialect">
               org.hibernate.dialect.HSQLDialect
            </prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
         </props>
      </property>
      <property name="dataSource">
         <ref bean="dataSource" />
      </property>
   </bean>

   <bean id="personDao"
      class="genericdao.impl.GenericDaoHibernateImpl">
      <constructor-arg>
         <value>genericdaotest.domain.Person</value>
      </constructor-arg>
      <property name="sessionFactory">
         <ref bean="sessionFactory" />
      </property>
   </bean>
</beans>
PersonDaoTest.java (Codes That Use Your DAO)
package genericdaotest;

import genericdao.GenericDao;
import genericdaotest.domain.Person;
import junit.framework.TestCase;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;

public class PersonDaoTest extends TestCase {
   private ApplicationContext factory;

   public PersonDaoTest(String s) {
      super(s);
      factory = new ClassPathXmlApplicationContext("my-test.xml");
   }

   public void testCrud() throws Exception {
      // Create
      GenericDao personDao = (GenericDao) factory.getBean("personDao");
      Person createPerson = new Person("Mellqvist", 88);
      personDao.create(createPerson);
      assertNotNull(createPerson.getId());
      Long id = createPerson.getId();

      restartSession();

      // Read
      Person foundPerson = (Person) personDao.read(id);
      assertEquals(createPerson.getWeight(), foundPerson.getWeight());

      restartSession();

      // Update
      Integer updateWeight = 90;
      foundPerson.setWeight(updateWeight);
      personDao.update(foundPerson);
      Person updatedPerson = (Person) personDao.read(id);
      assertEquals(updateWeight, updatedPerson.getWeight());

      restartSession();

      // Delete
      personDao.delete(updatedPerson);
      restartSession();
      assertNull(personDao.read(id));
   }

   protected void setUp() throws Exception {
      openSession();
   }

   protected void tearDown() throws Exception {
      closeSession();
   }

   private void openSession() {
      SessionFactory sessionFactory = getSessionFactory();
      Session session = SessionFactoryUtils.getSession(sessionFactory, true);
      TransactionSynchronizationManager.bindResource(sessionFactory,
            new SessionHolder(session));
   }

   private void closeSession() {
      SessionFactory sessionFactory = getSessionFactory();
      SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager
            .unbindResource(sessionFactory);
      sessionHolder.getSession().flush();
      sessionHolder.getSession().close();
      SessionFactoryUtils.releaseSession(sessionHolder.getSession(),
            sessionFactory);
   }

   private void restartSession() {
      closeSession();
      openSession();
   }

   private SessionFactory getSessionFactory() {
      return (SessionFactory) factory.getBean("sessionFactory");
   }
}

Exercise

練習寫一個你自己的DAO看看吧!
還記得需要哪些檔案嗎?
你可以重用:

所以你需要: Try Try看吧!


Wednesday, August 30, 2006

 

PictoBrowser {Flash Flickr Picture Browser}

一個用flash寫的widget
可以顯示某人某個set中的照片
但沒有辦法連回flickr
上面顯示的是我「最愛 | Favorites」set中的照片


Tuesday, August 29, 2006

 

My BPEL Presentation

BPEL

之前報告的投影片
比較特別的是那兩張我看了圖解王後用Visio 2007試作的圖表
BPEL Evolution

BPM Standards
不過投影片裡面有蠻多copy來的圖
所以看看就好,不用幫我宣傳

好的圖表放在投影片中
會比較容易說明
報告時顯得簡潔有力
整個概念也會比較清楚
但前提是那圖表要夠好
一些好圖表的概念我是從Richy的網站上學來的
有興趣增強自己圖解功力可以去看看他的網站跟圖解王這本書 :)


 

Flickr Geotagging

Flickr Geotagging

Google Earth這個一眼就讓人印象深刻的web application為網路世界帶來了許多應用
而把地理資訊與照片結合比較有名的是Zooomr這個跟Flickr類似的照片網站
現在Flickr也有他自己的Geotag系統了

試用了一下
現在的問題是我在家裡用的時候
介面還有點lag

而且老實說我地理不是很好
看著地圖如果它沒有非常詳細標明的話
我根本分不清楚哪裡是松山區哪裡是信義區
鳥瞰的視角、沒有夠大的放大倍率衛星圖片
誰會知道我現在是在哪個座標上照相呢?
感覺只好大概標一下

說不定不久的將來
數位相機就會透過GPS把該相片拍照的位置紀錄在照片的EXIF裡面
這樣往後就不用自己做這種雜工啦!


Monday, August 28, 2006

 

Canon EOS 400D

Canon EOS 400D

最近的入門級DSLR市場
從Sony推出A100後就開始很熱
面對如此強勁的對手
Nikon派了D80來應戰
而Canon也推出這台350D的後代400D
很快就會出現來一場大混戰

身邊有些朋友想買DSLR
以一個Canon使用者角色的我來說
當然是要推薦一下Canon的這台新機囉
所以特地找了一些文章給大家參考 :)

Update:
Canon EOS 400D 今日(8/31) 已經正式在台發表,總代理彩虹公司公佈建議售價如下:
Canon EOS 400D 單機: NT$26,500
Canon EOS 400D Kit (搭配 EF-S 18-55mm): NT$29,900


 

大稻埕煙火節

IMG_0033

喵 IMG_0025 IMG_0026 IMG_0027 IMG_0033 IMG_0034 IMG_0035 IMG_0037 IMG_0039 IMG_0041 IMG_0046 IMG_0047 IMG_0060 IMG_0066 IMG_0074 IMG_0078 IMG_0079 IMG_0080 IMG_0081 IMG_0083 IMG_0084 IMG_0085 IMG_0087 IMG_0088 IMG_0093 IMG_0105 IMG_0107 IMG_0110 IMG_0113 IMG_0116 IMG_0122 IMG_0123 IMG_0125 IMG_0126 IMG_0152 IMG_0164 IMG_0167 IMG_0168 IMG_0171 IMG_0206


去的地方人很多
有人頭有樹頭
完全沒有辦法帶景
不過以第一次照煙火來說還算滿意啦!

去照之前我還特別研究了一下怎麼照煙火
找到幾篇蠻有用的文章:

小小筆記:
帶三腳架、快門線、黑卡
手動模式、ISO 100、B快門、F8、焦距調無限遠

Labels: , , , ,


 

2006-08-23~25 澎湖之旅

即將出發 澎湖特殊建材 畫在牆上的雙心石滬 喵 怡莉 康康 智翔 吃仙人掌冰 澎湖跨海大橋 柱狀玄武岩 千手觀音 IMG_0137 IMG_0149 智翔 IMG_0160 怡莉 鯨魚洞 IMG_0191 夜釣小管去 船長示範如何釣小管 船長示範如何釣小管 元元與他釣的小管 智翔與他釣的小管 大隻的 怡莉與她釣的第一隻小管 我釣的第一隻 我釣的第二隻 葉子與她釣的第一隻小管 怡莉與她釣的第二隻小管 喵喵與她釣到的小管 IMG_0254 怡莉 喵喵 坐在香蕉船上 IMG_0291 元元 怡莉 IMG_0332 IMG_0335 IMG_0357 脹起前的河豚 脹起後的河豚 IMG_0371 IMG_0380 IMG_0390 IMG_0419 IMG_0420 IMG_0421 IMG_0425 IMG_0442 IMG_0467 澎湖的夜市 IMG_0476 IMG_0485 IMG_0487 康康 虹橋 元元 葉子 雙心石滬 雙心石滬 雙心石滬 雙心石滬 雙心石滬 IMG_0590 仙人掌 IMG_0599 喵喵 喵喵 怡莉 IMG_0613 IMG_0616 IMG_0618 IMG_0623 IMG_0626 IMG_0628 智翔 IMG_0652 我的腳 怡莉 喵喵 IMG_0672 IMG_0673 IMG_0686 IMG_0703 喵喵 喵喵 被沙埋起來的喵喵 怡莉妳在摸哪裡阿? IMG_0861 要回家囉


多謝怡莉的邀約
讓我暑假終於有機會出去玩啦!
一起去的還有怡莉、喵喵、葉子、康康、智翔、元元、俊廷
雖然都不是同lab的同學
沒有很熟
不過還是玩得很開心

這是我第三次去澎湖了
第一次是2003-08-05~08跟謝承璋還有他一些朋友去
第二次是2004-06-23~26大學畢業旅行時後三天去的
不同的時期,與不同的人去旅行
感覺都不一樣
而這次我兼具了攝影師的角色
分享一些給大家看看 :)

即將出發
還沒有變黑前來照一張

畫在牆上的雙心石滬
許家(港仔尾)聚落是我們到澎湖後的第一站
那裡的牆上都繪有許多澎湖著名的景物
像是這個澎湖很有名的雙心石滬就很漂亮

澎湖跨海大橋

吃仙人掌冰
跨海大橋旁邊的小路上有一家聽說最有名的仙人掌冰
雖說是最有名,但我卻是第一次知道有這家店
當我們要去買來吃的時候
正好還有東森的記者在採訪
遇到一群學生人手一支在吃冰
就叫我們喊個什麼「仙人掌冰,讚!」之類感覺很俗的口號上電視
那時我只顧忙著不讓融下來仙人掌汁沾到手或衣服
根本就沒有看鏡頭就是了
這家的仙人掌冰跟我以前吃過的不太一樣
超純的,濃濃稠稠
每個人吃了幾口後
嘴唇牙齒上感覺都是鮮紅的血很恐怖

船長示範如何釣小管
第一天晚上去釣小管
我第一次去釣小管的印象超糟的
一個晚上整船好像只釣到了一隻
整個都悶了
還好上岸後他們另外有準備海鮮粥給我們吃
不過這次我們這船收穫超豐富的
釣了一兩個小時後開始整船都狂會釣
我個人就釣到了兩隻
我釣的第一隻

我釣的第二隻
有吃生小管片、小管粥、還有涼拌小管
大家都吃到撐著了還吃不完呢!

坐在香蕉船上
第二天就是水上活動
香蕉船之類可以玩得很high的那種
不過年紀越大感覺對這種活動越恐懼
又或許是因為那天天氣陰陰的關係吧

脹起前的河豚

脹起後的河豚
下午去退潮後的海岸邊看潮間帶生物
覺得這些河豚之類的生物一直被抓起來玩還蠻可憐的
過了一會而沒有很脹的時候還被抓下去灌脹
就像彎彎畫的那樣很難過

澎湖的夜市
晚上跑去所謂的澎湖夜市吃東西
說是夜市也只有四五家攤而已
我吃的蚵仔煎那個蚵仔超大的
應該有一個大拇指那麼大
還有其實澎湖的特產風茹茶就是我們所說的青草茶
兩者是一樣的

虹橋
夜晚的虹橋七彩倒映在海面上很美

雙心石滬
第三天的重頭戲就屬七美島的雙心石滬了
這石滬有好幾百年的歷史
是一種抓魚的陷阱
漲潮時魚跑進去
退潮時魚出不來
不過一般的石滬都是單心型狀
顯得這個雙心石滬特別

IMG_0628
澎湖最有名的花:天人菊

要回家囉
三天的行程結束
帶了幾盒黑糖糕、冰心糕與一袋魷魚絲回家
還有我也有變黑囉,好險沒曬傷阿