Learning Spring-Data-Jpa (xiv) --- Custom Repository

  Sometimes, we need to customize the Repository to achieve some special business scenarios.

1, a single custom Repository

  1.1, a first segment interface and implementation (the default implementation of the interface to be used for the Impl suffix itself does not depend achieve spring-data, may be a conventional spring-bean, the bean can be injected into the other, e.g. JdbcTemplate).

/**
 * @author caofanqi
 */
public interface StudentRepositoryCustomJdbc {

    List<Student> findStudentByJdbcName(String name);

}


/**
 * Default To Impl end
 * @author caofanqi
 */
public class StudentRepositoryCustomJdbcImpl implements StudentRepositoryCustomJdbc {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Override
    public List<Student> findStudentByJdbcName(String name) {
        String sql = "SELECT * FROM cfq_jpa_student WHERE name = " + "'" + name + "'";
        return jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(Student.class));
    }

}

  1.2 Repository inherit their custom interface, you can use the expanded functions.

/**
 * Inheritance jpa the repository, and your own custom extensions
 * @author caofanqi
 */
public interface StudentRepository extends JpaRepositoryImplementation<Student,Long>, StudentRepositoryCustomJdbc {
}

  1.3, the test is as follows:

    @BeforeEach
    void setup(){
        Student s1 = Student.builder().name("张三").age(23).build();
        Student s2 = Student.builder().name("李四").age(24).build();
        Student s3 = Student.builder().name("王五").age(25).build();


        studentRepository.saveAll(Lists.newArrayList(s1,s2,s3));
    }

    @Test
    void testFindStudentByJdbcName(){
        List<Student> list = studentRepository.findStudentByJdbcName("张三");
        list.forEach(s -> System.out.println(s.getName()));
    }

  1.4, Print Console:

Hibernate: insert into cfq_jpa_student (age, name) values (?, ?)
Hibernate: insert into cfq_jpa_student (age, name) values (?, ?)
Hibernate: insert into cfq_jpa_student (age, name) values (?, ?)
Joe Smith

  1.5, you can have multiple custom extensions. Customize a higher priority than spring-data to us.

/**
 * Inheritance jpa the repository, and your own custom extensions
 * @author caofanqi
 */
public interface StudentRepository extends JpaRepositoryImplementation<Student,Long>, StudentRepositoryCustomJdbc,StudentRepositoryCustom<Student,Long> {
}
/**
 * Custom student function
 *
 * @author caofanqi
 */
public interface StudentRepositoryCustom<T,ID> {

    Optional<T> findById(ID id);

}


/**
 * Custom implementation repository function
 *
 * @author caofnqi
 */
@ slf4j
public class StudentRepositoryCustomImpl<T,ID> implements StudentRepositoryCustom<T,ID> {


    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Optional<T> findById(ID id) {
        log.info ( "Custom the findById" );
        T t = (T) entityManager.find(Student.class, id);
        return Optional.of(t);
    }
}

  

1.6, it can repositoryImplementationPostfix property @EnableJpaRepositories custom suffix, the default is Impl.

/**
 * Start class
 * @Author caofanqi
  * /
@SpringBootApplication
@EnableAsync
@EnableJpaRepositories(repositoryImplementationPostfix = "MyPostfix")
public class StudySpringDataJpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(StudySpringDataJpaApplication.class, args);
    }

}

 

 2, custom BaseRepository

  2.1, the proxy class SpringDataJpa provides us with the fact SimpleJpaRepository.  

  

  2.2, if we want to save all the operations are carried out Repository log, we can customize BaseRepository, to act as a proxy class. (Can also be a logical delete scenes)

    2.2.1, custom baseRepository

/**
 * Custom base Repository
 *
 * @Author caofanqi
  * /
@ slf4j
public class MyRepositoryImpl<T,ID> extends SimpleJpaRepository<T,ID> {

    private final EntityManager entityManager;

    MyRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
    }


    @Override
    public <S extends T> S save(S entity) {
        S save = super.save(entity);
        log.info("保存了:{}",save);
        return  save;
    }

}

  2.2.2 to inform the Spring-Data-Jpa use our custom baseRepository

/**
 * Start class
 * @Author caofanqi
  * /
@SpringBootApplication
@EnableAsync
@EnableJpaRepositories(
        /*queryLookupStrategy = QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND*/
     /*   ,repositoryImplementationPostfix = "MyPostfix",*/
        repositoryBaseClass = MyRepositoryImpl.class)
public class StudySpringDataJpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(StudySpringDataJpaApplication.class, args);
    }

}

  2.2.3 Test Method testSave again, as follows

  

 

 3, entityManager perform complex sql native returned DTO

  When using a method derived query and @Query notes queries, we can use the projector to object-oriented programming, but when executing complex native sql sql use entityManager, how to return the entity it? as follows:

  3.1、DTO

/**
 * Results entityManager map used, with the need to set a reference method is not a constructor, which is not the same as the projection
 * @Author caofanqi
  * /
@Data
@NoArgsConstructor
@AllArgsConstructor
public class StudentAgeAndAgeCountDTO {

    private Integer age;

    private Long ageCount;

}

  3.2、查询方法

    public List<StudentAgeAndAgeCountDTO> findCountGroupByAge(){

        /*
         *sql可以是更复杂的
         */
        String sql = "SELECT age,count(*) AS ageCount FROM cfq_jpa_student GROUP BY age ";

        Query nativeQuery = entityManager.createNativeQuery(sql);
        nativeQuery.unwrap(NativeQuery.class)
                //设置类型
                .addScalar("age", StandardBasicTypes.INTEGER)
                .addScalar("ageCount",StandardBasicTypes.LONG)
                //设置返回bean
                .setResultTransformer(Transformers.aliasToBean(StudentAgeAndAgeCountDTO.class));
        return nativeQuery.getResultList();

    }

  3.3、测试及结果 

 

 

 

 

源码地址:https://github.com/caofanqi/study-spring-data-jpa

Guess you like

Origin www.cnblogs.com/caofanqi/p/11974418.html