大字段共分两种,一是clob,即长文本。通常用来存储超过一定数量的(如4000)的字符,一是blob,即二进制字节数据,通常就是用户提交的附件
这里假定ssh+mysql的开发环境已配置完成。通过设计一个用户管理程序来举例说明针对mysql的大字段
处理方法
一、数据库字段定义
CREATE TABLE `users` (
`enable` int(11) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`account` varchar(255) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`resume` text,
`photo` blob,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8
上面的resume字段用来存储长文本,类型定义为text,photo字段用来存储附件,类型定义为blob
二、POJO配置
User.java:
import java.sql.Blob;
import java.sql.Clob;
@Entity
@Table(name="users")
public class User {
private Integer id;
private String account;
private String password;
private Integer enable;
private String resume; //定义为string,对应数据库中resume(text)字段
private Blob photo; //定义为blob类型,对应数据库中photo(blob)字段
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getEnable() {
return enable;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public Blob getResume() {
return resume;
}
public void setResume(Blob resume) {
this.resume = resume;
}
public void setEnable(Integer enable) {
this.enable = enable;
}
}
三、配置
struts的action
dao和service层没有什么特别的。也不需要特别处理,关键在struts 的action.
a 要配置附件接收属性,如:
private File file;
private String fileFileName;
private String fileContentType;
b 长
文本字段由于在POJO里已配置为String,不需要特别处理
privage String resume
c 处理思路是通过
hibernate将输入流转换为clob和blob之后再作持久化
UserAction.java:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.sql.Blob;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import cn.ibeans.ssh.users.model.User;
import cn.ibeans.ssh.users.service.UserManager;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
private static final long serialVersionUID = 3345502231566725471L;
private static Logger logger = Logger.getLogger(UserAction.class);
private User user;
private UserManager userManager;
//以下三项是struts处理文件上传的约定风格
private File photo;
private String photoFileName;
private String photoContentType;
public File getPhoto() {
return photo;
}
public void setPhoto(File photo) {
this.photo = photo;
}
public String getPhotoFileName() {
return photoFileName;
}
public void setPhotoFileName(String photoFileName) {
this.photoFileName = photoFileName;
}
public String getPhotoContentType() {
return photoContentType;
}
public void setPhotoContentType(String photoContentType) {
this.photoContentType = photoContentType;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Autowired
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
/**
*
* @return
* @throws Exception
*/
public String save() throws Exception{
if(null==user) return this.INPUT;
logger.debug("开始日志^");
//以用户提交到服务器端的文件实例为实参构造一个输入流,支持对二进制数据的两种存储方式
InputStream is = new FileInputStream(photo);
//1、第一种方式,将二进制文件以blob的方式存储到数据库
//将输入流转换为hibernate能识别的blob型数据对象
user.setPhoto(Hibernate.createBlob(is));
userManager.addUser(user);
//2、第二种方式,将二进制文件以文件方式存储到服务器硬盘
/*
//取得附件在服务器上的存储路径
String root = ServletActionContext.getServletContext().getRealPath("/upload");
File f1 = new File(root,photoFileName);//构造一个存储到指定路径的空文件
//File f2 = new File("D:\\lvlf\\apps\\webapps\\mavenssh\\upload\\note1.txt");
//以空文件为实参构造一个输出流,用来向硬盘上输出文件
OutputStream os = new FileOutputStream(f1);
byte[] bufer = new byte[400];
int len =0;
//循环将输入流的字节数据读入到临时字节数组中
while((len =is.read(bufer))>0){
logger.debug("读入的字节总数为"+len);
//将临时字节数组中的数据定入到输出流中,由于输出流是用指定路径的空文件构造的,
//当输出流关闭时,所有数据都会写到这个空文件中去,实现了用户将客户端文件上传到服务端的功能
os.write(bufer, 0, len);
}
is.close();
os.close();
*/
return this.SUCCESS;
}
public String list() throws Exception{
logger.debug("开始查询列表……");
List<User> users = userManager.findByHql("from User user", null);
logger.debug("用户数为:"+users.size());
return this.SUCCESS;
}
}
以上需要注意的是,最好不要同时将二进制文件既存入数据库又以文件的形式保存在硬盘上,Hibernate.createBlob()会将所有二进制字节数据从输入流中全部cut掉,不做保留
四、页面配置
页面上的表单也要也action对应上
user-input.jsp:
<s:form action="user_save" method="POST" enctype="multipart/form-data">
<s:textfield key="user.account"/>
<s:password key="user.password" />
<s:textarea key="user.resume" cssStyle="width:100%"></s:textarea>
<s:file key="photo"></s:file>
<s:submit/>
</s:form>