package jef.database.query; import java.util.List; import java.util.Map; import jef.database.Condition; import jef.database.Condition.Operator; import jef.database.Field; import jef.database.IConditionField; import jef.database.IQueryableEntity; import jef.database.meta.Reference; /** * 描述最通用的条件容器和查询内容 * @author Administrator * @Date 2011-6-16 * @param <T> */ public interface Query<T extends IQueryableEntity> extends TypedQuery<T>,JoinElement{ /** * 添加级联对象过滤条件 * 在对象中你可以创建{@link javax.persistence.OneToOne OneToOne} {@link javax.persistence.OneToMany OneToMany} * {@link javax.persistence.ManyToOne ManyToOne} * {@link javax.persistence.ManyToMany ManyToMany}等引用关系。 * 查询时这会产生级联查询来加载关联的对象。在这里添加的条件,可被用于过滤<strong>级联的对象</strong>。(注意:是级联引用的指向对象,不是当前对象)<br> * <h3>举例来说:</h3> * <pre><code> * Student student=new Student(); * student.getQuery().addCondition(QB.eq(Student.Field.id, 1)); * student.getQuery().addCascadeCondition( QB.eq(Lesson.Field.name, "语文")); * Student student=session.load(student); * //在上例中,无论学生是否有语文课成绩记录,都不影响查询ID=1的学生。 * //然而 * student.getLessons(); //此处得到的Lesson中只会有'语文' * </code></pre> * 总结来说——CascadeCondition只会影响到级联对象的选择,永远不会影响当前对象的选择。 * <br> * * <h3>为何使用</h3> * 一般来说,仅在一对多的时候使用。在上例中,如果一个学生对应的课程记录有数千条,而我们每次只需要统计学生“语数外”的成绩时, * 将其他课程的成绩查出来显然是十分浪费的。因此我们可以用CascadeCondition进一步缩小一对多查询的选择返回,防止因为一对多关系被滥用造成的性能下降 * * <h3>其他</h3> * 这一特性是即时加载还是延迟加载时都会生效。当用于对一级联时,如果不是左外连接,启用此特性将造成原本一次查出(使用外连接)的结果,被拆成两次查询。 * * * @param conditions * @return 当前Query对象 * @since 1.1 * @author Jiyi */ Query<T> addCascadeCondition(Condition conditions); /** * 添加级联对象过滤条件 * 在对象中你可以创建{@link javax.persistence.OneToOne OneToOne} {@link javax.persistence.OneToMany OneToMany} * {@link javax.persistence.ManyToOne ManyToOne} * {@link javax.persistence.ManyToMany ManyToMany}等引用关系。 * 查询时这会产生级联查询来加载关联的对象。在这里添加的条件,可被用于过滤<strong>级联的对象</strong>。(注意:是级联引用的指向对象,不是当前对象)<br> * <h3>举例来说:</h3> * <pre><code> * Student student=new Student(); * student.getQuery().addCondition(QB.eq(Student.Field.id, 1)); * student.getQuery().addCascadeCondition( QB.eq(Lesson.Field.name, "语文")); * Student student=session.load(student); * //在上例中,无论学生是否有语文课成绩记录,都不影响查询ID=1的学生。 * //然而 * student.getLessons(); //此处得到的Lesson中只会有'语文' * </code></pre> * 总结来说——CascadeCondition只会影响到级联对象的选择,永远不会影响当前对象的选择。 * <br> * * <h3>为何使用</h3> * 一般来说,仅在一对多的时候使用。在上例中,如果一个学生对应的课程记录有数千条,而我们每次只需要统计学生“语数外”的成绩时, * 将其他课程的成绩查出来显然是十分浪费的。因此我们可以用CascadeCondition进一步缩小一对多查询的选择返回,防止因为一对多关系被滥用造成的性能下降 * * <h3>其他</h3> * 这一特性是即时加载还是延迟加载时都会生效。当用于对一级联时,如果不是左外连接,启用此特性将造成原本一次查出(使用外连接)的结果,被拆成两次查询。 * @param refName 发生关系的字段名, 比如A -> B有多条路径的引用关系。用这个名称可以区分出是哪一条引用关系,可以指定间接级联关系,如 member.info * @param conditions * @return 当前Query对象 * @since 1.1 * @author Jiyi */ Query<T> addCascadeCondition(String refName,Condition... conditions); /** * 添加扩展查询 * @param querys * @return 当前Query对象 */ Query<T> addExtendQuery(Query<?> querys); /** * 清除所有其他条件,设置为全纪录查询条件 * @return 当前Query对象 */ Query<T> setAllRecordsCondition(); /** * 添加一个条件,运算符为equals * @param field * @param value * @return 当前Query对象 */ Query<T> addCondition(Field field,Object value); /** * 添加一个条件 * @param field 字段 * @param oper 运算符 * @param value 值 * @return 当前Query对象 */ Query<T> addCondition(Field field, Operator oper,Object value); /** * 添加一个条件,如Or Not And Exists NotExists等复杂条件 * @param condition 条件 * @return 当前Query对象 * @see IConditionField * @see IConditionField.And * @see IConditionField.Or * @see IConditionField.Not * @see IConditionField.Exists * @see IConditionField.NotExists * @since 1.1 * @author Jiyi * @see IConditionField */ Query<T> addCondition(IConditionField condition); /** * 添加一个条件,与之前的条件为And关系 * @param condition 条件 * @return Query对象本身 */ Query<T> addCondition(Condition condition); /** * 得到子查询过滤条件 * @return 所有的子查询过滤条件 */ Map<Reference, List<Condition>> getFilterCondition(); /** * 目前的设计趋势是逐步将DataObject相分离,用IQuery来代替原来DataObject的查询接口。 * @return */ T getInstance(); /** * 得到Query的其他查询提供者, * @return 其他外连接查询 */ Query<?>[] getOtherQueryProvider(); /** * 设置自定义的查询表名 * @param name */ void setCustomTableName(String name); /** * 获取:是否尝试用外连接的方式,一次性查出级联关系 * * @return 如果开启自动外连接功能,返回true * @see jef.database.DbCfg#DB_USE_OUTER_JOIN */ public boolean isCascadeViaOuterJoin(); /** * 设置:是否尝试用外连接的方式,一次性查出级联关系 * @param cascadeViaOuterJoin 如果为true,将尽量合并数据库查询来减少操作次数。 */ public void setCascadeViaOuterJoin(boolean cascadeViaOuterJoin); /** * 设置是否要使用级联查询。调用这个方法的效果等同于同时调用下面两个方法<code><pre> * .getResultTransformer().setLoadVsMany(false); * .getResultTransformer().setLoadVsOne(false); * </pre></code> * @param cascade 是否要级联查询 * @see jef.database.wrapper.populator.Transformer#setLoadVsMany(boolean) * @see jef.database.wrapper.populator.Transformer#setLoadVsOne(boolean) */ public void setCascade(boolean cascade); /** * 是否查询全部记录 * @return */ boolean isAll(); /** * 查询条件生成器 * <strong>试验性功能。<strong> * @return Terms * @see Terms */ Terms terms(); }