spring-data-jpa通用dao的扩展

虽然使用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里的映射对数据库进行简单操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值