前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot开发案例之整合Spring-data-jpa进阶篇

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

原创
作者头像
小柒2012
发布2018-03-30 18:12:38
1.1K1
发布2018-03-30 18:12:38
举报
文章被收录于专栏:IT笔记IT笔记

前言

有人说 从 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的核心概念图:

1190778-20171004143209911-1516587547.jpg
1190778-20171004143209911-1516587547.jpg
实现

班级表:

代码语言:txt
复制
@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;
	//忽略部分代码
}

学生表:

代码语言:txt
复制
@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:

代码语言:txt
复制
/**
 * 扩展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:

代码语言:txt
复制
/**
 * 动态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:

代码语言:txt
复制
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:

代码语言:txt
复制
@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;
	}

}

接口测试:

代码语言:txt
复制
@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测试

1.png
1.png

返回List< Object[] >:

2.png
2.png

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

3.png
3.png

返回List< Student >:

4.png
4.png

源码:https://gitee.com/52itstyle/spring-data-jpa

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 进阶查询
    • 需求:
      • 实现
      • Swagger2测试
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
      http://www.vxiaotou.com