虽然使用sPRing data jpa给开发带来了极大的简化,但对于追求更小更快的我们来说,要为每个实体都写一遍数据访问接口却仍显得过于繁琐。如果可以构建一个baseDao,里面配置好了基本的增删改查接口,其他的实体类来继承它,这样就会使我们的开发得到进一步的简化。
创建BaseRepository(baseDao)
@NoRepositoryBean //表示该接口不会创建这个接口的实例public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> { List<Object[]> listBySQL(String sql); /** * 保存实体 * * @param entity 实体id */ public void add(Object entity); /** * 更新实体 * * @param entity 实体id */ public void update(Object entity); /** * 删除实体 * * @param entityClass 实体类 * @param entityid 实体id */ public <T> void delete(Class<T> entityClass, Object entityid); /** * 删除实体 * * @param entityClass 实体类 * @param entityids 实体id数组 */ public <T> void delete(Class<T> entityClass, Object[] entityids); /** * 获取实体 * * @param <T> * @param entityClass 实体类 * @param entityId 实体id * @return */ public <T> T find(Class<T> entityClass, Object entityId);}创建实现类BaseRepositoryImpl
//Spring Data JPA都是调用SimpleJpaRepository来创建实例public class BaseRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> { //用于操作数据库 private final EntityManager em; //父类没有不带参数的构造方法,这里手动构造父类 public BaseRepositoryImpl(Class<T> domainClass, EntityManager entityManager) { super(domainClass, entityManager); this.em = entityManager; } //通过EntityManager来完成查询 @Override public List<Object[]> listBySQL(String sql) { return em.createNativeQuery(sql).getResultList(); } @Override public void add(Object entity) { em.persist(entity); } @Override public void update(Object entity) { em.merge(entity); } @Override public <T1> void delete(Class<T1> entityClass, Object entityid) { delete(entityClass, new Object[]{entityid}); } @Override public <T1> void delete(Class<T1> entityClass, Object[] entityids) { for (Object id : entityids) { em.remove(em.getReference(entityClass, id)); } } @Override public <T1> T1 find(Class<T1> entityClass, Object entityId) { return em.find(entityClass, entityId); }}创建一个自定义的工厂BaseRepositoryFactoryBean,在这个工厂中注册我们自己定义的BaseRepositoryImpl的实现。
public class BaseRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends JpaRepositoryFactoryBean<R, T, I> { /** * 接到factory之后,把factory扔了spring data jpa */ @Override protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) { return new BaseRepositoryFactory(em); } /** * //创建一个内部类,该类不用在外部访问 * 他的作用是将我们的baseReposity的实现类扔给factorybean * * @param <T> * @param <I> */ private static class BaseRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory { private final EntityManager em; public BaseRepositoryFactory(EntityManager em) { super(em); this.em = em; } /** * 通过这两个方法来确定具体的实现类,也就是Spring Data Jpa具体实例化一个接口的时候会去创建的实现类。 */ //设置具体的实现类是BaseRepositoryImpl @Override protected Object getTargetRepository(RepositoryInformation information) { return new BaseRepositoryImpl<T, I>((Class<T>) information.getDomainType(), em); } //设置具体的实现类的class @Override protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) { return BaseRepositoryImpl.class; } }}至此我们的扩展接口就算完成了,接下来只需要写自定义接口来实现它就好了。 创建StudentExtendsRepository实现BaseRepository
public interface StudentExtendsRepository extends BaseRepository<student, String> { //扩展的自定义方法 public student findById(String id);}创建服务控制类BaseController
import cn.entity.student;import cn.service.StudentExtendsRepository;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.transaction.annotation.EnableTransactionManagement;import org.springframework.transaction.annotation.Transactional;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import java.util.List;/** * 继承通用dao Created by shiyufeng on 2017/2/13. */@Transactional // 事务@RestController@EnableAutoConfiguration // 让 Spring Boot 根据应用所声明的依赖来对 Spring 框架进行自动配置@EnableTransactionManagement // 开启注解事务管理,等同于xml配置文件中的 <tx:annotation-driven />public class BaseController { @Resource private StudentExtendsRepository studentExtendsRepository; @RequestMapping("findStudentByBase") public String getStudent() { student student1 = studentExtendsRepository.find(student.class, "001"); return student1.toString(); } @RequestMapping("findStudentByBase2") public String getStudentAll() { List<student> student = studentExtendsRepository.findAll(); String a = ""; for (student studnet1 : student) { a = a + studnet1.toString(); } return a; } @RequestMapping("addStudent") public void addStudent() { student stu = new student(); // 自动生成id stu.setGrade("三年级"); stu.setName("addStudent"); studentExtendsRepository.add(stu); } @RequestMapping("updateStudent") public void updateStudent() { student stu = new student(); stu.setId("4"); stu.setGrade("update三年级"); stu.setName("updateStudent"); studentExtendsRepository.update(stu); } @RequestMapping("delStudent") public void delStudent() { studentExtendsRepository.delete(student.class, "4"); }}启动服务,访问BaseController里的映射对数据库进行简单操作。
新闻热点
疑难解答