欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

继承jpa Repository 写自定义方法查询实例

程序员文章站 2022-01-23 10:21:34
目录继承jpa repository写自定义方法查询首先定义实体类项目报错提示信息为是什么原因呢?jparepository 命名规范继承jpa repository写自定义方法查询今天在写jpa查询...

继承jpa repository写自定义方法查询

今天在写jpa查询的时候,遇到了添加自定义方法,项目启动报错原因,现总结如下:

首先定义实体类

@entity
@table(name = "user")
class user{
     @id
    @generatedvalue 
      int id;
      @column
      string age;
      @column
      string school;
      @column
      string username;
  set,get方法 (省略)
 
}
public interface userrepository extends jparepository<user, long> {
      list<user> findbyusernamelike(string username);
     list<user> aaa();
}

启动项目时,

项目报错提示信息为

org.springframework.data.mapping.propertyreferenceexception: no property aaa found for type com.fpi.safety.common.entity.po.user

再将list<user> aaa();方法去掉后,项目又可以正常启动运行

是什么原因呢?

经查找,原来是继承jpa,必须满足一些规则,规则如下

继承jpa Repository 写自定义方法查询实例

继承jpa Repository 写自定义方法查询实例

spring data jpa框架在进行方法名解析时,会先把方法名多余的前缀截取掉,比如find,findby,read,readby,get,getby,然后对剩下的部分进行解析。

假如创建如下的查询:findbyusername(),框架在解析该方法时,首先剔除findby,然后对剩下的属性进行解析,假设查询实体为user

1:先判断username(根据pojo规范,首字母变为小写)是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步;

2:从右往左截取第一个大写字母开头的字符串此处是name),然后检查剩下的字符串是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设用户为查询实体的一个属性;

3:接着处理剩下部分(username),先判断用户所对应的类型是否有username属性,如果有,则表示该方法最终是根据“user.username”的取值进行查询;否则继续按照步骤2的规则从右往左截取,最终表示根据“user.username”的值进行查询。

4:可能会存在一种特殊情况,比如user包含一个的属性,也有一个usernamechange属性,此时会存在混合。可以明确在属性之间加上“_”以显式表达意思,比如“findbyuser_namechange )“或者”findbyusername_change()“

从上面,我们可以得知,jap在解析是,aaa在user类中是没有属性的,所以报错no property aaa found.

如果我们想要使用jap框架,又不想再多增加一个自定义类,则必须符合其命名规则

如果,你记不住jpa的规则也没关系,你可以自己再多写一个类来实现自定义查询方法

如下:

1. 自定义一个接口,该接口用来声明自己额外定义的查询。

public interface useerrepositorytwo {
    public list<user> searchuser(string name, int id);
}

2. 创建一个接口,该接口 extends jparepository 或者 curdrepository, 以及上面自己定义的接口 useerrepositorytwo

public interface userrepositorytwoservice extends crudrepository<logdto, integer>, customizedlogrepository {
}

3. 实现userrepositorytwoservice

注意此处的类名,必须以 2 中创建的接口的名字userrepositorytwoservice,后面加上 impl 来声明,而不是写成 useerrepositorytwoimpl

public class userrepositorytwoserviceimpl implements userrepositorytwoservice {
    @autowired
    @persistencecontext
    private entitymanager entitymanager;
    @override
    public list<user> searchlogs(int id, string name) {
        ......
    }
}

自己在写自定义实现即可~

jparepository 命名规范

keyword sample jpql
and findbylastnameandfirstname where x.lastname=?1 and x.firstname=?2
or findbylastnameorfirstname where x.lastname=?1 or x.firstname=?2
between findbystartdatebetween where x.startdate between ?1 and ?2
lessthan findbyagelessthan where x.startdate < ?1
greaterthan findbyagegreaterthan where x.startdate >?1
after findbystartdateafter where x.startdate >n ?1
before findbystartdatebefore where x.startdate < ?1
isnull findbyageisnull where x.age is null
isnotnull,notnull findbyage(is)notnull where x.age not null
like findbyfirstnamelike where x.firstname like ?1
notlike findbyfirstnamenotlike where x.firstname not like ?1
startingwith findbyfirstnamestartingwithxxx where x.firstname like ?1(parameter bound with appended %)
endingwith findbyfirstnameendingwithxxx where x.firstname like ?1(parameter bound with appended %)
containing findbyfirstnamecontaining where x.firstname like ?1(parameter bound wrapped in %)
orderby findbyageorderbylastname where x.age = ?1 order by x.lastname desc
not findbylastnamenot where x.lastname <> ?1
notin findbyagenotin(collection age ) where x.age not in ?1
true findbyactivetrue() where x.active = true
false findbyactivefalse()

where x.active = false

例:

@repositorydefinition(domainclass = employee.class, idclass = integer.class)
public interface employeerepository { //extends repository<employee,integer>{
    public employee findbyname(string name);
    // where name like ?% and age <?
    public list<employee> findbynamestartingwithandagelessthan(string name, integer age);
    // where name like %? and age <?
    public list<employee> findbynameendingwithandagelessthan(string name, integer age);
    // where name in (?,?....) or age <?
    public list<employee> findbynameinoragelessthan(list<string> names, integer age);
    // where name in (?,?....) and age <?
    public list<employee> findbynameinandagelessthan(list<string> names, integer age);
    @query("select o from employee o where id=(select max(id) from employee t1)")
    public employee getemployeebymaxid();
    @query("select o from employee o where o.name=?1 and o.age=?2")
    public list<employee> queryparams1(string name, integer age);
    @query("select o from employee o where o.name=:name and o.age=:age")
    public list<employee> queryparams2(@param("name")string name, @param("age")integer age);
    @query("select o from employee o where o.name like %?1%")
    public list<employee> querylike1(string name);
    @query("select o from employee o where o.name like %:name%")
    public list<employee> querylike2(@param("name")string name);
    @query(nativequery = true, value = "select count(1) from employee")//这个使用了原生sql
    public long getcount();
    @modifying
    @query("update employee o set o.age = :age where o.id = :id")
    public void update(@param("id")integer id, @param("age")integer age);
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。