JpaRepository扩展接口

  • maven 依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
  •  BaseJpaRepository 
package com.demo;


import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;

import javax.persistence.EntityManager;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * ${DESCRIPTION}
 */

@NoRepositoryBean //接口不参与jpa的代理
public interface BaseJpaRepository<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T>, Serializable {

    EntityManager getEntityManager();

    <E> List<E> findByHql(String hql);


    List<Map<?,?>> findBySql(String sql);

    List<Map<?,?>> findBySql(String sql, Object[] params);

    List<Map<?,?>> findBySql(String sql, Map<String, Object> params);


    Map<?,?> findBySqlFirst(String sql);

    Map<?,?> findBySqlFirst(String sql, Object[] params);

    Map<?,?> findBySqlFirst(String sql, Map<String, Object> params);

    /**
     * basic == true 表示基本数据类型
     */
    <E> List<E> findBySql(String sql, Class<E> clazz, boolean basic);

    <E> List<E> findBySql(String sql, Class<E> clazz, boolean basic, Object[] params);

    <E> List<E> findBySql(String sql, Class<E> clazz, boolean basic, Map<String, Object> params);

    /**
     * 分页查询
     */
    <E> Page<E> findPageBySql(String sql, Pageable pageable, Class<E> clazz, boolean basic);

    <E> Page<E> findPageBySql(String sql, String countSql, Pageable pageable, Class<E> clazz, boolean basic);

    <E> Page<E> findPageBySql(String sql, Pageable pageable, Class<E> clazz, boolean basic, Object[] params);

    <E> Page<E> findPageBySql(String sql, String countSql, Pageable pageable, Class<E> clazz, boolean basic, Object[] params);

    <E> Page<E> findPageBySql(String sql, Pageable pageable, Class<E> clazz, boolean basic, Map<String, Object> params);

    <E> Page<E> findPageBySql(String sql, String countSql, Pageable pageable, Class<E> clazz, boolean basic, Map<String, Object> params);

    /**
     * basic == true 表示基本数据类型
     */
    <E> E findBySqlFirst(String sql, Class<E> clazz, boolean basic);

    <E> E findBySqlFirst(String sql, Class<E> clazz, boolean basic, Object[] params);

    <E> E findBySqlFirst(String sql, Class<E> clazz, boolean basic, Map<String, Object> params);

    T findByIdNew(ID id);

    /**
     * 批量插入
     */
    <S extends T> Iterable<S> batchSave(Iterable<S> iterable);

    /**
     * 批量更新
     */
    <S extends T> Iterable<S> batchUpdate(Iterable<S> iterable);


    void lazyInitialize(Class<T> entityClazz, List<T> l, String[] fields);

    void lazyInitialize(T obj, String[] fields);


}
  • BaseJpaRepositoryImpl
package com.demo;

import com.qtsec.demo.ApplicationContextProvider;
import org.hibernate.Hibernate;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.util.*;

/**
 * ${DESCRIPTION}
 */

@SuppressWarnings("unchecked")
public class BaseJpaRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements BaseJpaRepository<T, ID> {

	private static final long serialVersionUID = 5202242718223588507L;


	//批量更新时的阀值,每500条数据commit一次
    private static final Integer BATCH_SIZE = 500;


    //通过构造方法初始化EntityManager
    private final EntityManager entityManager;


