使用Hibernate 操作Clob成功小记
说明:
① 代码我已经测试成功,如下代码,只供借鉴。
② 我的开发环境是:JBuilder2006+Oracle9i
③ 文章如需引用转载,请注明出处
一、创建数据库
我使用的创建数据库的代码如下:
DROP TABLE INDUSTRYTYPE;
CREATE TABLE INDUSTRYTYPE
(
TYPEID NUMBER(10) PRIMARY KEY,
TYPENAME VARCHAR2(100) NOT NULL,
DESCRIPTION VARCHAR2(100) NOT NULL
);
DROP SEQUENCE INDUSTRYTYPE_SEQ;
CREATE SEQUENCE INDUSTRYTYPE_SEQ INCREMENT BY 1 START WITH 4000;
DROP TABLE INDUSTRY;
CREATE TABLE INDUSTRY
(
INDU_ID NUMBER(10) PRIMARY KEY,
ADMIN_ID NUMBER(10) NOT NULL,
TYPEID NUMBER(10) NOT NULL,
ISSUEDATE DATE NOT NULL,
CONTENT CLOB
);
DROP SEQUENCE INDUSTRY_SEQ;
CREATE SEQUENCE INDUSTRY_SEQ INCREMENT BY 1 START WITH 1;
二、 在Eclipse中创建POJO和映射文件
我的代码如下:
1. AbstractIndustry.java
/*
* WARNING: DO NOT EDIT THIS FILE. This is a generated file that is synchronized
* by MyEclipse Hibernate tool integration.
*
* Created Tue Feb 28 16:38:20 CST 2006 by MyEclipse Hibernate Tool.
*/
import java.io.Serializable;
/**
* A class that represents a row in the INDUSTRYTYPE table.
* You can customize the behavior of this class by editing the class, {@link Industrytype()}.
* WARNING: DO NOT EDIT THIS FILE. This is a generated file that is synchronized
* by MyEclipse Hibernate tool integration.
*/
public abstract class AbstractIndustrytype
implements Serializable
{
/** The cached hash code value for this instance. Settting to 0 triggers re-calculation. */
private int hashValue = 0;
/** The composite primary key value. */
private java.lang.Long typeid;
/** The value of the simple typename property. */
private java.lang.String typename;
/** The value of the simple description property. */
private java.lang.String description;
/**
* Simple constructor of AbstractIndustrytype instances.
*/
public AbstractIndustrytype()
{
}
/**
* Constructor of AbstractIndustrytype instances given a simple primary key.
* @param typeid
*/
public AbstractIndustrytype(java.lang.Long typeid)
{
this.setTypeid(typeid);
}
/**
* Return the simple primary key value that identifies this object.
* @return java.lang.Long
*/
public java.lang.Long getTypeid()
{
return typeid;
}
/**
* Set the simple primary key value that identifies this object.
* @param typeid
*/
public void setTypeid(java.lang.Long typeid)
{
this.hashValue = 0;
this.typeid = typeid;
}
/**
* Return the value of the TYPENAME column.
* @return java.lang.String
*/
public java.lang.String getTypename()
{
return this.typename;
}
/**
* Set the value of the TYPENAME column.
* @param typename
*/
public void setTypename(java.lang.String typename)
{
this.typename = typename;
}
/**
* Return the value of the DESCRIPTION column.
* @return java.lang.String
*/
public java.lang.String getDescription()
{
return this.description;
}
/**
* Set the value of the DESCRIPTION column.
* @param description
*/
public void setDescription(java.lang.String description)
{
this.description = description;
}
/**
* Implementation of the equals comparison on the basis of equality of the primary key values.
* @param rhs
* @return boolean
*/
public boolean equals(Object rhs)
{
if (rhs == null)
return false;
if (! (rhs instanceof Industrytype))
return false;
Industrytype that = (Industrytype) rhs;
if (this.getTypeid() == null || that.getTypeid() == null)
return false;
return (this.getTypeid().equals(that.getTypeid()));
}
/**
* Implementation of the hashCode method conforming to the Bloch pattern with
* the exception of array properties (these are very unlikely primary key types).
* @return int
*/
public int hashCode()
{
if (this.hashValue == 0)
{
int result = 17;
int typeidValue = this.getTypeid() == null ? 0 : this.getTypeid().hashCode();
result = result * 37 + typeidValue;
this.hashValue = result;
}
return this.hashValue;
}
}
2. Industrytype.java
/*
* Created Tue Feb 28 16:38:20 CST 2006 by MyEclipse Hibernate Tool.
*/
import java.io.Serializable;
import java.util.Set;
/**
* A class that represents a row in the 'INDUSTRYTYPE' table.
* This class may be customized as it is never re-generated
* after being created.
*/
public class Industrytype extends AbstractIndustrytype implements Serializable {
/**
* 存储某一种类型的所有行业交流
*/
private Set induSet;
/**
* Simple constructor of Industrytype instances.
*/
public Industrytype() {
}
/**
* Constructor of Industrytype instances given a simple primary key.
* @param typeid
*/
public Industrytype(java.lang.Long typeid) {
super(typeid);
}
public void setInduSet(Set induSet) {
this.induSet = induSet;
}
public Set getInduSet() {
return induSet;
}
/* Add customized code below */
}
3. Industrytype.hbm.xml
<?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">
<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration. -->
<!-- Created Tue Feb 28 16:38:20 CST 2006 -->
<hibernate-mapping package="com.scenechina.vr.model">
<class name="Industrytype" table="INDUSTRYTYPE">
<id name="typeid" column="TYPEID" type="java.lang.Long">
<generator class="assigned"/>
</id>
<property name="typename" column="TYPENAME" type="java.lang.String" not-null="true"/>
<property name="description" column="DESCRIPTION" type="java.lang.String" not-null="true"/>
<set name="induSet" cascade="all" inverse="true" lazy="false" table="Industry">
<key column="typeid"/>
<one-to-many class="Industry"/>
</set>
</class>
</hibernate-mapping>
4. AbstractIndustry.java
/*
* WARNING: DO NOT EDIT THIS FILE. This is a generated file that is synchronized
* by MyEclipse Hibernate tool integration.
*
* Created Tue Feb 28 16:38:20 CST 2006 by MyEclipse Hibernate Tool.
*/
import java.io.Serializable;
import java.sql.Clob;
/**
* A class that represents a row in the INDUSTRY table.
* You can customize the behavior of this class by editing the class, {@link Industry()}.
* WARNING: DO NOT EDIT THIS FILE. This is a generated file that is synchronized
* by MyEclipse Hibernate tool integration.
*/
public abstract class AbstractIndustry implements Serializable {
/** The cached hash code value for this instance. Settting to 0 triggers re-calculation. */
private int hashValue = 0;
/** The composite primary key value. */
private java.lang.Long induId;
/** The value of the simple adminId property. */
private java.lang.Long adminId;
/** The value of the simple typeid property. */
private java.lang.Long typeid;
/** The value of the simple issuedate property. */
private java.util.Date issuedate;
/** The value of the simple content property. */
private Clob content;
/** the value of the title of the industry */
private String title;
/**
* Simple constructor of AbstractIndustry instances.
*/
public AbstractIndustry() {
}
/**
* Constructor of AbstractIndustry instances given a simple primary key.
* @param induId
*/
public AbstractIndustry(java.lang.Long induId) {
this.setInduId(induId);
}
/**
* Return the simple primary key value that identifies this object.
* @return java.lang.Long
*/
public java.lang.Long getInduId() {
return induId;
}
/**
* Set the simple primary key value that identifies this object.
* @param induId
*/
public void setInduId(java.lang.Long induId) {
this.hashValue = 0;
this.induId = induId;
}
/**
* Return the value of the ADMIN_ID column.
* @return java.lang.Long
*/
public java.lang.Long getAdminId() {
return this.adminId;
}
/**
* Set the value of the ADMIN_ID column.
* @param adminId
*/
public void setAdminId(java.lang.Long adminId) {
this.adminId = adminId;
}
/**
* Return the value of the TYPEID column.
* @return java.lang.Long
*/
public java.lang.Long getTypeid() {
return this.typeid;
}
/**
* Set the value of the TYPEID column.
* @param typeid
*/
public void setTypeid(java.lang.Long typeid) {
this.typeid = typeid;
}
/**
* Return the value of the ISSUEDATE column.
* @return java.util.Date
*/
public java.util.Date getIssuedate() {
return this.issuedate;
}
/**
* Set the value of the ISSUEDATE column.
* @param issuedate
*/
public void setIssuedate(java.util.Date issuedate) {
this.issuedate = issuedate;
}public String getTitle() {
return title;
}
public Clob getContent() {
return content;
}
public void setTitle(String title) {
this.title = title;
}
public void setContent(Clob content) {
this.content = content;
}
/**
* Implementation of the equals comparison on the basis of equality of the primary key values.
* @param rhs
* @return boolean
*/
public boolean equals(Object rhs) {
if (rhs == null) {
return false;
}
if (!(rhs instanceof Industry)) {
return false;
}
Industry that = (Industry) rhs;
if (this.getInduId() == null || that.getInduId() == null) {
return false;
}
return (this.getInduId().equals(that.getInduId()));
}
/**
* Implementation of the hashCode method conforming to the Bloch pattern with
* the exception of array properties (these are very unlikely primary key types).
* @return int
*/
public int hashCode() {
if (this.hashValue == 0) {
int result = 17;
int induIdValue = this.getInduId() == null ? 0 :
this.getInduId().hashCode();
result = result * 37 + induIdValue;
this.hashValue = result;
}
return this.hashValue;
}
}
5. Industry.java
/*
* Created Tue Feb 28 16:38:20 CST 2006 by MyEclipse Hibernate Tool.
*/
import java.io.Serializable;
/**
* A class that represents a row in the 'INDUSTRY' table.
* This class may be customized as it is never re-generated
* after being created.
*/
public class Industry extends AbstractIndustry implements Serializable {
/**
* 行业交流所对应的类型
*/
public Industrytype induType;
/**
* Simple constructor of Industry instances.
*/
public Industry() {
}
/**
* Constructor of Industry instances given a simple primary key.
* @param induId
*/
public Industry(java.lang.Long induId) {
super(induId);
}
public void setInduType(Industrytype induType) {
this.induType = induType;
}
public Industrytype getInduType() {
return induType;
}
/* Add customized code below */
}
6. Industry.hbm.xml
<?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">
<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration. -->
<!-- Created Tue Feb 28 16:38:20 CST 2006 -->
<hibernate-mapping package="com.scenechina.vr.model">
<class name="Industry" table="INDUSTRY">
<id name="induId" column="INDU_ID" type="java.lang.Long">
<generator class="sequence">
<param name="sequence">INDUSTRY_SEQ</param>
</generator>
</id>
<property name="adminId" column="ADMIN_ID" type="java.lang.Long" not-null="true"/>
<property name="typeid" column="TYPEID" type="java.lang.Long" not-null="true"/>
<property name="title" column="TITLE" type="java.lang.String" not-null="true"/>
<property name="issuedate" column="ISSUEDATE" type="java.util.Date" not-null="true"/>
<property name="content" column="CONTENT" type="java.sql.Clob" update="true" insert="true" not-null="true" unique="false"/>
<many-to-one name="induType" lazy="false" column="TYPEID" entity-name="com.scenechina.vr.model.Industrytype" insert="false" update="false"/>
</class>
</hibernate-mapping>
三、 插入数据
我的实现代码如下:
// get the information of the request from the client
String sContent = new String(request.getParameter("content1").getBytes(
"iso8859_1"));
System.out.println("content : /n" + sContent);
String title = request.getParameter("title");
// initialize the industry type
String typeidStr = request.getParameter("typeid");
Long typeid = new Long(typeidStr.trim());
Industrytype induType = dao.getIndustrytypeDAO().getInstancec(typeid);
// initialize the industry
Industry indu = new Industry();
indu.setAdminId(this.adminUser.getAdminid());
indu.setContent(Hibernate.createClob(" "));
注意:" "一定要有空格,不能是一个””。””将会插入一个空串,那么会导致我们下面SerializableClob clob = (SerializableClob) indu.getContent() 取得的值为null,抛出异常。
indu.setTypeid(typeid);
indu.setInduType(induType);
indu.setIssuedate(new Date());
indu.setTitle(title);
org.hibernate.Session session = dao.getCurrentSession();
session.save(indu);
session.flush();
说明: 实现将数据存入数据库,此时可以修改,同时如果出现错误,还可以实现事务回滚。数据随写入数据库,但是当前事务还没有提交。
session.refresh(indu, LockMode.UPGRADE);
SerializableClob clob = (SerializableClob) indu.getContent();
CLOB wrapClob = (CLOB) clob.getWrappedClob();
java.io.Writer pw = wrapClob.getCharacterOutputStream();
pw.write(sContent);
pw.flush();
pw.close();
四、 显示数据
我们如何将Clob的数据显示出来呢?
我们先检索出一条记录
Industry industry = dao.getIndustryDAO().getInstance(new Long(indu_id.trim()));
然后
java.sql.Clob clob=industry.getContent();
String content="";
try{
content= clob.getSubString(1l,(int)clob.length());
}catch(Exception e){
e.printStackTrace();
}
此时的content已经是你在数据库中存储的字符串数据了,你就可以任意的显示和处理了。
五、 更新数据
Industry industry = dao.getIndustryDAO().getInstance(new Long(indu_id.
trim()));
// set the new properties to industry
ConversionUtil.request2object(request, industry);
// update the new data to database
dao.getIndustryDAO().updateObject(industry);
String sContent = request.getParameter("content1");
dao.getCurrentSession().refresh(industry,LockMode.UPGRADE);
这一句很重要,如果没有的话就会抛出异常:
发生如下错误:
ORA-22920: 未锁定含有 LOB 值的行 ORA-06512: 在"SYS.DBMS_LOB", line 708 ORA-06512: 在line 1
详细异常如下:
java.io.IOException: ORA-22920: 未锁定含有 LOB 值的行
ORA-06512: 在"SYS.DBMS_LOB", line 708
ORA-06512: 在line 1
at oracle.jdbc.dbaccess.DBError.SQLToIOException(DBError.java:618)
at oracle.jdbc.driver.OracleClobWriter.flushBuffer(OracleClobWriter.java:201)
at oracle.jdbc.driver.OracleClobWriter.flush(OracleClobWriter.java:161)
at com.scenechina.vr.action.industry.UpdateAction.execute(UpdateAction.java:39)
at com.scenechina.vr.action.DAOAction.run(DAOAction.java:28)
at org.lyj.commons.web.ControlServlet.doPost(ControlServlet.java:101)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
alve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
SerializableClob contClob = (SerializableClob) industry.getContent();
oracle.sql.CLOB clob = (oracle.sql.CLOB) contClob.getWrappedClob();
java.io.Writer pw = clob.getCharacterOutputStream();
pw.write(sContent);
pw.flush();
pw.close();
至此,关于Clob的操作已经完成。
希望对朋友们有所帮助。如果还有问题和我联系zhyiwww@163.com.