[Criteria]not in子查询,查询不在中间表的数据

为了查询不在某个角色的所有用户,操碎了心!当然,主要是因为对hibernate不熟练。

其实sql语句就是很简单的一句,如下:

select t.id, t.account from t_sm_user t where t.id not in (
       select r.user_id from t_sm_user_role r where r.role_id = ?
)

但是,总有那么些有的没有的约束不让你用sql语句简单粗暴的实现啊,比如某组长的强迫症啊(无限怨念中...)

所以本菜鸟只好苦逼的上网到处找资料,毕竟菜鸟求谅解。

经过无数次的刷新页面和无数次的控制台报错,本屌不负众望,成功用Criteria实现了not in 子查询。

下面放代码:


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 String account;              //账号
     private Set<Role> roles = new HashSet<Role>(0);
    // Constructors

    /** default constructor */

   
    @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="ACCOUNT", length=20)

    public String getAccount() {
        return this.account;
    }
    
    public void setAccount(String account) {
        this.account = account;
    }
    @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;
	}

}


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;
     <span style="color:#ff0000;">private Set<User> users = new HashSet<User>(0);</span>
     
     
    // Constructors
    //.......
<span style="white-space:pre">	</span>
    @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;
    }

<span style="color:#ff0000;">	@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;
	}</span>
   
}



查询关键部分代码如下:

DetachedCriteria query = DetachedCriteria.forClass(Role.class);
			<span style="color:#ff0000;">query.createAlias("users", "users")</span>
			.add(Restrictions.eq("id", roleId))
			<span style="color:#ff0000;">.setProjection(Property.forName("users.id"));</span>
			c.add(Property.forName("id").notIn(query));

因为中间表无实体类,所以要注意红色高亮部分;


hibernate打印语句:

select this_.id as id7_0_, this_.ACCOUNT as ACCOUNT7_0_
  from t_sm_user this_
 where this_.id not in
       (select users1_.id as y0_
          from t_sm_role this_
         inner join t_sm_user_role users3_ on this_.id = users3_.ROLE_ID
         inner join t_sm_user users1_ on users3_.USER_ID = users1_.id
         where this_.id = ?)




猜你喜欢

转载自blog.csdn.net/ragin/article/details/49904085