目录
那些坑
本猿最近因需求要做一个Spring Boot项目,封装一个BaseDao继承JpaRepository、JpaSpecificationExecutor,然后其他的dao接口继承BaseDao类而省代码。忽然脑一抽就把其他的dao接口除了继承BaseDao还继承了JpaRepository、JpaSpecificationExecutor。然后配置完了一运行就一直报我的serviceImpl那个父类实现类basedao未注入、找不到。
经过我一番的debug发现我还是来到运行控制台的报错地方,此时觉得spring工程的可配置文件它不香吗?非得和SpringBoot刚!!!

少说虚话,多做正事。各位兄die准备起飞!!!
工具:IDEA
创建工程
首先创建一个Spring Boot工程,在此提供一些之前创建的项目过程参考一下。




配置application.yml

server:
port: 8081
tomcat:
uri-encoding: UTF-8
servlet:
context-path: /private_kitechen
spring:
datasource:
url: jdbc:mysql://localhost:3306/myreport?useUnicode=true&characterEncoding=utf-8&useLegacyDatetimeCode=false&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password:
jpa:
database-platform: org.hibernate.dialect.MySQL5Dialect
show-sql: true
http:
encoding:
force: true
charset: UTF-8
enabled: true
搭建基本包
我们的包创建跟项目启动文件(private_kitchen)同一目录。

配置启动类等相关配置
注意这里的注解上的路径是实测可以扫描到的。

package com.study.it.private_kitchen;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import javax.annotation.PostConstruct;
import java.util.TimeZone;
@SpringBootApplication
@ComponentScan(basePackages = "com.study.it.*")
@EntityScan("com.study.it.entity")
@EnableJpaRepositories("com.study.it.dao")
public class PrivateKitchenApplication {
// 当时时区,本猿的电脑也是脑抽时区相差12小时
@PostConstruct
void started(){
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
// 启动类
public static void main(String[] args) {
SpringApplication.run(PrivateKitchenApplication.class, args);
}
}
ServletInitializer类

把实体类连爬带滚给拖进来
还要配置实体类里面


配置父接口BaseDao

package com.study.it.base;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.io.Serializable;
public interface BaseDao<T> extends JpaRepository<T, Serializable>, JpaSpecificationExecutor<T> {
}
配置其他dao接口继承BaseDao
这样有自定义的方法也可以加入里面去。

配置父接口BaseService
这个接口定义增删改查、分页等等的公用方法

package com.study.it.service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import java.io.Serializable;
import java.util.List;
public interface BaseService<T> {
void add(T o);
void edit(T o);
void remove(Serializable id);
List<T> findAll();
T findById(Serializable id);
T findOne(Specification<T> dc);
List<T> findList(Specification<T> dc);
Page<T> findPage(Specification<T> dc, Pageable pp);
long findCount(Specification<T> dc);
}
配置其他service继承BaseService

package com.study.it.service;
import com.study.it.entity.Admin;
public interface AdminService extends BaseService<Admin> {
}
配置父实现类BaseServiceImpl

package com.study.it.service.impl;
import com.study.it.base.BaseDao;
import com.study.it.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.List;
//不能写@Service,因为这个是当父类用的,帮子类节约代码,子类才是真正出场的对象
public abstract class BaseServiceImpl<T> implements BaseService<T> {
@Autowired
protected BaseDao<T> dao;
@Override
@Transactional
public void add(T o) {
dao.save(o);
}
@Override
@Transactional
public void edit(T o) {
dao.save(o);
}
@Override
@Transactional
public void remove(Serializable id) {
dao.deleteById(id);
}
@Override
@Transactional(readOnly = true)
public List<T> findAll() {
return dao.findAll();
}
@Override
@Transactional(readOnly = true)
public T findById(Serializable id) {
return dao.getOne(id);
}
@Override
@Transactional(readOnly = true)
public T findOne(Specification<T> dc) {
return dao.findOne(dc).get();
/* Optional<T> one = dao.findOne(dc);
if(one.isPresent())
return one.get();//返回一个特殊类型,用get()取回对象
return null;*/
}
@Override
@Transactional(readOnly = true)
public List<T> findList(Specification<T> dc) {
return dao.findAll(dc);
}
@Override
@Transactional(readOnly = true)
public Page<T> findPage(Specification<T> dc, Pageable pp) {
return dao.findAll(dc,pp);
}
@Override
@Transactional(readOnly = true)
public long findCount(Specification<T> dc) {
return dao.count(dc);
}
}
配置其他实现类serviceImpl继承BaseServiceImpl

package com.study.it.service.impl;
import com.study.it.dao.AdminDao;
import com.study.it.entity.Admin;
import com.study.it.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("adminservice")
public class AdminServiceImpl extends BaseServiceImpl<Admin> implements AdminService {
@Autowired
private AdminDao adminDao;
}

最后奉上spring Boot的模糊查询并分页的小例子
这个一个根据关键字查询Teacher集合。
@RequestMapping(value = "/findall", method = RequestMethod.POST)
public Page<Teacher> selectAll(
@RequestParam(value = "page", defaultValue = "1") int page
, String subject
){
Specification<Teacher> dc = new Specification<Teacher>() {
@Override
public Predicate toPredicate(
Root<Teacher> root
, CriteriaQuery<?> query
, CriteriaBuilder cb
) {
List<Predicate> cdts = new ArrayList<>();
if (subject != null && !subject.isEmpty()){
cdts.add(cb.like(root.get("subjects"), "%" + subject + "%"));
}
return cb.and(cdts.toArray(new Predicate[cdts.size()]));
}
};
Pageable pb =
PageRequest.of(page - 1, 10, Sort.by(Sort.Order.desc("id")));
return service.findPage(dc, pb);
}
结束


1166





