所谓通过“规范”的方法实现查询,就是我们只要对方法的命名按照 Spring Data 给我们规定的命名方式,我们就可以不用写 SQL 语句。
好处:
1、简单,实现简单查询开发效率高;
缺点:
1、方法名高度耦合,写的时候要参考文档进行编写;
2、不能实现一些复杂查询。
测试方法1:
Person getByLastNameStartingWithAndIdLessThan(String lastName,Integer id);
测试代码:
/**
*测试方法规范,使用方法规范的时候,我们发现,方法名的耦合度非常高
* 这样就丧失了灵活性,
* 例如 getByLastNameStartingWithAndIdLessThan 我写成 getByLastNameStartWithAndIdLessThan 就不对了
*/
@Test
public void testKeyWords() {
System.out.println(personRepository.getClass().getName());
Person person = personRepository.getByLastNameStartingWithAndIdLessThan("zhou", 3);
System.out.println(person);
}
控制台:
测试方法2:
Person getByLastNameEndingWithAndEmail(String lastName,String email);
测试代码2:
@Test
public void testKeyWords02() {
System.out.println(personRepository.getClass().getName());
Person person = personRepository.getByLastNameEndingWithAndEmail("guang", "zhouguang@163.com");
System.out.println(person);
}
控制台:
测试方法3:
List<Person> getByEmailInAndIdLessThan(List<String> emails,Integer id);
测试代码3:
/**
* 我的感受是这种方式,写之前一定要查一下表
*/
@Test
public void testKeyWords03() {
System.out.println(personRepository.getClass().getName());
List<Person> persons = personRepository.getByEmailInAndIdLessThan(Arrays.asList("zhouguang@163.com","liwei@sina.com"), 3);
for(Person person :persons){
System.out.println(person);
}
}
控制台:
测试级联
测试方法4:
// 根据级联属性 Address 下的 id 查询(这里有导航的概念)
List<Person> getByAddressIdGreaterThan(Integer id);
测试代码4:
/**
* 测试级联
*/
@Test
public void testKeyWords2(){
List<Person> persons = personRepository.getByAddressIdGreaterThan(1);
for(Person person :persons){
System.out.println(person);
}
}
控制台:
我似乎还不太明白,所以我又写个一个测试方法
// 根据级联属性 Address 下的 province 查询(这里有导航的概念)
List<Person> getByAddressProvince(String name);
/**
* 测试级联2
*/
@Test
public void testKeyWords2Ex(){
List<Person> persons = personRepository.getByAddressProvince("fujian");
for(Person person :persons){
System.out.println(person);
}
}
控制台:
这里我们要注意一点:
getByAddressProvince
这种写法如果有属性 addressProvince,会按照属性进行 where 查询;
如果 Person 里有 address 属性,并且 address 有级联属性 province ,则会进行级联查询。
两者都存在的情况下,优先进行属性查询。如果我们非要级联查询,级联属性之间可以使用 “_” 连接。
注意:优先使用当前类的属性进行 where 查询,而不会进行关联查询。如果要强制关联查询,方法签名应该这样写。
// 根据级联属性 Address 下的 id 查询(这里有导航的概念)
List<Person> getByAddress_IdGreaterThan(Integer id);
// 根据级联属性 Address 下的 province 查询(这里有导航的概念)
List<Person> getByAddress_Province(String name);
解决办法其实很简单: