如何连接两个表并在JPA中显示?
TABLES:
用户
+----+----------+----------+-----------+
| id | username | password | userlevel |
+----+----------+----------+-----------+
| 1 | you | you | 1 |
| 2 | me | me | 2 |
| 3 | we | we | 3 |
| 4 | us | us | 1 |
+----+----------+----------+-----------+
User_level
+------+--------+
| id | level |
+------+--------+
| 1 | Admin |
| 2 | Leader |
| 3 | Member |
+------+--------+
类:
User.java
package com.taskmanagement.entities;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
@Table(name = "USER")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String username;
private String password;
private int userlevel;
public User() {
}
public User(int id, String username, String password, int userlevel) {
this.username = username;
this.password = password;
this.userlevel = userlevel;
}
public int getId() {
return id;
}
public String getUserName() {
return username;
}
public void setUserName(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getUserLevel() {
return userlevel;
}
public void setUserLevel(int userlevel) {
this.userlevel = userlevel;
}
@Override
public String toString() {
return "User" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", userlevel='" + userlevel + '\'';
}
}
UserService.java
package com.taskmanagement.service;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import com.taskmanagement.entities.User;
import java.util.List;
public class UserService {
private EntityManager em;
public UserService(EntityManager em) {
this.em = em;
}
public User addUser(int id, String username, String password, UserLevel userlevel) {
User user = new User(id, username, password, userlevel);
em.persist(user);
em.flush();
return user;
}
public List<User> findAllUser() {
TypedQuery<User> query = em.createQuery("SELECT u.username,u.password,ul.level FROM User u JOIN u.user_level ul", User.class);
return query.getResultList();
}
}
Client.java
package com.taskmanagement.client;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import com.taskmanagement.entities.User;
import com.taskmanagement.service.UserService;
import java.util.List;
public class Client {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("TaskManagement");
EntityManager em = emf.createEntityManager();
UserService service = new UserService(em);
User user = new User();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
User userservice = service.addUser(user.getId(),"Username","Password","xxx");
//System.out.println("Latest id: "+userservice.getId());
transaction.commit();
System.out.println(String.format("Persisted: %s\n", userservice));
System.out.println("--- Find all Users---");
List<User> userservices = service.findAllUser();
for (User foundUser : userservices) {
System.out.println(String.format("Found: %s\n", foundUser));
}
}
}
我想显示加入user_level表的所有用户,以便显示用户以及用户的级别。
更新
我发现了这个错误,我不知道它为什么不起作用:
Exception in thread "main" java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: user_level of: com.taskmanagement.entities.User [SELECT u.username,u.password,ul.level FROM com.taskmanagement.entities.User u JOIN u.user_level ul]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:350)
at com.taskmanagement.service.UserService.findAllUser(UserService.java:48)
at com.taskmanagement.client.Client.main(Client.java:35)
Caused by: org.hibernate.QueryException: could not resolve property: user_level of: com.taskmanagement.entities.User [SELECT u.username,u.password,ul.level FROM com.taskmanagement.entities.User u JOIN u.user_level ul]
at org.hibernate.QueryException.generateQueryException(QueryException.java:137)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:120)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:234)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:131)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:93)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1836)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:342)
... 2 more
Caused by: org.hibernate.QueryException: could not resolve property: user_level of: com.taskmanagement.entities.User
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:77)
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1978)
at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:367)
at org.hibernate.hql.internal.ast.tree.FromElement.getPropertyType(FromElement.java:500)
at org.hibernate.hql.internal.ast.tree.DotNode.getDataType(DotNode.java:671)
at org.hibernate.hql.internal.ast.tree.DotNode.prepareLhs(DotNode.java:275)
at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:219)
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:126)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:393)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3903)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3689)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3567)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:708)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:564)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
... 10 more
答案 0 :(得分:0)
我相信好的设计会决定你应该为User_level
表确实有一个单独的实体类:
@Entity
@Table(name = "USER_LEVEL")
public class UserLevel {
@OneToMany (mappedBy="userLevel")
private Set<User> users;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String level;
public UserLevel() {
}
public UserLevel(int id, String level) {
this.id = id;
this.level = level;
}
public Set<User> getUsers() {
return users;
}
public int getId() {
return id;
}
public String getLevel() {
return level;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public void setId(int id) {
this.id = id;
}
public void setLevel(String level) {
this.level = level;
}
}
接下来应更新User
实体类,以引用上面为用户级别创建的实体,而不是原始字段。
@Entity
@Table(name = "USER")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String username;
private String password;
@ManyToOne
@JoinColumn(name="id") // 'id' is the foreign key in the UserLevel table
private UserLevel userLevel; // reference the entity class
public User() {
}
// getters and setters omitted for brevity
public UserLevel getUserLevel() {
return userLevel;
}
public void setUserLevel(UserLevel userLevel) {
this.userLevel = userLevel;
}
}
完成这些更改后,您可以轻松地执行要获取结果的连接查询:
String theQuery = "SELECT u, ul FROM User u JOIN u.userLevel ul";
TypedQuery<Object[]> query = entityManager.createQuery(theQuery, Object[].class);
List<Object[]> list = query.getResultList();
for (Object[] o : list) {
User u = o[0];
UserLevel ul = o[1];
System.out.println("User " + u.getUserName() + " has level " + ul.getLevel());
}