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

原创 2015年11月18日 11:02:35

为了查询不在某个角色的所有用户,操碎了心!当然,主要是因为对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 = ?)




版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

oracle子查询中not in后面不能为null值的理解

首先说说oracle中的null值吧。 null在oracle中代表未知,表示可能有,也可能没有。任何与null值的普通运算都为null,但可以用一些函数来处理null值,oracle排序中默认nu...

子查询(in not )转化为连接查询的方法(很神奇的,BI可以借鉴)

引用    我们进行数据查询的时候极少有可能就在一张表里就能得到想要的数据,不可避免得会用到子查询或者连接查询,很多时候我们很轻松自然得会想到子查询的方法,但是子查询往往效率比较低,而转换成连接查询...

mysql 两表join与in子查询的比较

有两个表 promotion_full_reduction base_user_favorite_item 现在要查询用户收藏的商品中参加促销了的商品个数,有两种写法,一种是使用in子查询:SELEC...

oracle sql 多表 嵌套子查询 连接查询, join where exist in 的区别

sql中exits和in的区别 转:http://hi.baidu.com/delphi_relive/blog/item/d7c0034a49c4932208f7ef21.html in 和...

sql多表查询之三:子查询IN

关于使用子查询IN,给大家一个小忠告:子查询IN适合外结果集大,子查询结果集小的情况,千万不能滥用子查询IN,您一定要保证子查询所返回的结果集尽量的小,哪怕你的SQL返回记录数只有1条,如果你使用到了...

使用In的子查询.rar

  • 2010-07-02 13:13
  • 44KB
  • 下载

Hibernate查询之Criteria查询in中的长度大于1000解决方案

众所周知。hibernate的查询有好几种,Criteria正是其查询方式的一种,跟其他查询方式比较下具体优缺多有争议,不过这个不是今天要讨论的重点,我开发用的就是Criteria查询,先来说说我在使...

一步一步学MySQL----16 多表数据记录查询之子查询

16.1 为什么使用子查询 日常工作中,经常会用到多表查询,而在进行多表查询时,首先会对两个表进行笛卡尔积操作,然后再选取符合匹配条件的数据记录。在进行笛卡尔积操作的时候,会生成两个数据表中数据记...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)