spring CrudRepository、JpaSpecificationExecutor接口

最近在改造一个spring boot的项目,看到下面代码

package com.example.demo.repository;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;


import com.example.demo.data.TestEntity;
public interface TTestRepository extends CrudRepository<TestEntity, Long>,JpaSpecificationExecutor<TestEntity>{


TestEntity findByUserName(String userName);

Page<TestEntity> queryByUserName(String userName,Pageable pageable);

Slice<TestEntity> queryById(Long Id,Pageable pageable);

List<TestEntity> findBypassWord(String passWord,Sort sort);

}


注入接口调相应的方法,

@RestController
public class TestInterfaceImpl {


@Autowired
TTestRepository itestRepository;

@RequestMapping("/findById")
public String testRep(){
TestEntity entity = itestRepository.findByUserName("ZhangSan");
return entity.toString();
}


@RequestMapping("/add")
public String testAdd(){
TestEntity entity = new TestEntity("LiSi","123456");
itestRepository.save(entity);
return entity.toString();
}

@RequestMapping("/queryPage")
public String queryPage(@PageableDefault(value=20,sort={"id","userName"},direction = Sort.Direction.DESC) Pageable pageable){
Page<TestEntity> page = itestRepository.queryByUserName("ZhangSan", pageable);
return page.toString();
}

@RequestMapping("/querySlice")
public String querySlice(@PageableDefault(value=20,sort={"id","userName"},direction = Sort.Direction.DESC) Pageable pageable){
Slice<TestEntity> slice = itestRepository.queryById(1l, pageable);
return slice.getContent().get(0).toString();
}
}

正常工作。

看到这百思不得其解,没有找到接口的实现类啊???

1:继承了CrudRepository、JpaSpecificationExecutor接口也没看到自己写的接口类的实现,这是怎么一回事?

答1:了解到spring-data-jpa提供了CrudRepository、JpaSpecificationExecutor接口的默认实现,实现类为SimpleJpaRepository,package:org.springframework.data.jpa.repository.support

/**

 * Default implementation of the {@link org.springframework.data.repository.CrudRepository} interface. This will offer
 * you a more sophisticated interface than the plain {@link EntityManager} .
 * 
 * @author Oliver Gierke
 * @author Eberhard Wolff
 * @author Thomas Darimont
 * @author Mark Paluch
 * @param <T> the type of the entity to handle
 * @param <ID> the type of the entity's identifier
 */
@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID extends Serializable>

implements JpaRepository<T, ID>, JpaSpecificationExecutor<T> {

2:CrudRepository<TestEntity, Long>,JpaSpecificationExecutor<TestEntity>接口中的方法有默认实现,那接口中自定义的方法没写实现类,为什么也能正常工作???

下面译自spring-data官方文档,

原址为:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation

定义查询方法

存储库代理有两种方法从方法名派生特定于存储区的查询。它可以直接从方法名派生查询,或者使用手动定义的查询。可用选项取决于实际存储。但是,必须有一种策略来决定创建什么样的实际查询。让我们来看看可用的选项。 

直接从方法名派生查询

拿上面的作为例子:

TestEntity findByUserName(String userName);

该机制将前缀分隔为find…Byread…Byquery…Bycount…By,get…By去掉然后开始解析其余部分。

findByUserName去掉前缀则为UserName,该机制开始按照驼峰的命名方式从右往左开始解析,解析为User,Name,Name,解析完成后发现name并不是TestEntity中的属性,于是继续解析为UserName,而userName为TestEntity中的属性,所以生成了from TestEntity where userName=?的query语句。

如果解析到最后也没匹配,则会抛出异常在程序启动的时候。

附TestEntity实体代码:

@Entity
@Table(name = "T_TEST")
public class TestEntity implements Serializable {
/**

*/
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "username")
private String userName;

@Column(name = "password")
private String passWord;

@Column(name = "email")
private String email;

@Column(name = "mobile")
private String mobile;

@Column(name = "nickname")
private String nickName;

public TestEntity() {
super();
}

public TestEntity(String userName, String passWord) {
super();
this.userName = userName;
this.passWord = passWord;
}

/**
* @return id
*/
public Long getId() {
return id;
}

/**
* @param id 要设置的 id
*/
public void setId(Long id) {
this.id = id;
}

/**
* @return userName
*/
public String getUserName() {
return userName;
}

/**
* @param userName 要设置的 userName
*/
public void setUserName(String userName) {
this.userName = userName;
}

/**
* @return passWord
*/
public String getPassWord() {
return passWord;
}

/**
* @param passWord 要设置的 passWord
*/
public void setPassWord(String passWord) {
this.passWord = passWord;
}

/**
* @return email
*/
public String getEmail() {
return email;
}

/**
* @param email 要设置的 email
*/
public void setEmail(String email) {
this.email = email;
}

/**
* @return mobile
*/
public String getMobile() {
return mobile;
}

/**
* @param mobile 要设置的 mobile
*/
public void setMobile(String mobile) {
this.mobile = mobile;
}

/**
* @return nickName
*/
public String getNickName() {
return nickName;
}

/**
* @param nickName 要设置的 nickName
*/
public void setNickName(String nickName) {
this.nickName = nickName;
}

@Override
public String toString() {
return "TestEntity [id=" + id + ", userName=" + userName + ", passWord=" + passWord + ", email=" + email + ", mobile=" + mobile + ", nickName=" + nickName + "]";
}

}

完。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

myskybeyond

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值