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>