Spring Data Jpa自定义关联查询,可以使用原生SQL,也可以使用JPQL语法。
原生SQL返回数组对象List<Object[]>
;JPQL返回自定义对象List<ViewUserInfo>
ViewUserInfo.java
/**
* 自定义实体
*/
public class ViewUserInfo {
//table: user info
private Integer id;
private String name;
private String username;
//table: role
private long roleId;
//table: permission
private String url;
private String permission;
public ViewUserInfo(){
}
//构造函数,JPQL自定义查询将引用
public ViewUserInfo(int userId,String username,String name,
long roleid,String url,String permission){
this.id=userId;
this.username=username;
this.name=name;
this.roleId= roleid;
this.url=url;
this.permission=permission;
}
set,get...
}
JpaUserRepository.java
//查询方法定义 SQL
@Query(value = "select "
+" a.id as userId,a.username,a.name,b.role_id as roleId,d.url,d.permission "
+" from user_info a, sys_user_role b, sys_role_permission c,sys_permission d "
+" where a.id=b.u_id and b.role_id=c.role_id and c.permission_id=d.id",
nativeQuery = true)//原生SQL
public List<Object[]> findByNameSQL(String name);
//查询方法定义 JPQL
@Query(value = "select new com.test.demo.model.ViewUserInfo("
+" a.id,a.username,a.name,b.roleid,c.url,c.permission ) "
+" from JpaUser a, SysUserRole b, SysPermission c "
+" where a.id=b.uid and b.roleid=c.id")
public List<ViewUserInfo> findByName(String name);
JpaController.java
//原生SQL
@RequestMapping("/jpa/getSql")
public String getNameSql(Model model, @RequestParam String name) {
List<Object[]> users = userRepository.findByNameSQL(name);
for(Object[] objs : users){
System.out.println("----");
for(int i = 0,j=objs.length; i < j; i++){
System.out.println("--"+objs[i]);
}
}
model.addAttribute("users", users);
return "/jpa/listSql";
}
//JPQL
@RequestMapping("/jpa/getJpql")
public String getName(Model model, @RequestParam String name) {
List<ViewUserInfo> users = userRepository.findByName(name);
for(ViewUserInfo user : users){
System.out.println("----");
System.out.println("----"+user.getName());
System.out.println("----"+user.getUrl());
}
model.addAttribute("users", users);
return "/jpa/listJpql";
}
JPQL自定义语法中的对象是对应每个表的JOPO,不再逐一罗列
SysUserRole.java
@Entity
@Table(name = "sys_user_role")
public class SysUserRole {
@Id
private Integer id;
@Column(name="role_id")
private Long roleid;
@Column(name="u_id")
private Long uid;
get,set...
}
listSql.html文件路径为main\resources\templates\jpa,注意css的引入路径
同时thymeleaf遍历数组 List<Object[]的写法
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>用户角色列表-userRoleList</title>
<link rel="stylesheet" th:href="@{../css/bootstrap.css}" />
</head>
<body class="container">
<br/>
<h1>用户角色列表</h1>
<br/><br/>
<div class="with:80%">
<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<th>账号</th>
<th>昵称</th>
<th>角色ID</th>
<th>url</th>
<th>permission</th>
</tr>
</thead>
<tbody>
<!--遍历数组 List<Object[]> -->
<!--与ViewUserInfo构造方法中的参数顺序保持一致-->
<!--userId, username, name, roleid, url, permission-->
<tr th:each="user,itemStat:${users}">
<th scope="row" th:text="${itemStat.count}">1</th>
<td th:text="${user[1]}">.</td>
<td th:text="${user[2]}">.</td>
<td th:text="${user[3]}">.</td>
<td th:text="${user[4]}">.</td>
<td th:text="${user[5]}">.</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
测试
调用controler中的方法http://cos6743:8081/jpa/getJpql?name=test11
eclipse控制台
网页
调用controler中的方法http://cos6743:8081/jpa/getSql?name=test11