属性表达式

接下来我们来看看属性表达式。在之前的例子中,属性表达式只涉及到被管理的实体类的直接属性,在创建查询时我们已经确保解析出的属性是被管理实体类的属性之一。实际上,我们可以定义嵌套属性。假设Person类有一个Address,Address中又有ZipCode。在这种情况下,下面方法的方法名会通过x.address.zipCode来检索属性。

List<Person> findByAddressZipCode(ZipCode zipCode);

Spring Data的查询构造器会先把AddressZipCode当做一个整体,检查其是不是实体类的一个属性。如果是,就使用这个属性。如果不是,会按照驼峰式从右向左进行分割,再进行属性匹配。在上面的例子中,会将AddressZipCode分为AddressZipCode。如果第一次分割之后还没有找到相匹配的属性,构造器会左移分割点重新进行分割,分为AddressZipCode,并继续解析是否有相匹配的属性。 在大多数情况下,构造器都能够正确的解析出相匹配的属性。但在某些特殊情况下,可能会选择了错误的属性。假设Person类中除了address外,还有一个addressZip属性。那么构造器会在第一次分割后就匹配到相应的属性,然后报错(因为addressZip中没有code属性)。 为了避免的解析的歧义问题,我们可以在方法名中使用'_'符号来显式的表达意图,更改后的方法名如下:

List<Person> findByAddress_ZipCode(ZipCode zipCode);

因为构造器已经将下划线作为保留字符,所以强烈建议开发者遵循标准的Java命名规范,不要在属性名中使用下划线,采用驼峰式命名。