Hibernaet更新update效率问题

在使用Hibernate作为持久化框架时,遇到更新实体效率问题,特别是当实体包含多个字段或大字段如blob、clob时。由于缓存的存在,事务中进行部分更新变得复杂,对整体性能产生影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在实际应用中,使用Hibernatez作为持久化框架,处理更新实体时,有一些潜在的效率问题。


1、场景:

实体表包含多个字段,或者字段中存在blob或clob大字段,同时,可能这些实体有缓存支持,这样在事务中难以操作和实现部分更新。

如:一个模板实体Template中:



@Entity
@Table(name = "TASKTEMPLATE")
// @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@TypeDefs({ @TypeDef(name = "blob", typeClass = BlobByteArrayType.class) })
public class TaskTemplate implements Serializable {

	private static final long serialVersionUID = 1L;

	public TaskTemplate() {
	}

	public TaskTemplate(String id, byte[] wordContent) {
		this.id = id;
		this.wordContent = wordContent;
	}

	@Id
	@Column(name = "sid", length = 32)
	@GeneratedValue(generator = "system-uuid")
	@GenericGenerator(name = "system-uuid", strategy = "uuid.hex")
	private String id;
	@Type(type = "blob")
	@Column(length = 20971520)
	private byte[] excelContent;

	// 任务包内容
	@Type(type = "blob")
	@Column(length = 20971520)
	private byte[] zipContent;

	// 模型信息
	@Type(type = "blob")
	@Column(length = 20971520)
	private byte[] xmlContent;

	@Type(type = "blob")
	@Column(length = 20971520)
	private byte[] wordContent;// Word模板

	@ManyToOne
	@Index(name = "TASK_TEMPLATE_IDX")
	@JoinColumn(name = "TASK_ID")
	private Task task;
	/**
	 * 列表展示图片(24的)
	 */
	@Type(type = "blob")
	@Column(length = 20971520)
	private byte[] images;
	/**
	 * 平铺展示图片(48的)
	 */
	@Type(type = "blob")
	@Column(length = 20971520)
	private byte[] imagesTile;

	public byte[] getImagesTile() {
		return imagesTile;
	}

	public void setImagesTile(byte[] imagesTile) {
		this.imagesTile = imagesTile;
	}

	public byte[] getImages() {
		return images;
	}

	public void setImages(byte[] images) {
		this.images = images;
	}

	public Task getTask() {
		return task;
	}

	public void setTask(Task task) {
		this.task = task;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public byte[] getExcelContent() {
		return excelContent;
	}

	public void setExcelContent(byte[] excelContent) {
		this.excelContent = excelContent;
	}

	public byte[] getZipContent() {
		return zipContent;
	}

	public void setZipContent(byte[] zipContent) {
		this.zipContent = zipContent;
	}

	public byte[] getXmlContent() {
		return xmlContent;
	}

	public void setXmlContent(byte[] xmlContent) {
		this.xmlContent = xmlContent;
	}

	public byte[] getWordContent() {
		return wordContent;
	}

	public void setWordContent(byte[] wordContent) {
		this.wordContent = wordContent;
	}

}
这么多的大字段,在处理类似的更新时可能存在这种写法:

List<TaskTemplate> taskTemplates = taskTemplateManager.getByTaskID(tsk.getId());
			for (TaskTemplate taskTemplate : taskTemplates) {
				if (imageForm != null)
					taskTemplate.setImages(imageForm);
				if (imageTile != null)
					taskTemplate.setImagesTile(imageTile);
			}
			taskTemplateManager.saveOrUpdateAll(taskTemplates);

2、处理:并且这里的saveOrUpdateAll使用时Hibernate中模板类方式,更新将会是全表的所有字段。但实际上应用只有来两个需要变化的字段,处理就可以改为这样比较合适:(1、使用hql限制字段 2、使用软解析赋值处理)

public void saveAndUpdateLittle(TaskTemplate taskTemplates){
		String update = "update TaskTemplate t set t.images=?,t.imagesTile=? where t.id = ?";
		taskTemplateDao.executeHql(update, taskTemplates.getImages(),taskTemplates.getImagesTile(),taskTemplates.getId());
	}


public void executeHql(String hsql,Object... values) throws HibernateException{
		Query query = createQuery(hsql, values);
		query.executeUpdate();
	}

public Query createQuery(final String hql,
			final Object... values) {
		return (Query) this.getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = session.createQuery(hql);

				if (values != null) {
					for (int i = 0; i < values.length; i++) {
						query.setParameter(i, values[i]);
					}
				}
				return query;
			}
		});

	}

这样,问题解决了,并且效率得到较大提升:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值