`
wubo_789
  • 浏览: 13368 次
  • 性别: Icon_minigender_1
  • 来自: 武穴
社区版块
存档分类
最新评论

Hibernate字段查询问题小记

阅读更多
我有一个实体类,包含了BLOB字段和集合属性字段,有时候查询希望排除BLOB字段和集合属性字段,有时候又希望只排除其中一个,这时问题就来了。
本来BLOB字段也可以设为lazy为true的,但是要做什么字节码强化,我想走走其他路子。
EntityBean
public class FormInfo {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	//主键
	private long id;
	@Column(name="owner_id")
	//所有者主键
	private long ownerId;
	@Column(name="title_text",nullable=false)
	//标题
	private String titleText;
	@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
	@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
	@JoinColumn(name="forminfo_id")
	//字段
	private Set<FieldInfo> fields;
	@Basic(fetch=FetchType.LAZY)
	@Lob
	@Column(name="source_code",columnDefinition="CLOB")
	//表单源码
	private String sourceCode;
	@Column(name="table_name",unique=true,nullable=false)
	//数据表名
	private String tableName;
	@Column(name="create_time")
	//创建时间
	private Timestamp createTime;
	@Column(name="update_time")
	//修改时间
	private Timestamp updateTime;
	//描述
	private String description;
	//删除标记
	private boolean deleted;
	//锁定标记
	private boolean locked; 
	//完成标记
	private boolean completed;
	@Column(name="module_id")
	//模块主键
	private long moduleId;

	public FormInfo(){
		
	}
	//为HQL准备 日期类型改为java.util.Date类型,不然会报找不到构造方法异常
	public FormInfo(long id, long ownerId, String titleText,
			Set<FieldInfo> fields, String tableName, java.util.Date createTime,
			java.util.Date updateTime, String description, boolean deleted,
			boolean locked, boolean completed, long moduleId) {
		super();
		this.id = id;
		this.ownerId = ownerId;
		this.titleText = titleText;
		this.fields = fields;
		this.tableName = tableName;
		this.createTime = new java.sql.Timestamp(createTime.getTime());
		this.updateTime = new java.sql.Timestamp(updateTime.getTime());
		this.description = description;
		this.deleted = deleted;
		this.locked = locked;
		this.completed = completed;
		this.moduleId = moduleId;
	}

	public FormInfo(long id, long ownerId, String titleText, String tableName,
			java.util.Date createTime, java.util.Date updateTime, String description,
			boolean deleted, boolean locked, boolean completed, long moduleId) {
		super();
		this.id = id;
		this.ownerId = ownerId;
		this.titleText = titleText;
		this.tableName = tableName;
		this.createTime = new java.sql.Timestamp(createTime.getTime());
		this.updateTime = new java.sql.Timestamp(updateTime.getTime());
		this.description = description;
		this.deleted = deleted;
		this.locked = locked;
		this.completed = completed;
		this.moduleId = moduleId;
	}
//...省略getter、setter
}

BeanUtils
public class BeanUtils {
	
	private static Log logger = LogFactory.getLog(BeanUtils.class);
	
	/**
	 * @param entityClass 实体类
	 * @param prefix 前缀
	 * @param fields 要过滤的字段列表
	 * @return 返回逗号分隔的entityClass的所有声明字段,排除filters指定的字段
	 */
	public static String getFieldNames(Class entityClass, String prefix, String... filters){
		Field[] fs = entityClass.getDeclaredFields();
		StringBuilder sb = new StringBuilder();
		String p = prefix != null ? prefix : "";
		for(int i=0;i<fs.length;i++){
			Field f = fs[i];
			if(contains(f.getName(), filters)){
				continue;
			}
			if(i>0)sb.append(",");
			sb.append(p + f.getName());
		}
		return sb.toString();
	}
	
	private static boolean contains( String f, String... fs){
		if(fs == null)return false;
		boolean result = false;
		for(int i=0; i<fs.length; i++){
			if(fs[i].indexOf(",") != -1){
				return contains(f, fs[i].split(","));
			}else{
				if(f.equals(fs[i])){
					result = true;
					break;
				}
			}
		}
		return result;
	}
}


尝试一:HQL
super.find("select new FormInfo(" + BeanUtils.getFieldNames(FormInfo.class, "f.", "sourceCode") + ") from FormInfo f where f.completed = true");
生成SQL如下:
select
        forminfo0_.id as col_0_0_,
        forminfo0_.owner_id as col_1_0_,
        forminfo0_.title_text as col_2_0_,
        . as col_3_0_,
        forminfo0_.table_name as col_4_0_,
        forminfo0_.create_time as col_5_0_,
        forminfo0_.update_time as col_6_0_,
        forminfo0_.description as col_7_0_,
        forminfo0_.deleted as col_8_0_,
        forminfo0_.locked as col_9_0_,
        forminfo0_.completed as col_10_0_,
        forminfo0_.module_id as col_11_0_
    from
        t_bddz_forminfo forminfo0_
    inner join
        t_bddz_fieldinfo fields1_
            on forminfo0_.id=fields1_.forminfo_id
    where
        forminfo0_.completed=1
异常:org.hibernate.util.JDBCExceptionReporter,101 - ORA-00936: 缺失表达式
super.find("select new FormInfo(" + BeanUtils.getFieldNames(FormInfo.class, "f.", "sourceCode,fields") + ") from FormInfo f where f.completed = true");
生成SQL:
select
        forminfo0_.id as col_0_0_,
        forminfo0_.owner_id as col_1_0_,
        forminfo0_.title_text as col_2_0_,
        forminfo0_.table_name as col_3_0_,
        forminfo0_.create_time as col_4_0_,
        forminfo0_.update_time as col_5_0_,
        forminfo0_.description as col_6_0_,
        forminfo0_.deleted as col_7_0_,
        forminfo0_.locked as col_8_0_,
        forminfo0_.completed as col_9_0_,
        forminfo0_.module_id as col_10_0_
    from
        t_bddz_forminfo forminfo0_
    where
        forminfo0_.completed=1
异常:org.hibernate.QueryException: could not instantiate class [org.bsth.bddz.bean.FormInfo] from tuple
测试结果:失败,看来行不通了。


尝试二:用投影
public List<FormInfo> list(){
return super.findFieldsOfBean(BeanUtils.
getFieldNames(FormInfo.class, "", "sourceCode,fields").split(",")
, "completed", new Object[]{true});
}
一切正常
生成SQL:
select
        this_.id as y0_,
        this_.owner_id as y1_,
        this_.title_text as y2_,
        this_.table_name as y3_,
        this_.create_time as y4_,
        this_.update_time as y5_,
        this_.description as y6_,
        this_.deleted as y7_,
        this_.locked as y8_,
        this_.completed as y9_,
        this_.module_id as y10_
    from
        t_bddz_forminfo this_
    where
        this_.completed=?
如果改为:
public List<FormInfo> list(){
return super.findFieldsOfBean(BeanUtils.getFieldNames(FormInfo.class, "", "sourceCode").split(",")
, "completed", new Object[]{true});
}
并在findFieldsOfBean(...)方法中添加criteria.setFetchMode("fields", FetchMode.JOIN);
执行结果和SQL都同上一个一样,并没有把fields关联查询出来
看来在Hibernate中如果用了投影查询,FetchMode.JOIN就不起作用了

总结:目前还没解决即要排除BLOB字段又要关联集合属性字段的查询。
分享到:
评论

相关推荐

    Hibernate_query查询数据表中的一个字段.

    本篇将详细讲解如何使用Hibernate进行查询,特别是针对数据表中的一个特定字段。 一、Hibernate简介 Hibernate是Java领域的一个开源ORM框架,它简化了数据库操作,通过映射Java类到数据库表,可以将数据库操作转化...

    Hibernate_query查询数据表中部分字段.

    本文将深入探讨如何使用Hibernate进行数据表中的部分字段查询,这在实际开发中是非常常见的需求。 首先,理解Hibernate的核心概念:实体(Entity)、持久化类(Persistent Class)和映射文件(Mapping File)。实体...

    注意hibernate查单一字段和查两个以上的字段返回的结果

    在实际应用中,我们需要合理设计查询,避免N+1查询问题,这通常通过预加载(Eager Loading)或多级缓存来解决。预加载可以在一次查询中加载关联的对象,减少数据库交互次数。而使用二级缓存则可以存储已经查询过的...

    Hibernate更新某些字段

    为了解决这个问题,Hibernate 提供了三种方法来更新某些字段: ### 方法一:在 XML 中设置 property 标签 update = "false" 在 Hibernate 的 XML 配置文件中,我们可以设置某些属性的 update 属性为 false,这样 ...

    Hibernate连表查询 Hibernate连表查询

    如果查询结果包含多个字段,并且希望将这些字段封装成一个对象,则可以使用Hibernate的投影列表功能,或者手动创建一个新的类来存储查询结果。 ### 总结 本文主要介绍了Hibernate中的连表查询方法及其在实际开发中...

    Hibernate中对表某个字段排序

    Hibernate中对表某个字段排序,直接在配置里面实现排序功能。

    Hibernate分页查询小结

    Hibernate分页查询小结

    hibernate根据字段生成数据库表

    ### Hibernate根据字段生成数据库表 #### 一、概述 在软件开发过程中,特别是在进行多数据库支持的应用程序开发时,我们经常需要将同一套代码部署到不同的数据库系统上。这种情况下,手动为每个数据库创建相同的表...

    hibernate 进行多表查询每个表中各取几个字段

    本篇文章将探讨如何在Hibernate中进行多表查询,并从每个表中选取特定的字段。 一、Hibernate的多表查询基础 在Hibernate中,多表查询通常涉及到关联关系的映射,包括一对一(OneToOne)、一对多(OneToMany)、多...

    用Hibernate实现领域对象的自定义字段

    本文将深入探讨如何使用Hibernate实现领域对象的自定义字段,这涉及到对Hibernate核心概念的理解以及自定义类型的应用。 首先,我们需要了解Hibernate的核心概念。Hibernate主要通过配置文件(hibernate.cfg.xml)...

    hibernate3中通过nativesql或取部分字段并映射为具体对象的实现

    本篇文章将深入探讨在Hibernate3中如何通过Native SQL查询部分字段,并将其映射到具体的Java对象上。这种方式在处理一些特定的、效率较高的SQL查询时非常有用。 首先,我们需要理解Hibernate中的`SQLQuery`接口,这...

    Hibernate 配置跟数据库字段的对应关系

    本文将深入探讨如何在Hibernate配置中设置与数据库字段的对应关系,以及相关的Mysql数据库数据类型。 首先,我们需要理解Hibernate的核心配置文件`hibernate.cfg.xml`,在这个文件中,我们定义了数据源、持久化类...

    hibernate将本地SQL查询结果封装成对象

    要将本地SQL查询的结果封装成对象,我们首先需要定义一个映射文件(.hbm.xml),在这个文件中,我们需要指定查询返回的对象类型以及字段与数据库列的对应关系。例如: ```xml &lt;hibernate-mapping&gt; ...

    hibernate使用中与各种数据库字段类型对应类型训练

    本训练主要关注在使用Hibernate时如何处理与各种数据库字段类型的映射,这对于理解和优化数据库交互至关重要。 首先,我们要理解Hibernate的核心概念——对象关系映射(ORM)。ORM允许我们将数据库表结构映射到Java...

    hibernate实现动态SQL查询

    相比静态SQL,动态SQL更加灵活,能够适应复杂多变的查询需求,避免了硬编码SQL带来的问题,如代码冗余、难以维护等。 三、Hibernate中的动态SQL 在Hibernate中,我们通常使用HQL(Hibernate Query Language)或...

    hibernate实现递归查询

    本文将深入探讨如何使用Hibernate实现递归查询,以解决在数据层次结构中涉及父节点与子节点关系时的问题。递归查询通常用于处理树形结构的数据,例如组织结构、菜单系统或者文件目录等。 首先,我们需要了解递归的...

    hibernate实体映射文件字段设置默认值

    ### Hibernate实体映射文件字段设置默认值 在Hibernate框架中,实体映射文件(通常为`.hbm.xml`)用于定义Java对象与数据库表之间的映射关系。这其中包括了属性到数据库表列的映射、主键生成策略、以及一些高级特性...

    hibernate通用查询

    Hibernate通用查询是Java开发中非常重要的一个概念,它极大地简化了数据库操作,使得开发者无需编写大量的SQL语句,即可实现复杂的数据查询。本知识点主要围绕Hibernate的通用查询功能展开,包括其基本原理、优势...

Global site tag (gtag.js) - Google Analytics