java 如何优雅的实现一个mysql where 条件语句来查找数据?

    我们在使用mysql的时候 经常会写where语句 比如 where (age>18 and name="张三")or age >2 .那么这种是怎么实现的呢?这里我们用一个设计模式 :specification 

     我们首先定义一个接口:

public interface Specification<T> {
	public boolean isSatisfiedBy(T t);
}

isSatisfiedBy() 这个方法是用来检测是否满足我们的条件。后面的所有操作都是基于这个方法来设计,继续定义一个基类:

public abstract class AbstractSpecification<T> implements Specification<T> {
	
	public abstract boolean isSatisfiedBy(T t);
	
	public AbstractSpecification<T> or(Specification<T> s) {
		return new OrSpecification<T>(this,s);
	}

	public AbstractSpecification<T> and(Specification<T> s) {
		return new AndSpecification<T>(this,s);
	}

	public AbstractSpecification<T> not() {
		return new NotSpecification<T>(this);
	}

}

 这个基类里实现了specification 接口 提供了一个抽象方法 isSatisfiedBy()给子类覆盖

添加三个子类 and or not 

public class AndSpecification<T> extends AbstractSpecification<T> {

	private Set<Specification<T>> set = new HashSet<Specification<T>>();
	
	public AndSpecification(Specification<T> a, Specification<T> b) {
		set.add(a);
		set.add(b);
	}
	
	public boolean isSatisfiedBy(T t) {
		for( Specification<T> s : set ) {
			if( !s.isSatisfiedBy(t) ) {
				return false;
			}
		}
		return true;
	}
	
	@Override
	public AbstractSpecification<T> and(Specification<T> s) {
		set.add(s);
		return this;
	}

}



public class NotSpecification<T> extends AbstractSpecification<T> {

	private Specification<T> spec;
	
	public NotSpecification(Specification<T> s) {
		this.spec=s;
	}
	
	@Override
	public boolean isSatisfiedBy(T t) {
		return !spec.isSatisfiedBy(t);
	}

}


public class OrSpecification<T> extends AbstractSpecification<T> {

	private Set<Specification<T>> set = new HashSet<Specification<T>>();
	
	public OrSpecification(Specification<T> a, Specification<T> b) {
		set.add(a);
		set.add(b);
	}
	
	public boolean isSatisfiedBy(T t) {
		for( Specification<T> s : set ) {
			if( s.isSatisfiedBy(t) ) {
				return true;
			}
		}
		return false;
	}
	
	@Override
	public AbstractSpecification<T> or(Specification<T> s) {
		set.add(s);
		return this;
	}

}

 基本的框架已经达成了 ,现在实现一个 年龄大于num的类:

public class AgeMoreThanSpecification extends AbstractSpecification<People> {
	
	private int age;
	 
	
	public AgeMoreThanSpecification (int age) {
		super();
		this.age= age;
	 
	}
	
	public boolean isSatisfiedBy(People t) {
		return t.age>age;
	}

}

继续加一个name 等于 xxx的类:


public class NameSpecification extends AbstractSpecification<People> {

	private String name;

	public ToyTypeNameSpecification(String name) {
		super();
		this.name = name;
	}

	@Override
	public boolean isSatisfiedBy(People t) {
		return t.getName().equals(name);
	}

}

ok  返回看开始说的那个sql 条件 where (age>18 and name="张三")or age >2

我可以构造一个people list 来找这些满足的条件


//此处为伪代码
People p=new People("张三",19);
People p2=new People("张三1",1);
People p3=new People("张三2",1);
People p4=new People("张三3",14);

List.add(p);

List.add(p2);

List.add(p3);

List.add(p4);


Specification specification=new OrSpecification(new AndSpecification(new AgeMoreThanSpecification(18),new NameSpecification("张三")),new AgeMoreThanSpecification(2));

for l:list
if(specification.isSatisfiedBy(l)){

 //find 2 item  People p4=new People("张三3",14);  People p=new People("张三",19); 
}

 优点代码的实现全部隐藏,只暴露过程。 缺点就是类的数量比较多。添加一个条件就是一个子类。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值