转载

SpringBoot开发案例之整合Spring-data-jpa进阶篇

SpringBoot开发案例之整合Spring-data-jpa进阶篇

前言

有人说 从 jdbc->jdbctemplate->hibernation/mybatis 再到 jpa,真当开发人员的学习时间不要钱?我觉得到 h/m 这一级的封装已经有点过了,再往深处走就有病了。

还有人说JPA 很反人类(一个面试官),还举了一个很简单举了例子说:一个数据库如果有 50 个字段,那你写各种条件查询不是要写很多?就是应该用类似 SQL 的方式来查询啊?

其实在我看来,存在即合理,人们总是向着好的方向去发展,学习什么不需要成本,底层语言牛逼倒是去学啊,不还是看不懂,弄不明白。很多知识对于程序员来说,都是一通百通,查询文档就是了,最主要的是能方便以后的开发即可。

对于反人类这一说,只能说 to young to simple,JPA的初衷肯定也不会是让你写一个几十个字段的查询,顶多一到两个而已,非要这么极端?再说JPA也是提供了EntityManager来实现SQL或者HQL语句查询的不是,JPA本质上还是集成了Hibernate的很多优点的。

进阶查询

需求:

学生表(app_student)、班级表(app_class)、当然表结构比较简单,比如这时候我们需要查询学生列表,但是需要同时查询班级表的一些数据,并以JSON或者实体的方式返回给调用者。

本次需求,主要实现JPA的以下几个特性:

  • 封装EntityManager基类
  • 多表查询返回一个List
  • 多表查询返回一个Map
  • 多表查询返回一个实体

Entitymanager的核心概念图:

SpringBoot开发案例之整合Spring-data-jpa进阶篇

实现

班级表:

@Entity
@Table(name = "app_class")
public class AppClass {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id", nullable = false)
	private Integer id;
	private String className;
	private String teacherName;
	//忽略部分代码
}

学生表:

@Entity
@Table(name = "app_student")
public class AppStudent {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id", nullable = false)
	private Integer id;
	private Integer classId;
	private String name;
	private Integer age;
	//忽略部分代码
}

封装接口 DynamicQuery:

/**
 * 扩展SpringDataJpa, 支持动态jpql/nativesql查询并支持分页查询
 * 使用方法:注入ServiceImpl
 * 创建者 张志朋
 * 创建时间	2018年3月8日
 */
public interface DynamicQuery {

	public void save(Object entity);

	public void update(Object entity);

	public <T> void delete(Class<T> entityClass, Object entityid);

	public <T> void delete(Class<T> entityClass, Object[] entityids);
	
	 /**
     * 查询对象列表,返回List
     * @param resultClass
     * @param nativeSql
     * @param params
     * @return  List<T>
     * @Date	2018年3月15日
     * 更新日志
     * 2018年3月15日  张志朋  首次创建
     *
     */
	<T> List<T> nativeQueryList(String nativeSql, Object... params);
	
	 /**
     * 查询对象列表,返回List<Map<key,value>>
     * @param nativeSql
     * @param params
     * @return  List<T>
     * @Date	2018年3月15日
     * 更新日志
     * 2018年3月15日  张志朋  首次创建
     *
     */
	<T> List<T> nativeQueryListMap(String nativeSql,Object... params);

	 /**
     * 查询对象列表,返回List<组合对象>
     * @param resultClass
     * @param nativeSql
     * @param params
     * @return  List<T>
     * @Date	2018年3月15日
     * 更新日志
     * 2018年3月15日  张志朋  首次创建
     *
     */
	<T> List<T> nativeQueryListModel(Class<T> resultClass, String nativeSql, Object... params);

}

封装实现 DynamicQueryImpl:

/**
 * 动态jpql/nativesql查询的实现类
 * 创建者 张志朋
 * 创建时间	2018年3月8日
 */
@Repository
public class DynamicQueryImpl implements DynamicQuery {

	Logger logger = LoggerFactory.getLogger(DynamicQueryImpl.class);

	@PersistenceContext
	private EntityManager em;

	public EntityManager getEntityManager() {
		return em;
	}

	@Override
	public void save(Object entity) {
		em.persist(entity);
	}

	@Override
	public void update(Object entity) {
		em.merge(entity);
	}

	@Override
	public <T> void delete(Class<T> entityClass, Object entityid) {
		delete(entityClass, new Object[] { entityid });
	}

