Hibernate4 解决Clob问题,网上很多都是hibernate3

hibernate4在处理clob字段上面和hibernate3有很大的不一样

今天感觉遇到了很大一个坑,但是好在解决了。

解决方案如下

创建类

package org.moon.framework.util.clob;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Map;

/**
 * Created by Administrator on 2017/1/5.
 */
public class SpringContextHolder implements ApplicationContextAware {

    private static ApplicationContext applicationContext;


    //实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextHolder.applicationContext = applicationContext;
    }


    //取得存储在静态变量中的ApplicationContext.
    public static ApplicationContext getApplicationContext() {
        checkApplicationContext();
        return applicationContext;
    }

    //从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
        checkApplicationContext();
        return (T) applicationContext.getBean(name);
    }


    //从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
    //如果有多个Bean符合Class, 取出第一个.
    @SuppressWarnings("unchecked")
    public static <T> T getBean(Class<T> clazz) {
        checkApplicationContext();
        @SuppressWarnings("rawtypes")
        Map beanMaps = applicationContext.getBeansOfType(clazz);
        if (beanMaps!=null && !beanMaps.isEmpty()) {
            return (T) beanMaps.values().iterator().next();
        } else{
            return null;
        }
    }

    private static void checkApplicationContext() {
        if (applicationContext == null) {
            throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
        }
    }

}

再创建

package org.moon.framework.util.clob;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.util.compare.EqualsHelper;
import org.hibernate.usertype.UserType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.jdbc.support.lob.OracleLobHandler;
import org.springframework.stereotype.Service;

/**
 * Created by Administrator on 2017/1/5.
 */
public class ClobTypeString implements UserType, Serializable{



    public int[] sqlTypes() {
        return new int[] { Types.CLOB };
    }


    public Class returnedClass() {
        return String.class;
    }

    public boolean equals(Object x, Object y) throws HibernateException {
        return EqualsHelper.equals(x, y);
    }


    public int hashCode(Object x) throws HibernateException {
        // TODO Auto-generated method stub
        return x.hashCode();
    }


    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
            throws HibernateException, SQLException {
        if (null != names && names.length > 0) {
            LobHandler lobHandler = getCurrentLobHandler(session);
            return lobHandler.getClobAsString(rs, names[0]);
        }
        return "";
    }


    public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
            throws HibernateException, SQLException {

        LobHandler lobHandler = getCurrentLobHandler(session);
        lobHandler.getLobCreator().setClobAsString(st, index, (String) value);

    }


    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }


    public boolean isMutable() {
        // TODO Auto-generated method stub
        return false;
    }


    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) value;
    }


    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return cached;
    }


    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return original;
    }

    private LobHandler getCurrentLobHandler(SessionImplementor session) {
        String dialect = session.getFactory().getDialect().getClass().getName();
        if (null != dialect && dialect.toLowerCase().contains("oracle")) {
            return SpringContextHolder.getBean("oracleLobHandler");
        }
        return SpringContextHolder.getBean("defaultLobHandler");
    }
}

    applicationContext.xml 中加入

<!--处理clob类型问题-->
<bean id="nativeJdbcExtractor" lazy-init="true"
     class="org.springframework.jdbc.support.nativejdbc.C3P0NativeJdbcExtractor" />
<bean id="oracleLobHandler" name="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler"
     lazy-init="true">
   <property name="nativeJdbcExtractor">
      <ref bean="nativeJdbcExtractor" />
   </property>
</bean>
<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"
     lazy-init="true">
</bean>

<bean class="org.moon.framework.util.clob.SpringContextHolder"></bean>

<!--end 处理clob类型问题-->

    因为使用的是alibab的druid数据连接池,还要引用一个jar

<dependency>
  <groupId>c3p0</groupId>
  <artifactId>c3p0</artifactId>
  <version>0.9.1.2</version>
</dependency>

   hbm配置

<?xml version="1.0"?>
<!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/Hibernate Mapping DTD 4.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.sofn.cms.beans.Article" table="CMS_ARTICLE">
        <id name="pk_article" type="string" column="pk_article">
            <generator class="org.moon.framework.util.sys.HibernateOIDGenerator"/>
        </id>
        <version name="ts" column="ts" type="timestamp"></version>
        <property name="articletitle" type="string" column="articletitle"/>
        <property name="pk_articletype" type="string" column="pk_articletype"/>
        <property name="articleauthor" type="string" column="articleauthor"/>
        <property name="articleimg" type="string" column="articleimg"/>
        <property name="articleorders" type="big_decimal" column="articleorders"/>
        <property name="articlestatus" type="string" column="articlestatus"/>
        <property name="articleinfo" type="org.moon.framework.util.clob.ClobTypeString" column="articleinfo"/>
        <property name="datastatus" type="string" column="datastatus"/>
    </class>
