为DAO添加一个很有用的接口

DAO功能有限的接口

我们的DAO里有这么一个接口:

	/**
	 * 按属性查找对象列表,匹配方式为相等.
	 */
	public List<T> findBy(final String propertyName, final Object value) {
		assert StringUtils.isNotBlank(propertyName);
		String jpql = "from " + getEntityClass().getName() + " t where t." + propertyName + "=?";
		return find(jpql, value);
	} 

如,我们需要查找用户状态为已开启的用户列表时,就会使用这个方法。

新的需求

今天,我们来谈谈另外一个需求,假设角色与权限是单向关联的,我们需要查找拥有权限A的所有角色。

以前的解决方案

以往我们要实现这个功能,一般我们需要在RoleDao里写一个方法,如listByPermissionName,实现可能就通过一个JPQL解决了:

	/**
	 * 获取拥有指定权限的角色列表.
	 */
	public List<User> listByPermissionName(final String permissionName) {
		// 注意,当有join子句时,必须要有select子句,不然返回的结果将不是Role类型。
		String jpql = "select distinct r from " + Role.class.getName() + " r left join r.permissions p where p.name=?";
		return super.find(jpql, permissionName);
	}
 
便利的解决方案

现在我们碰到了很多个这种类似需求,所以,可不可以dao父类方法可以解决这个问题呢?
所以,这两个接口就产生了:

	/**
	 * 按集合属性里的某个属性查找对象列表,匹配方式为相等.
	 * 
	 * @param propertyName 集合属性名
	 * @param nestedPropertyName 集合属性对象的指定属性
	 * @param value 匹配值
	 */
	public List<T> findBy(final String propertyName, final String nestedPropertyName, final Object value) {
		assert StringUtils.isNotBlank(propertyName);
		assert StringUtils.isNotBlank(nestedPropertyName);
		String jpql = "select distinct t from " + getEntityClass().getName() + " t left join t." + propertyName
				+ " p where p." + nestedPropertyName + "=?";
		return find(jpql, value);
	}

	/**
	 * 按集合属性里的某个属性查找唯一对象,匹配方式为相等.
	 * 
	 * @param propertyName 集合属性名
	 * @param nestedPropertyName 集合属性对象的指定属性
	 * @param value 匹配值
	 */
	public T findUniqueBy(final String propertyName, final String nestedPropertyName, final Object value) {
		assert StringUtils.isNotBlank(propertyName);
		assert StringUtils.isNotBlank(nestedPropertyName);
		String jpql = "select distinct t from " + getEntityClass().getName() + " t left join t." + propertyName
				+ " p where p." + nestedPropertyName + "=?";
		return findUnique(jpql, value);
	}
 

现在,要实现上面那个功能,只需要在RoleManager里调用IdEntityDao里的这个方法就OK了:

	/**
	 * 获取拥有指定权限的角色列表.
	 */
	@Transactional(readOnly = true)
	public List<User> listByPermissionName(final String permissionName) {
		return getEntityDao().findBy("permissions", "name", permissionName);
	}
 

所提供的方法有几个问题

  1. 获取其属性对象采用的是left join的方式,若需要fetch的方式呢?
  2. 查找的是其属性对象指定的属性值,那么如果有多层呢?

    如: getEntityDao().findBy("permissions", "creator.name", permissionName); 
  1. 我们的dao基类代码都只考虑no fetch的情况,所有需要加载延迟属性的方法都需要自己再写dao方法实现 ,这在目前所有的框架里都是这样的。是否考虑提供findWithLazyPropertiesBy(String propertyName, Object value, String[] fetchedPropertyNames); 的方法,有待讨论
  2. 这个方法确实只考虑到一级集合属性的情况。可以考虑提供findByMultiLevelProperty(String multiLevelPropertyName, Object value); 的方法,这样使用(在RoleManager中):List<Role> role = getEntityDao().findBy("permissions.resources.name", "资源名称");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值