	@Override
	public <T> void delete(Class<T> entityClass, Object[] entityids) {
		for (Object id : entityids) {
			em.remove(em.getReference(entityClass, id));
		}
	}
	private Query createNativeQuery(String sql, Object... params) {
		Query q = em.createNativeQuery(sql);
		if (params != null && params.length > 0) {
			for (int i = 0; i < params.length; i++) {
				q.setParameter(i + 1, params[i]); // 与Hiberante不同,jpa
													// query从位置1开始
			}
		}
		return q;
	}
	@SuppressWarnings("unchecked")
	@Override
	public <T> List<T> nativeQueryList(String nativeSql, Object... params) {
		Query q = createNativeQuery(nativeSql, params);
		q.unwrap(SQLQuery.class).setResultTransformer(Transformers.TO_LIST);
		return q.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public <T> List<T> nativeQueryListModel(Class<T> resultClass,
			String nativeSql, Object... params) {
		Query q = createNativeQuery(nativeSql, params);;
		q.unwrap(SQLQuery.class).setResultTransformer(Transformers.aliasToBean(resultClass));
		return q.getResultList();
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> List<T> nativeQueryListMap(String nativeSql, Object... params) {
		Query q = createNativeQuery(nativeSql, params);
		q.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		return q.getResultList();
	}

}

业务 IStudentService:

public interface IStudentService {
	 /**
	  * 返回List<Object[]>
	  * @Author  科帮网
	  * @return  List<Object[]>
	  * @Date	2018年3月28日
	  * 更新日志
	  * 2018年3月28日  科帮网 首次创建
	  *
	  */
	 List<Object[]> listStudent();
	 /**
	  * 返回List<Student>
	  * @Author  科帮网
	  * @return  List<Student>
	  * @Date	2018年3月28日
	  * 更新日志
	  * 2018年3月28日  科帮网 首次创建
	  *
	  */
     List<Student> listStudentModel();
     /**
      * List<Map<Object, Object>>
      * @Author  科帮网
      * @return  List<Map<Object,Object>>
      * @Date	2018年3月28日
      * 更新日志
      * 2018年3月28日  科帮网 首次创建
      *
      */
     List<Map<Object, Object>> listStudentMap();
}

业务实现 StudentServiceImpl:

@Service
public class StudentServiceImpl implements IStudentService {

	@Autowired
	private DynamicQuery dynamicQuery;
	
	
	@Override
	public List<Object[]> listStudent() {
		String nativeSql = "SELECT s.id AS studentId,c.id AS classId,c.class_name AS className,c.teacher_name AS teacherName,s.name,s.age FROM app_student s,app_class c";
		List<Object[]> list = dynamicQuery.nativeQueryList(nativeSql, new Object[]{});
		return list;
	}
	
	@Override
	public List<Student> listStudentModel() {
		String nativeSql = "SELECT s.id AS studentId,c.id AS classId,c.class_name AS className,c.teacher_name AS teacherName,s.name,s.age FROM app_student s,app_class c";
		List<Student> list = dynamicQuery.nativeQueryListModel(Student.class, nativeSql, new Object[]{});
		return list;
	}

	@Override
	public List<Map<Object,Object>> listStudentMap() {
		String nativeSql = "SELECT s.id AS studentId,c.id AS classId,c.class_name AS className,c.teacher_name AS teacherName,s.name,s.age FROM app_student s,app_class c";
		List<Map<Object,Object>> list = dynamicQuery.nativeQueryListMap(nativeSql, new Object[]{});
		return list;
	}

}

接口测试:

@Api(tags ="测试接口")
@RestController
@RequestMapping("/test")
public class StudentController {
	private final static Logger LOGGER = LoggerFactory.getLogger(StudentController.class);
	
	@Autowired
	private IStudentService studentService;
	
	@ApiOperation(value="学生List")
	@PostMapping("/list")
	public Result list(HttpServletRequest request){
		LOGGER.info("学生List");
		List<Object[]> list = studentService.listStudent();
		return Result.ok(list);
	}
	@ApiOperation(value="学生Map")
	@PostMapping("/listMap")
	public Result listMap(HttpServletRequest request){
		LOGGER.info("学生Map");
		List<Map<Object, Object>> list = studentService.listStudentMap();
		return Result.ok(list);
	}
	@ApiOperation(value="学生Model")
	@PostMapping("/listModel")
	public Result listModel(HttpServletRequest request){
		LOGGER.info("学生Model");
		List<Student> list = studentService.listStudentModel();
		return Result.ok(list);
	}
}

Swagger2测试

SpringBoot开发案例之整合Spring-data-jpa进阶篇

返回List< Object[] >:

SpringBoot开发案例之整合Spring-data-jpa进阶篇

返回List< Map< Object, Object > >:

SpringBoot开发案例之整合Spring-data-jpa进阶篇

返回List< Student >:

SpringBoot开发案例之整合Spring-data-jpa进阶篇

SpringBoot开发案例之整合Spring-data-jpa进阶篇
SpringBoot开发案例之整合Spring-data-jpa进阶篇

作者:小柒

出处: https://blog.52itstyle.com

分享是快乐的,也见证了个人成长历程,文章大多都是工作经验总结以及平时学习积累,基于自身认知不足之处在所难免,也请大家指正,共同进步。

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 如有问题, 可邮件(345849402@qq.com)咨询。

原文  https://blog.52itstyle.com/archives/2582/
正文到此结束
Loading...