</hibernate-mapping>

   java bean对象

package com.sofn.cms.beans;

import org.moon.framework.beans.pub.AbstractValueObject;

import java.math.BigDecimal;
import java.sql.Clob;
import java.util.Date;
import java.sql.Blob;

/**
 * 文章信息模型对象
* @author moon.l
 *
 */
@SuppressWarnings("serial")
public class Article extends AbstractValueObject {


    /*
    * 主键    */
private String pk_article;//主键
/*
    * 对应字段    */
private String articletitle; //文章标题
private String pk_articletype; //文章类型
private String articleauthor; //文章作者
private String articleimg; //文章插图
private BigDecimal articleorders; //文章排序
private String articlestatus; //文章状态
private String articleinfo; //文章内容
private String datastatus; //数据状态
/*
    * 主键    */
public String getPrimaryKey() {
        return pk_article;
    }

    public void setPrimaryKey(String key) {
        this.pk_article = key;
    }

    public String getPk_article(){
        return pk_article;
    }
    //pk_article set
public void setPk_article(String pk_article){
        this.pk_article = pk_article;
    }

    /*
    *其余字段    */
    //文章标题 get
public String getArticletitle(){
        return articletitle;
    }
    //文章标题 set
public void setArticletitle(String articletitle){
        this.articletitle = articletitle;
    }
    //文章类型 get
public String getPk_articletype(){
        return pk_articletype;
    }
    //文章类型 set
public void setPk_articletype(String pk_articletype){
        this.pk_articletype = pk_articletype;
    }
    //文章作者 get
public String getArticleauthor(){
        return articleauthor;
    }
    //文章作者 set
public void setArticleauthor(String articleauthor){
        this.articleauthor = articleauthor;
    }
    //文章插图 get
public String getArticleimg(){
        return articleimg;
    }
    //文章插图 set
public void setArticleimg(String articleimg){
        this.articleimg = articleimg;
    }
    //文章排序 get
public BigDecimal getArticleorders(){
        return articleorders;
    }
    //文章排序 set
public void setArticleorders(BigDecimal articleorders){
        this.articleorders = articleorders;
    }
    //文章状态 get
public String getArticlestatus(){
        return articlestatus;
    }
    //文章状态 set
public void setArticlestatus(String articlestatus){
        this.articlestatus = articlestatus;
    }
    //文章内容 get
public String  getArticleinfo(){
        return articleinfo;
    }
    //文章内容 set
public void setArticleinfo(String articleinfo){
        this.articleinfo = articleinfo;
    }
    //数据状态 get
public String getDatastatus(){
        return datastatus;
    }
    //数据状态 set
public void setDatastatus(String datastatus){
        this.datastatus = datastatus;
    }
}

   对应字段类型为String

  

   再来做下测试

  TestSpring.java

package org.moon;

import com.sofn.cms.beans.Article;
import com.sofn.cms.service.ArticleService;
import freemarker.template.TemplateException;
import org.apache.log4j.Logger;
import org.hibernate.Hibernate;
import org.hibernate.LobHelper;
import org.hibernate.internal.SessionImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.moon.framework.beans.Table;
import org.moon.framework.dao.BaseDAO;
import org.moon.framework.service.BaseService;
import org.moon.framework.service.FreemarkerSrcService;
import org.moon.framework.service.codefree.CreateBean;
import org.moon.framework.service.codefree.CreateHbm;
import org.moon.framework.util.sys.DataType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobCreatorUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Clob;
import java.sql.SQLException;
import java.util.List;

