JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java Application Framework » Spring  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
己加入精華區
by caterpillar at 2006-08-14 21:05
本主題所含的標籤
無標籤
作者 Spring 對 Lob 的支援… [精華]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2006-08-14 20:29 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
如果要將 將檔案存入資料庫,我們在JDBC中可以使用CLOB與BLOB來分別針對文字檔案與二進位檔案進行儲存,Spring中可以透過JdbcTemplate來處理CLOB與BLOB。

舉個例子來說,假設您的MySQL資料庫表格如下:
1
2
3
4
5
CREATE TABLE test (
    id INT AUTO_INCREMENT PRIMARY,
    txt TEXT,
    image BLOB
);


假設我們現在分別讀進一個文字檔案與二進位檔案,並想將之儲存至資料庫中,則我們可以使用JdbcTemplate,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        final File binaryFile = new File("c:\\workspace\\wish.jpg");
        final File txtFile = new File("c:\\workspace\\test.txt");
       
        final InputStream is = new FileInputStream(binaryFile);
        final Reader reader = new FileReader(txtFile);
       
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
       
        final LobHandler lobHandler = new DefaultLobHandler();
       
        jdbcTemplate.execute("INSERT INTO test (txt, image) VALUES(?, ?)",
                     new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
                        protected void setValues(PreparedStatement pstmt, LobCreator lobCreator)
                                                           throws SQLException, DataAccessException {
                            lobCreator.setClobAsCharacterStream(pstmt, 1, reader, (int) txtFile.length());
                            lobCreator.setBlobAsBinaryStream(pstmt, 2, is, (int) binaryFile.length());
                        }
                     });
       
        reader.close();
        is.close();


JdbcTemplate中傳入了AbstractLobCreatingPreparedStatementCallback的實作,並傳入一個 LobHandler,對於MySQL(MS SQL Server或Oracle 10g),這邊使用DefaultLobHandler即可,對於Oracle 9i特定的LOB處理,我們可以使用OracleLobHandler。

如果要從資料庫中將資料讀取出來,並另存為檔案,我們可以使用以下的程式:
1
2
3
4
5
6
7
8
9
10
11
12
13
        final Writer writer = new FileWriter("c:\\workspace\\test_bak.txt");
        final OutputStream os = new FileOutputStream(new File("c:\\workspace\\wish_bak.jpg"));
       
        jdbcTemplate.query("SELECT txt,image FROM test WHERE id = ?",
                new Object[] {new Integer(1)},
                new AbstractLobStreamingResultSetExtractor() {
                    protected void streamData(ResultSet rs) throws SQLException, IOException, DataAccessException {
                        FileCopyUtils.copy(lobHandler.getClobAsCharacterStream(rs, 1), writer);
                        FileCopyUtils.copy(lobHandler.getBlobAsBinaryStream(rs, 2), os);
                    }
                 });
        writer.close();
        os.close();


reply to postreply to post
良葛格學習筆記
作者 Re:Spring 對 Lob 的支援… [Re:caterpillar]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2006-08-14 20:30 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
在使用Spring搭配Hibernate時,可以簡化對Lob型態的處理,只要在SessionFactory建構時指定LobHandler,例如:
* beans-config.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?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>com.mysql.jdbc.Driver</value> 
        </property> 
        <property name="url"> 
            <value>jdbc:mysql://localhost:3306/demo</value> 
        </property> 
        <property name="username"> 
            <value>root</value> 
        </property> 
        <property name="password"> 
            <value>123456</value> 
        </property> 
    </bean> 
    
    <bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"/>
   
    <bean id="sessionFactory" 
          class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" destroy-method="close"> 
        <property name="dataSource"> 
            <ref bean="dataSource"/> 
        </property>
        <property name="lobHandler">
             <ref bean="lobHandler"/>
        </property>
        <property name="mappingResources"> 
            <list> 
                <value>onlyfun/caterpillar/User.hbm.xml</value> 
            </list> 
        </property> 
        <property name="hibernateProperties"> 
            <props> 
                <prop key="hibernate.dialect"> 
                    org.hibernate.dialect.MySQLDialect 
                </prop> 
            </props> 
        </property> 
    </bean> 
    
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory">
            <ref bean="sessionFactory"/>
        </property>
    </bean>
</beans>


在這邊指定LobHandler時,對於MySQL、DB2、MS SQL Server、Oracle 10g,使用DefaultLobHandler即可,而對於Oracle 9i,則可以使用OracleLobHandler。

接下來的操作與一般對HibernateTemplate的操作無異,例如您的資料庫表格為:
1
2
3
4
5
CREATE TABLE user (
    id INT auto_increment PRIMARY Key,
    txt TEXT,
    image BLOB
);


Spring的ClobStringType可以將CLOB映射至String,而BlobByteArrayType可以將BLOB映射至byte[],所以我們可以設計一個User類別如下:

* User.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package onlyfun.caterpillar;
 
public class User {
    private Integer id;
    private String txt;
    private byte[] image;
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public byte[] getImage() {
        return image;
    }
    public void setImage(byte[] image) {
        this.image = image;
    }
    public String getTxt() {
        return txt;
    }
    public void setTxt(String txt) {
        this.txt = txt;
    }  
}


Use.hbm.xml沒什麼特別的:

* User.hbm.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping 
    PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
 
<hibernate-mapping> 
    <class name="onlyfun.caterpillar.User" table="user"> 
 
        <id name="id" column="id"> 
            <generator class="native"/> 
        </id> 
 
        <property name="txt" column="txt"/> 
 
        <property name="image" column="image"/> 
    </class> 
</hibernate-mapping>


以下是個簡單的儲存與讀取Lob的程式片段示範:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
        ApplicationContext context =
            new FileSystemXmlApplicationContext("beans-config.xml");
       
        InputStream is = new FileInputStream(new File("c:\\workspace\\wish.jpg"));
        byte[] b = new byte[is.available()];       
        is.read(b);
        is.close();
       
        User user = new User();
        user.setTxt("long...long...text");
        user.setImage(b);
       
        HibernateTemplate hibernateTemplate = (HibernateTemplate) context.getBean("hibernateTemplate");
        hibernateTemplate.save(user);
       
        user = (User) hibernateTemplate.execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                User user = (User) session.load(User.class, new Integer(1));
                Hibernate.initialize(user);
                return user;
            }
        });
       
        System.out.println(user.getTxt());
        b = user.getImage();
       
        OutputStream os = new FileOutputStream(new File("c:\\workspace\\wish_bak.jpg"));
        os.write(b);
        os.close();


reply to postreply to post
良葛格學習筆記
作者 Re:Spring 對 Lob 的支援… [Re:caterpillar]
YuLimin

简单就是美

版主

發文: 134
積分: 0
於 2006-09-22 15:19 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
这种方式并没有解决CLOB超过4K的问题吧?

reply to postreply to post
 当兵不后悔!后悔不当兵! 
超越黎明时空,追逐时代潮流!
人,是要靠自己的!简单就是美!
我的Java:http://www.Java2Class.net
我的Blog:http://YuLimin.JavaEye.com
作者 Re:Spring 對 Lob 的支援… [Re:caterpillar]
zxum5577





發文: 2
積分: 0
於 2006-11-06 16:31 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
驱动程序的版本正确的的话,这个方法是支持超过4K。我现在主要是不知道怎么去确定使用那个版本的驱动。一个一个试出来的......

reply to postreply to post
» JWorld@TW »  Java Application Framework » Spring

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8