    public BaseJpaRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
    }


    @Override
    public EntityManager getEntityManager() {
        return entityManager;
    }

	@Override
    public <E> List<E> findByHql(String hql) {
        return (List<E>) entityManager.createQuery(hql)
                .getResultList();
    }


    @Override
    public List<Map<?,?>> findBySql(String sql) {
        return findBySql(sql, new HashMap<>());
    }

	@Override
    public List<Map<?,?>> findBySql(String sql, Object[] params) {
        Query nativeQuery = entityManager.createNativeQuery(sql);
        if (params != null && params.length > 0) {
            for (int i = 0; i < params.length; i++) {
                nativeQuery.setParameter(i + 1, params[i]);
            }
        }
        return nativeQuery.unwrap(NativeQueryImpl.class)
                .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
                .getResultList();
    }

	@Override
    public List<Map<?,?>> findBySql(String sql, Map<String, Object> params) {
        Query nativeQuery = entityManager.createNativeQuery(sql);
        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                nativeQuery.setParameter(key, params.get(key));
            }
        }
        return nativeQuery.unwrap(NativeQueryImpl.class)
                .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
                .getResultList();
    }


    @Override
    public <E> List<E> findBySql(String sql, Class<E> clazz, boolean basic) {
        return findBySql(sql, clazz, basic, new HashMap<>());
    }

    @Override
    public <E> List<E> findBySql(String sql, Class<E> clazz, boolean basic, Object[] params) {
        return getJpaUtil().mapListToObjectList(findBySql(sql, params), clazz, basic);
    }

    @Override
    public <E> List<E> findBySql(String sql, Class<E> clazz, boolean basic, Map<String, Object> params) {
        return getJpaUtil().mapListToObjectList(findBySql(sql, params), clazz, basic);
    }

    @Override
    public <E> Page<E> findPageBySql(String sql, Pageable pageable, Class<E> clazz, boolean basic) {
        return findPageBySql(sql, pageable, clazz, basic, new HashMap<>());
    }

    @Override
    public <E> Page<E> findPageBySql(String sql, String countSql, Pageable pageable, Class<E> clazz, boolean basic) {
        return findPageBySql(sql, countSql, pageable, clazz, basic, new HashMap<>());
    }

    @Override
    public <E> Page<E> findPageBySql(String sql, Pageable pageable, Class<E> clazz, boolean basic, Object[] params) {
        return findPageBySql(sql, null, pageable, clazz, basic, params);
    }

	@Override
    public <E> Page<E> findPageBySql(String sql, String countSql, Pageable pageable, Class<E> clazz, boolean basic, Object[] params) {
        if (!sql.toLowerCase().contains("order by")) {
            StringBuilder stringBuilder = new StringBuilder(sql);
            stringBuilder.append(" order by ");
            final Sort sort = pageable.getSort();
            final List<Sort.Order> orders = sort.toList();
            for (Sort.Order order : orders) {
                stringBuilder.append(order.getProperty())
                        .append(" ")
                        .append(order.getDirection().name())
                        .append(",");
            }
            sql = stringBuilder.toString();
            sql = sql.substring(0, sql.length() - 1);
        }

        final Query nativeQuery = entityManager.createNativeQuery(sql);
        nativeQuery.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
        nativeQuery.setMaxResults(pageable.getPageSize());

        if (params != null && params.length > 0) {
            for (int i = 0; i < params.length; i++) {
                nativeQuery.setParameter(i + 1, params[i]);
            }
        }


        List<Map<?,?>> resultList = nativeQuery.unwrap(NativeQueryImpl.class)
                .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).getResultList();

        final List<E> objectList = getJpaUtil().mapListToObjectList(resultList, clazz, basic);

        if (!StringUtils.hasText(countSql)) {
            countSql = "select count(*) from ( " + sql + " ) a";
        }
        final BigInteger count = findBySqlFirst(countSql, BigInteger.class, true);

        Page<E> page = new PageImpl<>(objectList, pageable, count.longValue());

        return page;
    }

    @Override
    public <E> Page<E> findPageBySql(String sql, Pageable pageable, Class<E> clazz, boolean basic, Map<String, Object> params) {
        return findPageBySql(sql, null, pageable, clazz, basic, params);
    }

	@Override
    public <E> Page<E> findPageBySql(String sql, String countSql, Pageable pageable, Class<E> clazz, boolean basic, Map<String, Object> params) {
        if (!sql.toLowerCase().contains("order by")) {
            StringBuilder stringBuilder = new StringBuilder(sql);
            stringBuilder.append(" order by ");
            final Sort sort = pageable.getSort();
            final List<Sort.Order> orders = sort.toList();
            for (Sort.Order order : orders) {
                stringBuilder.append(order.getProperty())
                        .append(" ")
                        .append(order.getDirection().name())
                        .append(",");
            }
            sql = stringBuilder.toString();
            sql = sql.substring(0, sql.length() - 1);
        }

        final Query nativeQuery = entityManager.createNativeQuery(sql);
        nativeQuery.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
        nativeQuery.setMaxResults(pageable.getPageSize());

        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                nativeQuery.setParameter(key, params.get(key));
            }
        }


        List<Map<?,?>> resultList = nativeQuery.unwrap(NativeQueryImpl.class)
                .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).getResultList();

        final List<E> objectList = getJpaUtil().mapListToObjectList(resultList, clazz, basic);

        if (!StringUtils.hasText(countSql)) {
            countSql = "select count(*) from ( " + sql + " ) a";
        }
        final BigInteger count = findBySqlFirst(countSql, BigInteger.class, true);

        Page<E> page = new PageImpl<>(objectList, pageable, count.longValue());

        return page;
    }

    @Override
    public Map<?,?> findBySqlFirst(String sql) {
        return findBySqlFirst(sql, new HashMap<>());
    }

    @Override
    public Map<?,?> findBySqlFirst(String sql, Object[] params) {
        Query nativeQuery = entityManager.createNativeQuery(sql);
        if (params != null && params.length > 0) {
            for (int i = 0; i < params.length; i++) {
                nativeQuery.setParameter(i + 1, params[i]);
            }
        }
        final Optional<?> first = nativeQuery.unwrap(NativeQueryImpl.class)
                .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
                .stream().findFirst();
        if (first.isPresent()) {
            return (Map<?,?>) first.get();
        }
        return null;
    }

    @Override
    public Map<?,?> findBySqlFirst(String sql, Map<String, Object> params) {
        Query nativeQuery = entityManager.createNativeQuery(sql);
        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                nativeQuery.setParameter(key, params.get(key));
            }
        }
        final Optional<?> first = nativeQuery.unwrap(NativeQueryImpl.class)
                .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
                .stream().findFirst();
        if (first.isPresent()) {
            return (Map<?,?>) first.get();
        }
        return null;
    }


    @Override
    public <E> E findBySqlFirst(String sql, Class<E> clazz, boolean basic) {
        return findBySqlFirst(sql, clazz, basic, new HashMap<>());
    }

    @Override
    public <E> E findBySqlFirst(String sql, Class<E> clazz, boolean basic, Object[] params) {
        return getJpaUtil().mapToObject(findBySqlFirst(sql, params), clazz, basic);
    }

    @Override
    public <E> E findBySqlFirst(String sql, Class<E> clazz, boolean basic, Map<String, Object> params) {
        return getJpaUtil().mapToObject(findBySqlFirst(sql, params), clazz, basic);
    }

    @Override
    public T findByIdNew(ID id) {
        T t = null;

        if(id == null){
            return null;
        }

        Optional<T> optional = this.findById(id);
        if (optional.isPresent()) {
            t = optional.get();
        }

        return t;

    }


    @Override
    @Transactional
    public <S extends T> Iterable<S> batchSave(Iterable<S> iterable) {
        Iterator<S> iterator = iterable.iterator();
        int index = 0;
        while (iterator.hasNext()) {
            entityManager.persist(iterator.next());
            index++;
            if (index % BATCH_SIZE == 0) {
                entityManager.flush();
                entityManager.clear();
            }
        }
        if (index % BATCH_SIZE != 0) {
            entityManager.flush();
            entityManager.clear();
        }
        return iterable;
    }

    @Override
    @Transactional
    public <S extends T> Iterable<S> batchUpdate(Iterable<S> iterable) {
        Iterator<S> iterator = iterable.iterator();
        int index = 0;
        while (iterator.hasNext()) {
            entityManager.merge(iterator.next());
            index++;
            if (index % BATCH_SIZE == 0) {
                entityManager.flush();
                entityManager.clear();
            }
        }
        if (index % BATCH_SIZE != 0) {
            entityManager.flush();
            entityManager.clear();
        }
        return iterable;
    }


    @Override
    public void lazyInitialize(Class<T> entityClazz, List<T> l, String[] fields) {
        if (fields != null) {
            for (String field : fields) {

                String targetMethod = "get" + upperFirstWord(field);

                Method method;
                try {
                    method = entityClazz.getDeclaredMethod(targetMethod);
                    for (T o : l) {
                        Hibernate.initialize(method.invoke(o));
                    }
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    @Override
    public void lazyInitialize(T obj,
                               String[] fields) {
        if (obj != null) {
            if (fields != null) {
                for (String field : fields) {

                    String targetMethod = "get" + upperFirstWord(field);

                    Method method;
                    try {
                        method = obj.getClass().getDeclaredMethod(targetMethod);
                        Hibernate.initialize(method.invoke(obj));
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
            }
        }
    }

    private String upperFirstWord(String str) {
        StringBuffer sb = new StringBuffer(str);
        sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
        return sb.toString();
    }

    private JpaUtil getJpaUtil() {
        JpaUtil objectUtil = (JpaUtil) ApplicationContextProvider.getBean("jpaUtil");
        return objectUtil;
    }

}
  •  ApplicationContextProvider
package com.demo;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;

/**
 * ${DESCRIPTION}
 */


@Component
public class ApplicationContextProvider
        implements ApplicationContextAware {
    /**
     * 上下文对象实例
     */
    private static ApplicationContext applicationContext;

    /**
     * 获取applicationContext
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextProvider.applicationContext = applicationContext;
    }

    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }


    /**
     * 描述 : <获得多语言的资源内容>. <br>
     * <p>
     * <使用方法说明>
     * </p>
     *
     * @param code
     * @param args
     * @return
     */
    public static String getMessage(String code, Object[] args) {
        return getApplicationContext().getMessage(code, args, LocaleContextHolder.getLocale());
    }

    /**
     * 描述 : <获得多语言的资源内容>. <br>
     * <p>
     * <使用方法说明>
     * </p>
     *
     * @param code
     * @param args
     * @param defaultMessage
     * @return
     */
    public static String getMessage(String code, Object[] args,
                                    String defaultMessage) {
        return getApplicationContext().getMessage(code, args, defaultMessage,
                LocaleContextHolder.getLocale());
    }
}
  • JpaUtil
package com.demo;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * ${DESCRIPTION}
 */

@Component("jpaUtil")
@Slf4j
public class JpaUtil {

    @Autowired
    ObjectMapper objectMapper;

    /**
     * 查询结果为List<Map>时,可以通过该方法转换为对象List,注意Map中key要与对象属性匹配,或者对象属性标注了@JsonProperty
     */
    @SuppressWarnings("unchecked")
	public <E> List<E> mapListToObjectList(List<Map<?,?>> mapList, Class<E> clazz, boolean basic) {

        List<E> list = new ArrayList<>();
        for (Map<?,?> map : mapList) {
            if (basic) {
                list.add((E)map.values().stream().findFirst().get());

            } else {
                try {
                    final String valueAsString = objectMapper.writeValueAsString(map);
                    E newInstance = (E) objectMapper.readValue(valueAsString, clazz);
                    list.add(newInstance);
                } catch (JsonProcessingException e) {
                    log.error("",e);
                }
            }
        }
        return list;
    }

    /**
     * 查询结果为Map时,可以通过该方法转换为对象,注意Map中key要与对象属性匹配,或者对象属性标注了@JsonProperty
     */
    @SuppressWarnings("unchecked")
	public <E> E mapToObject(Map<?,?> map, Class<E> clazz, boolean basic) {
        if(map == null){
            return null;
        }
        E newInstance = null;
        //基本类型,说明返回值只有一列
        if (basic) {
            newInstance =  (E) map.values().stream().findFirst().get();

        } else {
            try {
                final String valueAsString = objectMapper.writeValueAsString(map);
                newInstance = (E) objectMapper.readValue(valueAsString, clazz);
            } catch (JsonProcessingException e) {
                log.error("",e);
            }
        }
        return newInstance;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您的问题是如何使用Spring Boot JPA实现增删查改等常规操作。以下是针对您提供的数据库表的一个基本示例: 首先,您需要定义一个名为Student的实体类,包含对应的属性和构造函数、getter和setter方法。例如: ``` @Entity @Table(name = "Students") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "StuNum", nullable = false, unique = true) private int stuNum; @Column(name = "Id", nullable = false) private int id; @Column(name = "StuName", nullable = false) private String stuName; @Column(name = "Address", nullable = false) private String address; public Student(int id, int stuNum, String stuName, String address) { this.id = id; this.stuNum = stuNum; this.stuName = stuName; this.address = address; } // getters and setters } ``` 其中,@Entity注解表示这是一个实体类,@Table注解表示对应的数据库表名。@Id注解表示该属性是表中的主键,@GeneratedValue注解表示该主键使用自动增长的方式生成,@Column注解表示对应的列名。 接下来,您需要定义一个名为StudentRepository接口,继承自JpaRepository。例如: ``` @Repository public interface StudentRepository extends JpaRepository<Student, Integer> { } ``` 其中,@Repository注解表示这是一个Spring组件,@JpaRepository注解表示这是一个继承自JpaRepository接口,其中Student对应的是实体类,Integer对应的是主键的类型。 最后,您可以在需要使用增删查改等操作的地方注入StudentRepository,使用对应的方法进行操作。例如: ``` @RestController public class StudentController { @Autowired private StudentRepository studentRepository; // 添加学生 @PostMapping("/students") public Student addStudent(@RequestBody Student student) { return studentRepository.save(student); } // 根据学号删除学生 @DeleteMapping("/students/{stuNum}") public void deleteStudent(@PathVariable int stuNum) { studentRepository.deleteById(stuNum); } // 根据学号查询学生 @GetMapping("/students/{stuNum}") public Student getStudent(@PathVariable int stuNum) { return studentRepository.findById(stuNum).orElse(null); } // 修改学生信息 @PutMapping("/students") public Student updateStudent(@RequestBody Student student) { return studentRepository.save(student); } } ``` 其中,@RestController注解表示这是一个可以对外提供RESTful接口的组件,@Autowired注解表示这是一个需要注入的Spring组件。通过调用StudentRepository的对应方法,实现了增删查改等常规操作。 这仅仅是一个基本的示例,您可以根据具体需求进行扩展和修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值