[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 = ?)




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

mongotemplate mongodb的各种操作 模糊查询 精确查询 等等

本意是想查查mongo数据库的int类型的like怎么查,但是好像没 解决这个问题。 一. 常用查询: 1. 查询一条数据:(多用于保存时判断db中是否已有当前数据,这里 is...
  • LXB15959168136
  • LXB15959168136
  • 2016年08月19日 18:38
  • 20209

T-SQL查询:慎用 IN 和 NOT IN

今天突然想到之前在书上看到的一个例子,竟然想不起来了. 于是翻书找出来,测试一下. -- drop table father,son create table father(fid int,name...
  • kk185800961
  • kk185800961
  • 2014年12月06日 01:08
  • 6501

Criteria Query常用的查询限制方法

Restrictions.like(属性名, 查询条件的值, 匹配方式): Restrictions.in(属性名, 查询条件的值, 匹配方式): Restrictions.eq(属性名, 查询条件的...
  • u010918876
  • u010918876
  • 2015年01月13日 11:20
  • 1933

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

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

SQL中带有NOT IN 子查询改写

NOT IN子查询改写LEFT JOIN
  • wanbin6470398
  • wanbin6470398
  • 2017年12月04日 14:10
  • 147

在SQL Server中为什么不建议使用Not In子查询

在SQL Server中,子查询可以分为相关子查询和无关子查询,对于无关子查询来说,Not In子句比较常见,但Not In潜在会带来下面两种问题: 结果不准确 查询性能低下       ...
  • wxw_317
  • wxw_317
  • 2015年11月11日 17:38
  • 190

sql 在not in 子查询有null值情况下经常出现的陷阱

如果下:Table_A表和Table_B表,要求查询出在Table_A表中不在Table_B表中的记录。 CREATE TABLE [dbo].[Table_A]( [ID] [n...
  • wozengcong
  • wozengcong
  • 2015年05月06日 18:09
  • 2399

sql 在not in 子查询有null值情况下经常出现的陷阱

sql null相关处理
  • xxc1605629895
  • xxc1605629895
  • 2017年12月27日 22:44
  • 28

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

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

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

引用    我们进行数据查询的时候极少有可能就在一张表里就能得到想要的数据,不可避免得会用到子查询或者连接查询,很多时候我们很轻松自然得会想到子查询的方法,但是子查询往往效率比较低,而转换成连接...
  • qq1071946724
  • qq1071946724
  • 2015年01月13日 14:20
  • 466
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[Criteria]not in子查询,查询不在中间表的数据
举报原因:
原因补充:

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