一直搞不懂栋哥的各类EQ啊EXIST啊什么的,说实话,我很是讨厌数据库和sql...sql
可是,逃不掉的,必需要看懂了 /(ㄒoㄒ)/~~数据库
先来一张图app
首先,咱们须要继承以加入框架框架
servicethis
@Service public class UserService extends DcBaseService<User> { @Autowired private UserRepo userRepo; }
repodebug
public interface UserRepo extends DcJpaRepository<User, String> { }
service 和 repo 层的代码几乎什么都不用写。code
这里来看一次分页的过程。继承
UserService
调用父类 DcBaseService
的 queryPage
方法。接口
DcJpaRepository
代码图片
@NoRepositoryBean public interface DcJpaRepository<T, PK extends Serializable> extends JpaRepository<T, PK> { Page<T> queryPage(DcQuery var1); }
DcBaseService
代码
@Transactional public class DcBaseService<T extends IDAble> { @Autowired private DcJpaRepository<T, String> dcJpaRepository; public Page<T> queryPage(DcQuery dcQuery) { return this.dcJpaRepository.queryPage(dcQuery); } }
DcBaseService
中的queryPage
方法中调用了自动注入的 dcJpaRepository
实例,但这个实例究竟是什么呢?
回头来看,UserService
中的 userRepo
也是自动注入的。
对于dcJpaRepository
和userRepo
, userRepo
的类型是dcJpaRepository
的子类,User
也能够当作T
的子类, 那么,这二者应该是同一个实例,即子类实例userRepo
,但userRepo
的类型是接口,它的实例从哪来?
因而开始debug,两种状况以下
UserService
自有方法
UserController
@GetMapping("/123") public void getAll(@PageableDefault Pageable page) { System.out.println(ticketService.ticketRepo); ticketService.findAllabc(); // ticketService.queryPage(null); }
UserService
public void findAllabc() { System.out.println(this.ticketRepo); }
因而可知,实例类型为DcJpaRepositorySupport
,顺便看到了 Spring 的依赖,是在方法调用须要时才注入(想一想都是一个很复杂的过程)。
DcBaseService
父类方法
UserController
@GetMapping("/123") public void getAll(@PageableDefault Pageable page) { System.out.println(ticketService.ticketRepo); // ticketService.findAllabc(); ticketService.queryPage(null); }
DcBaseService
public Page<T> queryPage(DcQuery dcQuery) { return this.dcJpaRepository.queryPage(dcQuery); }
如图,实例类型仍是DcJpaRepositorySupport
。
经过以上两种状况,查看这个DcJpaRepositorySupport
源码以下
public class DcJpaRepositorySupport<T, PK extends Serializable> extends SimpleJpaRepository<T, PK> implements DcJpaRepository<T, PK> { public Page<T> queryPage(DcQuery dcQuery) { return this.findAll(.......); } }
Ok,再回头看最初的类图,推论以下:
正如直接写UserRepo
继承JpaRepository
同样,后者定义的方法,如findOne
,是由SimpleJpaRepository
类来实现的。 queryPage
是由DcJpaRepository
接口定义,DcJpaRepositorySupport
实现的。
由于多态,Spring 能够经过类型自动注入子类实例,而这个实现类,必然加持@Repository
注解(或其它), 之因此DcJpaRepositorySupport
能够被注入,是由于它继承了SimpleJpaRepository
。
若是没有自定义的Repository
实现,继承DcBaseService
的 service 能够不用再注入任何 xxxRepo
,由于 Spring 根本就不会找上门来。