跳转到内容

查询模型使用示例

查询模型(query model)的特性及原理可以参考:查询模型使用文档

本文档使用下面模型生成的query model作为示例,描述query model的使用方式

@Data
@ToString(callSuper = true)
@Model(
name = "员工模型",
mainField = "staffName",
fieldGroups = {
@FieldGroup(fieldName = {Staff.staffNumber_field, Staff.staffName_field}),
@FieldGroup(fieldName = {Staff.staffNumber_field, Staff.staffName_field}, type = FieldGroupType.SEARCHABLE),
@FieldGroup(fieldName = {Staff.staffNumber_field, Staff.staffName_field}, type = FieldGroupType.SEARCH_SHOW),
}
)
public class Staff extends BaseModel<Long> {
@Field(name = "员工名称")
private String staffName;
@TextMeta(rule = "STRING(STAFF)+TIMES(yyyy-MM-dd)+INCRE(1,6,0,0)")
@Field(name = "员工编号")
private String staffNumber;
@Field(name = "手机号", type = FieldType.Phone, nullable = false)
@NotNull(message = "手机号不能为空")
private String mobile;
@Field(name = "邮箱", type = FieldType.Email)
private String email;
@Field(name = "出生日期", type = FieldType.Date)
private Date birthday;
/**
* 非持久化字段,年龄通过 birthday 实时计算
*/
@Transient
@Field(name = "年龄")
private Integer age;
@Field(name = "住址", type = FieldType.Text)
private String liveAddress;
/**
* 薪资, 主要为了引入 Currency 类型字段
*/
@Field(name = "薪资", type = FieldType.Currency)
private Currency salary;
@Field(name = "岗位类型")
@NotNull(message = "岗位类型不能为空")
@DictionaryMeta(value = PositionType.class)
private String positionType;
@Field(name = "所属公司", nullable = false, type = FieldType.Link)
@NotNull(message = "公司不能为空")
@LinkMeta
private Company company;
/**
* 多对多,员工可能属于多个虚拟组织,如纵向划分职能部门后,还有横向的架构评审委员会等虚拟部门
*/
@Field(name = "部门", type = FieldType.LookupMany)
@NotNull(message = "部门不能为空")
@LookupMeta(linkField = StaffDepartmentRelation.staff_field)
@JunctionMeta(model = StaffDepartmentRelation.class, lookupField = StaffDepartmentRelation.department_field)
private List<Department> departments;
/**
* 一对一,一人一台笔记本电脑,一个笔记本同时只能所属一个员工
*/
@Field(name = "办公设备")
@LookupMeta
private Equipment equipment;
}

级联查询

示例中嵌套查询了Staff.Department.id、Staff.Department.name、Staff.Department.Company.id、Staff.Department.Company.name字段,展示了三层嵌套,如果实际使用中嵌套深度更深,按照规律继续嵌套下去即可

QStaff staff = new QStaff();
Select select = new Select();
select.addField(Staff.id_field);
select.addField(Staff.staffName_field);
Set<Select.Field> deptSelect = new HashSet<>();
deptSelect.add(new Select.Field(Department.id_field));
deptSelect.add(new Select.Field(Department.name_field));
Set<Select.Field> companySelect = new HashSet<>();
companySelect.add(new Select.Field(Company.id_field));
companySelect.add(new Select.Field(Company.name_field));
deptSelect.add(new Select.Field(Department.company_field, companySelect));
select.addField(Staff.departments_field, deptSelect);
staff.getQueryParams().setSelect(select);
staff.setId(new QLongId(Lists.newArrayList(1L, 2L, 3L)));
List<Staff> all = DS.findAll(staff);

上面示例的sql:

select id,staffName,departments.id,departments.name,departments.company.id,departments.company.name from erp_Staff where id in (?)

IS NULL & IS NOT NULL

通过设置query model字段的Operators属性实现,意味着使用手动指定的操作比较当前字段,而不是自动推断字段的比较操作,Operators还有其他枚举,表示不同的操作,例如 != 、 not in 等。

QStaff staff = new QStaff();
QString staffName = new QString("");//value 不能是 null
staffName.setOperator(Operators.NOT_NULL);
// staffName.setOperator(Operators.NULL);
staff.setStaffName(staffName);
List<Staff> all = DS.findAll(staff);

示例的sql:

select * from erp_Staff where staffName is not null

range

范围查询,不是query model中所有字段都可以使用这种方式查询,是RangeType子类的字段才能使用,需要注意的是,QString不是RangeType的子类,因此不能使用这种方式,QLong是RangeType的子类,但是QLongId不是RangeType子类,因此id字段也不能通过这种方式查询

QStaff staff = new QStaff();
QDate birthday = new QDate(DateUtils.parseDate("2020-1-1", "yyyy-MM-dd"), new Date());
staff.setBirthday(birthday);
List<Staff> all = DS.findAll(staff);

示例的sql:

select * from erp_Staff where birthday >= ? and birthday <= ?