/**
 * Created by Administrator on 2016/12/30.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class TestSpring {

    private static Logger logger = Logger.getLogger(TestSpring.class);

//    @Autowired
//    private ApplicationContext applicationContext;
@Autowired
private ArticleService articleService;

    @Autowired
FreemarkerSrcService freemarkerSrcService;

//    @Test
//    public void createCode() throws TemplateException, IOException, SQLException {
//        Table table = new Table();
//        table.setTableName("CMS_ARTICLE");
//        table.setBeanCode("Article");
//        table.setBeanName("文章信息");
//        table.setPackageName("com.sofn.cms");
//        table.setFilesUrl("E:/code");
//        table = freemarkerSrcService.getTableInfo(table);
//        CreateBean.createBean(table);
//        CreateHbm.createHbm(table);
//    }
@Test
public void test(){


        Article vo = new Article();
        vo.setArticletitle("测试");
        vo.setArticleinfo("啊实打实我问问的");
        articleService.save(vo);
        //
String hql = "from Article vo";
        List<Article> list = (List<Article>)articleService.query(hql);
        for (Article article : list) {
            System.out.println(article.getArticleinfo());
        }

    }


}

  运行结果

Hibernate: insert into CMS_ARTICLE (ts, articletitle, pk_articletype, articleauthor, articleimg, articleorders, articlestatus, articleinfo, datastatus, pk_article) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select article0_.pk_article as pk_artic1_1_, article0_.ts as ts2_1_, article0_.articletitle as articlet3_1_, article0_.pk_articletype as pk_artic4_1_, article0_.articleauthor as articlea5_1_, article0_.articleimg as articlei6_1_, article0_.articleorders as articleo7_1_, article0_.articlestatus as articles8_1_, article0_.articleinfo as articlei9_1_, article0_.datastatus as datasta10_1_ from CMS_ARTICLE article0_
爱出发穿
啊实打实的
啊实打实我问问的

 问题已解决

  完整:applicationContext.xml 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:tx="http://www.springframework.org/schema/tx"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xmlns:mvc="http://www.springframework.org/schema/mvc"
	   xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
	http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
	http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.3.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
	http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">


	<!--公共部分-->
	<context:component-scan base-package="org.moon.framework.dao,org.moon.framework.service" />
	<!--业务实现-->
	<context:component-scan base-package="com.sofn.cms.dao,com.sofn.cms.service" />

	<!-- 引入属性文件 -->
	<context:property-placeholder location="classpath:config.properties" />


	<!-- 配置数据源 -->
	<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
		<property name="url" value="${jdbc_url}" />
		<property name="username" value="${jdbc_username}" />
		<property name="password" value="${jdbc_password}" />

		<!-- 初始化连接大小 -->
		<property name="initialSize" value="0" />
		<!-- 连接池最大使用连接数量 -->
		<property name="maxActive" value="20" />
		<!-- 连接池最大空闲 -->
		<property name="maxIdle" value="20" />
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="0" />
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="60000" />

		<property name="poolPreparedStatements" value="true" />
		<property name="maxPoolPreparedStatementPerConnectionSize" value="33" />

		<property name="validationQuery" value="${validationQuery}" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
		<property name="testWhileIdle" value="true" />

		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="25200000" />

		<!-- 打开removeAbandoned功能 -->
		<property name="removeAbandoned" value="true" />
		<!-- 1800秒,也就是30分钟 -->
		<property name="removeAbandonedTimeout" value="1800" />
		<!-- 关闭abanded连接时输出错误日志 -->
		<property name="logAbandoned" value="true" />

		<!-- 监控数据库 -->
		<property name="filters" value="stat" />
		<!--<property name="filters" value="mergeStat" />-->
	</bean>


	<!-- 配置hibernate session工厂 -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="hibernateProperties">
			<props>
				<!--<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>-->
				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
				<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
			</props>
		</property>

		<!-- 自动扫描注解方式配置的hibernate类文件 -->
		<property name="mappingDirectoryLocations">
			<list>
				<value>classpath:hbm</value>
				<value>classpath:pubhbm</value>
			</list>
		</property>
	</bean>

	<!-- 配置事务管理器 -->
	<bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>


	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />


	<!--使用hibernateTemplate 模板-->
	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>

	<!--通用的dao查询方法-->
	<bean id="baseDAO" class="org.moon.framework.dao.impl.BaseDAOImpl">
		<property name="hibernateTemplate" ref="hibernateTemplate"></property>
		<property name="dataSource" ref="dataSource"></property>
	</bean>



	<!--处理clob类型问题-->
	<bean id="nativeJdbcExtractor" lazy-init="true"
		  class="org.springframework.jdbc.support.nativejdbc.C3P0NativeJdbcExtractor" />
	<bean id="oracleLobHandler" name="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler"
		  lazy-init="true">
		<property name="nativeJdbcExtractor">
			<ref bean="nativeJdbcExtractor" />
		</property>
	</bean>
	<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"
		  lazy-init="true">
	</bean>

	<bean class="org.moon.framework.util.clob.SpringContextHolder"></bean>

	<!--end 处理clob类型问题-->


</beans>

猜你喜欢

转载自liaoyue11.iteye.com/blog/2349053