关于在Hibernate、Struts2中使用Clob数据类型
2015-04-14 11:07
435 查看
关于在Hibernate、Struts2中使用Clob数据类型
情景假设:你需要存储一篇文档,假设文档的属性有四个,分别为:id(作为Hibernate主键)、title(标题)、content(内容)、publishTime(发布时间),当然,在不考虑复杂的情景下(比方说你想要记录文档的状态-发布或者草稿、版本号等等),这四个属性足够了。我们的焦点不是id、title或者publishTime,而是content。这里应该有以下的疑问:
·content应该使用什么样的数据库类型
·content应该使用什么样的Java类型
首先,先解决使用什么样的数据库类型。文档中存储的都是字符串(当然,附件这种二进制数据一般是存储在其他表格中的),那么假设t_document为文档表,其中的content列使用的肯定就是字符串数据类型了,再次假定使用的数据库是mysql,在mysql数据库中,varchar类型与char类型都是字符串。varchar类型长度是21000多,或许你以为这个数值很大了,足够满足大部分的文档内容要求了,但是在这里我告诉你,实际应用中往往是从一些office文档中直接拷贝一段文字然后放到我们的html编辑器,之后就提交到数据库的。一个包含了1000个字符左右的word文档,拷贝到html编辑器之后,其长度可能增长了一倍都不止。所以,2000多个字符的word文档,极可能拷贝到html编辑器后包含了20000个字符以上,这时候,如果你使用varchar作为数据库类型,那么在Java程序运行时,就要报MysqlSqlException了,因为存储的数据过长了,数据库不能进行处理(varchar数据类型是这样,而char数据类型则会进行剪裁,实际应用中,varchar类型用得居多,尤其是长字符串)。上述问题要怎么解决呢?在mysql里面,针对大文本,有三个数据类型(text、mediumtext、longtext),这三个大文本数据类型,能够存储几十万个字符,这足够满足我们的项目需求了。
其次,解决使用什么样的java类型。java的字符串,虽说不见得有长度限制,但是,针对数据库的大文本类型,hibernate却是提倡使用Clob(java.mysql.Clob)的,并且hibernate为Clob提供了实现ClobImpl(Clob只是一个接口,不能被直接使用)。这个实现给我们提供了一个ClobImpl(String str)的构造器,这意味着你可以使用你最熟悉的String来构造ClobImpl。此外,在将ClobImpl转换成为String的时候,也很方便,ClobImpl#getSubString(int pos, int len),参数pos是起始位置,从1开始,len是读取的串的长度。
Hibernate的大文本数据类型解决掉了,但是在Web层,传递的数据都是String,我们会有需求,将String在Web层转换成为Clob对象,并且在Service层回传对象给Web层时,将Clob转换成为字符串。在这里,Web层使用的MVC框架是Struts2,有两种解决方式,第一,在传递参数的时候,不使用领域模型,而是使用零散的参数,比如需要content,就在Action中声明String content域,而不是声明一个Document document域,在传递给Service层之前,把content通过手工代码转换成为一个Clob对象。另外一种方式就是,结合Struts2的Converter,这里推荐使用Struts2TypeConverter,在Action中声明Clob content域,让Strut2的转换功能帮助我们把String转换成为Clob,在提交给Service层处理。
附上手工转换Clob代码
关于Service层的依赖代码省略…
附上Struts2相关转换器代码
之后配置一个全局的xwork-properties文件,放置在classpath的根下
情景假设:你需要存储一篇文档,假设文档的属性有四个,分别为:id(作为Hibernate主键)、title(标题)、content(内容)、publishTime(发布时间),当然,在不考虑复杂的情景下(比方说你想要记录文档的状态-发布或者草稿、版本号等等),这四个属性足够了。我们的焦点不是id、title或者publishTime,而是content。这里应该有以下的疑问:
·content应该使用什么样的数据库类型
·content应该使用什么样的Java类型
首先,先解决使用什么样的数据库类型。文档中存储的都是字符串(当然,附件这种二进制数据一般是存储在其他表格中的),那么假设t_document为文档表,其中的content列使用的肯定就是字符串数据类型了,再次假定使用的数据库是mysql,在mysql数据库中,varchar类型与char类型都是字符串。varchar类型长度是21000多,或许你以为这个数值很大了,足够满足大部分的文档内容要求了,但是在这里我告诉你,实际应用中往往是从一些office文档中直接拷贝一段文字然后放到我们的html编辑器,之后就提交到数据库的。一个包含了1000个字符左右的word文档,拷贝到html编辑器之后,其长度可能增长了一倍都不止。所以,2000多个字符的word文档,极可能拷贝到html编辑器后包含了20000个字符以上,这时候,如果你使用varchar作为数据库类型,那么在Java程序运行时,就要报MysqlSqlException了,因为存储的数据过长了,数据库不能进行处理(varchar数据类型是这样,而char数据类型则会进行剪裁,实际应用中,varchar类型用得居多,尤其是长字符串)。上述问题要怎么解决呢?在mysql里面,针对大文本,有三个数据类型(text、mediumtext、longtext),这三个大文本数据类型,能够存储几十万个字符,这足够满足我们的项目需求了。
其次,解决使用什么样的java类型。java的字符串,虽说不见得有长度限制,但是,针对数据库的大文本类型,hibernate却是提倡使用Clob(java.mysql.Clob)的,并且hibernate为Clob提供了实现ClobImpl(Clob只是一个接口,不能被直接使用)。这个实现给我们提供了一个ClobImpl(String str)的构造器,这意味着你可以使用你最熟悉的String来构造ClobImpl。此外,在将ClobImpl转换成为String的时候,也很方便,ClobImpl#getSubString(int pos, int len),参数pos是起始位置,从1开始,len是读取的串的长度。
Hibernate的大文本数据类型解决掉了,但是在Web层,传递的数据都是String,我们会有需求,将String在Web层转换成为Clob对象,并且在Service层回传对象给Web层时,将Clob转换成为字符串。在这里,Web层使用的MVC框架是Struts2,有两种解决方式,第一,在传递参数的时候,不使用领域模型,而是使用零散的参数,比如需要content,就在Action中声明String content域,而不是声明一个Document document域,在传递给Service层之前,把content通过手工代码转换成为一个Clob对象。另外一种方式就是,结合Struts2的Converter,这里推荐使用Struts2TypeConverter,在Action中声明Clob content域,让Strut2的转换功能帮助我们把String转换成为Clob,在提交给Service层处理。
附上手工转换Clob代码
package com.nytech.core.web.action.admin; import java.util.Set; import org.hibernate.lob.ClobImpl; import com.nytech.core.entity.model.Document; import com.nytech.core.web.action.base.BaseJsonAction; import com.nytech.utils.model.CommonUtils; import com.nytech.utils.model.JSONConstant; /** * @author daniel * */ @SuppressWarnings("serial") public class AddDocumentAction extends BaseJsonAction { private String title; private String content; /** * @return the title */ public String getTitle() { return title; } /** * @param title the title to set */ public void setTitle(String title) { this.title = title; } /** * @return the content */ public String getContent() { return content; } /** * @param content the content to set */ public void setContent(String content) { this.content = content; } /* (non-Javadoc) * @see com.opensymphony.xwork2.ActionSupport#execute() */ @Override public String execute() throws Exception { // TODO Auto-generated method stub try { Document doc = new Document(); doc.setTitle(title); if(content != null) { doc.setContent(new ClobImpl(content)); } super.getAdminService().addDocument(doc); super.getDataMap().put(JSONConstant.JSON_STATUS, JSONConstant.JSON_STATUS_SUCCESS); } catch(Exception e) { e.printStackTrace(); super.getDataMap().put(JSONConstant.JSON_STATUS, JSONConstant.JSON_STATUS_ERROR); } return SUCCESS; } }
关于Service层的依赖代码省略…
附上Struts2相关转换器代码
package com.nytech.struts.converter; import java.sql.Clob; import java.sql.SQLException; import java.util.Map; import org.apache.struts2.util.StrutsTypeConverter; import org.hibernate.lob.ClobImpl; /** * @author daniel * */ @SuppressWarnings("rawtypes") public class ClobConverter extends StrutsTypeConverter { @Override public Object convertFromString(Map arg0, String[] arg1, Class arg2) { // TODO Auto-generated method stub Clob clob = null; clob = new ClobImpl(arg1[0]); return clob; } @Override public String convertToString(Map arg0, Object arg1) { // TODO Auto-generated method stub String str = ""; if(arg1 instanceof Clob) { Clob clob = (Clob) arg1; try { str = clob.getSubString(0, (int) clob.length()); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return str; } }
之后配置一个全局的xwork-properties文件,放置在classpath的根下
java.sql.Clob=com.nytech.struts.converter.ClobConverter
相关文章推荐
- 关于Oracle的Clob数据类型在Hibernate中的应用
- 使用 hibernate 存取大对象数据类型(clob和blob)
- 使用 hibernate 存取大对象数据类型(clob和blob)
- 使用 hibernate 存取大对象数据类型(clob和blob)
- 关于oracle blob类型、clob类型在hibernate 中如何使用注解
- 使用 hibernate 存取大对象数据类型(clob和blob)
- 使用Hibernate存取大对象数据类型(clob和blob)
- 使用 hibernate 存取大对象数据类型(clob和blob)
- Spring JDBC-使用Spring JDBC获取本地连接对象以及操作BLOB/CLOB类型数据
- [随记]在Hibernate中如何使用Blob数据类型
- hibernate对象映射Date数据类型和input datetime使用注意事项
- 关于mybatis的参数2个使用经验(类似于struts2的通配所有页面的action配置,xmlsq语句参数类型为基本类型时的快捷指定办法)
- 关于sql查询字符char类型数据的条件使用
- 关于Hive中的复杂数据类型Array,Map,Structs的一些使用案例
- 使用hibernate和mysql生成数据表时,类型为string的属性对应的数据列不能插入汉字
- 转载一篇关于Mysql 时间、日期数据类型使用的总结
- 关于C/C++中静态本地变量的使用与数据类型修饰符const
- 关于struts2使用xml拦截器(interceptor)限制文件上传(fileUpload)大小和类型的问题,道友看一看
- 使用Struts2+Hibernate(HQL)添加数据、查询数据
- 关于如何实现在整合struts2和hibernate4框架下实现many-to-one级联数据表在JSP页面中的输出