欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-12 16:15:06
...

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>