之前一直用mybatis,最近接触一个项目用的hibernate,hibernate新手,说句不好听的话:特么蛋疼!好难用啊有木有!好难用啊有木有!好难用啊有木有!重要的话说三遍。
因为distinct性能差,所以组织让我调整hql语句。如果用mybatis吧 分分钟就好了,像这样
select a.*
from t_access_token a
where exists (select 'T'
from t_sm_role_access_token r
where r.access_token_id = a.id
and exists (select 'T'
from t_sm_user_role u
where r.role_id = u.role_id
and u.user_id = 1))
order by a.seq asc, a.id asc
hql就蛋疼了啊,中间表没有实体类。hql又是面向对象 ,没办法直接select 'T' from t_sm_role_access_token啊。查了下hql有个elements方法。
东拼西凑写了hql语句, 放详细点。
AccessToken实体类
package cn.ffcs.system.domain;
import static javax.persistence.GenerationType.SEQUENCE;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@Entity
@Table(name="t_access_token")
@JsonIgnoreProperties(value={"hibernateLazyInitializer"})
public class AccessToken implements java.io.Serializable{
private Integer id;
private String sysName;
private String appKey;
private String secret;
private Date createTime;
private String isEvent;
private String mailAddress;
private String isSendMail;
private Integer pId;
private String url;
private String appCode;
private String host;
private String type;
private String status = "1";
private Set<Role> roles = new HashSet<Role>(0);
private Integer seq;
private String icon;
public AccessToken(){}
public AccessToken(Integer id, String sysName, String appKey,
String secret, Date createTime, String isEvent, String mailAddress,
String isSendMail, Integer pId, String url, String appCode,
String host) {
super();
this.id = id;
this.sysName = sysName;
this.appKey = appKey;
this.secret = secret;
this.createTime = createTime;
this.isEvent = isEvent;
this.mailAddress = mailAddress;
this.isSendMail = isSendMail;
this.pId = pId;
this.url = url;
this.appCode = appCode;
this.host = host;
}
@SequenceGenerator(name="seq_accesstoken", sequenceName="seq_accesstoken",allocationSize=10)
@GeneratedValue (generator="seq_accesstoken")
@Column(name="ID", unique=true, nullable=false, precision=22, scale=0)
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="SYS_NAME", length=250)
public String getSysName() {
return sysName;
}
public void setSysName(String sysName) {
this.sysName = sysName;
}
@Column(name="APP_KEY", length=250)
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
@Column(name="SECRET", length=250)
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
@Temporal(TemporalType.DATE)
@Column(name="CREATE_TIME", length=250)
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Column(name="IS_EVENT", length=250)
public String getIsEvent() {
return isEvent;
}
public void setIsEvent(String isEvent) {
this.isEvent = isEvent;
}
@Column(name="MAIL_ADDRESS", length=250)
public String getMailAddress() {
return mailAddress;
}
public void setMailAddress(String mailAddress) {
this.mailAddress = mailAddress;
}
@Column(name="IS_SEND_MAIL", length=250)
public String getIsSendMail() {
return isSendMail;
}
public void setIsSendMail(String isSendMail) {
this.isSendMail = isSendMail;
}
@Column(name="PID")
public Integer getpId() {
return pId;
}
public void setpId(Integer pId) {
this.pId = pId;
}
@Column(name="URL", length=255)
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Column(name="APP_CODE", length=20)
public String getAppCode() {
return appCode;
}
public void setAppCode(String appCode) {
this.appCode = appCode;
}
@Column(name="HOST", length=50)
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
@Column(name="TYPE", length=3)
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
@ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="accessTokens")
@JsonIgnore
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
@Column(name="SEQ", length=20)
public Integer getSeq() {
return seq;
}
public void setSeq(Integer seq) {
this.seq = seq;
}
@Column(name="ICON", length=20)
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
}
User实体类:
package cn.ffcs.system.domain;
// default package
import static javax.persistence.GenerationType.SEQUENCE;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import cn.ffcs.system.common.ReflectIgnore;
/**
* User entity. @author MyEclipse Persistence Tools
*/
@SuppressWarnings("serial")
@Entity
@Table(name="t_sm_user")
@JsonIgnoreProperties(value={"hibernateLazyInitializer"})
public class User implements java.io.Serializable, UserDetails {
// Fields
private Integer id;
private Integer orgId;
@ReflectIgnore
private Org org;
private String account; //账号
@ReflectIgnore
private String password;
private String nickname; //昵称/别名
private String userName; //用户姓名
private String tel; //联系电话
private String mobile; //手机
private String identityCard; //身份证号码
private Integer sex; //性别
private String jobTitle; //职位名称
private String email; //邮件地址
private String descript;
private Integer status = 1; //记录状态0-,1-
private Date createTime = new Date();
private Date updateTime = new Date();
private Integer createUser;
private Set<Role> roles = new HashSet<Role>(0);
@ReflectIgnore
private Integer[] roleIds;
@ReflectIgnore
private String roleNames;
@ReflectIgnore
private List<Authority> userAuthorities;
private String picPath;
// Constructors
/** default constructor */
public User() {
}
/** full constructor */
public User(Integer orgId, Org org, String account, String password, String nickname, String tel, String email, String descript, Integer status, Date createTime, Integer createUser, Set<Role> roles,String userName,String mobile,String identityCard,Integer sex,String jobTitle) {
this.orgId = orgId;
this.org = org;
this.account = account;
this.password = password;
this.nickname = nickname;
this.tel = tel;
this.email = email;
this.descript = descript;
this.status = status;
this.createTime = createTime;
this.createUser = createUser;
this.roles = roles;
this.userName = userName;
this.mobile = mobile;
this.identityCard = identityCard;
this.sex = sex;
this.jobTitle = jobTitle;
}
@SequenceGenerator(name="seq_t_sm_user_id", sequenceName="seq_t_sm_user_id",allocationSize=10)
@GeneratedValue (generator="seq_t_sm_user_id")
@Id
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="ORG_ID", length=50)
public Integer getOrgId() {
return orgId;
}
public void setOrgId(Integer orgId) {
this.orgId = orgId;
}
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ORG_ID", insertable=false, updatable=false)
public Org getOrg() {
return this.org;
}
public void setOrg(Org org) {
this.org = org;
}
@Column(name="ACCOUNT", length=20)
public String getAccount() {
return this.account;
}
public void setAccount(String account) {
this.account = account;
}
@Column(name="PASSWORD", length=50)
@JsonIgnore
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
@Column(name="NICKNAME", length=50)
public String getNickname() {
return this.nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
@Column(name="TEL", length=50)
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Column(name="EMAIL", length=50)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Column(name="DESCRIPT", length=200)
public String getDescript() {
return this.descript;
}
public void setDescript(String descript) {
this.descript = descript;
}
@Column(name="STATUS", precision=22, scale=0)
@JsonIgnore
public Integer getStatus() {
return this.status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name="CREATE_TIME")
@JsonIgnore
public Date getCreateTime() {
return this.createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Column(name="CREATE_USER", precision=22, scale=0)
@JsonIgnore
public Integer getCreateUser() {
return this.createUser;
}
public void setCreateUser(Integer createUser) {
this.createUser = createUser;
}
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinTable(name = "t_sm_user_role",
joinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "ROLE_ID", referencedColumnName = "id")
)
@JsonIgnore
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
@Transient
public Integer[] getRoleIds() {
return roleIds;
}
public void setRoleIds(Integer[] roleIds) {
this.roleIds = roleIds;
}
@Transient
@JsonIgnore
public List<Authority> getUserAuthorities() {
return userAuthorities;
}
public void setUserAuthorities(List<Authority> userAuthorities) {
this.userAuthorities = userAuthorities;
}
@Column(name="PIC_PATH", length=50)
public String getPicPath() {
return picPath;
}
public void setPicPath(String picPath) {
this.picPath = picPath;
}
//覆盖spring security的方法
@Override
@Transient
@JsonIgnore
public Collection<GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> grantedAuthorities = new HashSet<GrantedAuthority>();
for(Authority authority : userAuthorities){
grantedAuthorities.add(new GrantedAuthorityImpl("AUTH_" + authority.getId()));
}
return grantedAuthorities;
}
@Override
@Transient
@JsonIgnore
public String getUsername() {
return this.account;
}
@Override
@Transient
@JsonIgnore
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
@Transient
@JsonIgnore
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
@Override
@Transient
@JsonIgnore
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
@Transient
@JsonIgnore
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
@Column(name="USERNAME", length=50)
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Column(name="MOBILE", length=50)
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
@Column(name="IDENTITYCARD", length=50)
public String getIdentityCard() {
return identityCard;
}
public void setIdentityCard(String identityCard) {
this.identityCard = identityCard;
}
@Column(name="SEX", length=20)
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
@Column(name="JOBTITLE", length=50)
public String getJobTitle() {
return jobTitle;
}
public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name="UPDATE_TIME")
@JsonIgnore
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
@Transient
public String getRoleNames() {
return roleNames;
}
public void setRoleNames(String roleNames) {
this.roleNames = roleNames;
}
}
Role实体类
package cn.ffcs.system.domain;
import static javax.persistence.GenerationType.SEQUENCE;
import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.JoinColumn;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.hibernate.annotations.GenericGenerator;
import cn.ffcs.system.common.ReflectIgnore;
/**
* Role entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table(name="t_sm_role")
public class Role implements java.io.Serializable {
// Fields
/**
*
*/
private static final long serialVersionUID = 5586297524648936632L;
private Integer id;
private String name;
private String descript;
private Integer status = 1;
private Date createTime = new Date();
private Integer createUser;
private Set<User> users = new HashSet<User>(0);
private Set<Authority> authorities = new HashSet<Authority>(0);
private Set<AccessToken> accessTokens = new HashSet<AccessToken>(0);
@ReflectIgnore
private Integer[] authorityIds;
private Set<Mobile> menus = new HashSet<Mobile>(0);
@ReflectIgnore
private Integer[] menuIds;
@ReflectIgnore
private Integer[] accessTokenIds;
// Constructors
/** default constructor */
public Role() {
}
/*
*//** full constructor */
public Role(String name, String descript, Integer status, Date createTime, Integer createUser, Set<User> users, Set<Authority> authorities) {
this.name = name;
this.descript = descript;
this.status = status;
this.createTime = createTime;
this.createUser = createUser;
this.users = users;
this.authorities = authorities;
}
@SequenceGenerator(name="seq_t_sm_role_id", sequenceName="seq_t_sm_role_id",allocationSize=10)
@GeneratedValue (generator="seq_t_sm_role_id")
@Id
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="NAME", length=20)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="DESCRIPT", length=200)
public String getDescript() {
return this.descript;
}
public void setDescript(String descript) {
this.descript = descript;
}
@Column(name="STATUS", precision=22, scale=0)
@JsonIgnore
public Integer getStatus() {
return this.status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name="CREATE_TIME", length=7)
@JsonIgnore
public Date getCreateTime() {
return this.createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Column(name="CREATE_USER", precision=22, scale=0)
@JsonIgnore
public Integer getCreateUser() {
return this.createUser;
}
public void setCreateUser(Integer createUser) {
this.createUser = createUser;
}
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "roles")
@JsonIgnore
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
@ManyToMany(cascade = CascadeType.PERSIST, fetch=FetchType.LAZY)
@JoinTable(name = "t_sm_role_auth",
joinColumns = @JoinColumn(name = "ROLE_ID", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "AUTHORITY_ID", referencedColumnName = "id")
)
@JsonIgnore
public Set<Authority> getAuthorities() {
return authorities;
}
public void setAuthorities(Set<Authority> authorities) {
this.authorities = authorities;
}
@ManyToMany(cascade = CascadeType.PERSIST, fetch=FetchType.LAZY)
@JoinTable(name = "t_sm_role_access_token",
joinColumns = @JoinColumn(name ="ROLE_ID", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name="ACCESS_TOKEN_ID", referencedColumnName = "id"))
@JsonIgnore
public Set<AccessToken> getAccessTokens() {
return accessTokens;
}
public void setAccessTokens(Set<AccessToken> accessTokens) {
this.accessTokens = accessTokens;
}
@Transient
public Integer[] getAuthorityIds() {
return authorityIds;
}
public void setAuthorityIds(Integer[] authorityIds) {
this.authorityIds = authorityIds;
}
@ManyToMany(cascade = CascadeType.PERSIST, fetch=FetchType.LAZY)
@JoinTable(name = "t_sm_role_sso",
joinColumns = @JoinColumn(name = "ROLE_ID", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "AUTHORITY_ID", referencedColumnName = "MENU_ID")
)
@JsonIgnore
public Set<Mobile> getMenus() {
return menus;
}
public void setMenus(Set<Mobile> menus) {
this.menus = menus;
}
@Transient
public Integer[] getMenuIds() {
return menuIds;
}
public void setMenuIds(Integer[] menuIds) {
this.menuIds = menuIds;
}
@Transient
public Integer[] getAccessTokenIds() {
return accessTokenIds;
}
public void setAccessTokenIds(Integer[] accessTokenIds) {
this.accessTokenIds = accessTokenIds;
}
}
select a from AccessToken a where exists (from Role r where a in elements(r.accessTokens) and exists(from User u where r in elements(u.roles) and u.id = ?) and r.status = 1) and a.status = 1 order by a.seq asc, a.id asc
最后打印出来的sql语句
select accesstoke0_.ID as ID0_,
accesstoke0_.TYPE as TYPE0_,
accesstoke0_.HOST as HOST0_,
accesstoke0_.SEQ as SEQ0_,
accesstoke0_.ICON as ICON0_,
accesstoke0_.status as status0_,
accesstoke0_.MAIL_ADDRESS as MAIL7_0_,
accesstoke0_.URL as URL0_,
accesstoke0_.CREATE_TIME as CREATE9_0_,
accesstoke0_.SYS_NAME as SYS10_0_,
accesstoke0_.APP_KEY as APP11_0_,
accesstoke0_.SECRET as SECRET0_,
accesstoke0_.IS_EVENT as IS13_0_,
accesstoke0_.IS_SEND_MAIL as IS14_0_,
accesstoke0_.PID as PID0_,
accesstoke0_.APP_CODE as APP16_0_
from t_access_token accesstoke0_
where (exists (select role1_.id
from t_sm_role role1_
where (accesstoke0_.ID in
(select accesstoke2_.ACCESS_TOKEN_ID
from t_sm_role_access_token accesstoke2_
where role1_.id = accesstoke2_.ROLE_ID))
and (exists (select user3_.id
from t_sm_user user3_
where (role1_.id in
(select roles4_.ROLE_ID
from t_sm_user_role roles4_
where user3_.id = roles4_.USER_ID))
and user3_.id = 1))
and role1_.STATUS = 1))
and accesstoke0_.status = 1
order by accesstoke0_.SEQ asc, accesstoke0_.ID asc
关键点:
1、是实体类添加的Set集合
2、hql的elements函数