Hibernate 封装一个可变字段查询方法

这里采用的是JPA的方式,普通方式的也是一样的原理。
Brand.java

@Entity
@Table(name = "brand")
public class Brand {

    @Id
    @Column(name = "brand_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer bid;

    @Column(name = "brand_name")
    private String bname;

    public Brand() {
        super();
    }

    public Brand(String bname) {
        super();
        this.bname = bname;
    }

    public Brand(Integer bid, String bname) {
        super();
        this.bid = bid;
        this.bname = bname;
    }
    ...
}

BaseDao.java

public class BaseDaoImpl<T> implements BaseDao<T> {
    protected Class<T> clazz;

    public BaseDaoImpl() {
        // 获取父类的参数化类型
        ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
        // 获取父类的参数化类型的第一个泛型参数
        clazz = (Class<T>) type.getActualTypeArguments()[0];
    }

    /**
     * 查询实体的部分字段
     * @param fields    实体的属性
     * @return
     */
        @Override
    public List<T> findProperties(String... fields) {
        EntityManager entityManager = null;
        List<T> list = null;
        try {
            // 获取实体管理器
            entityManager = entityManagerFactory.createEntityManager();

            // 准备HQL语句
            // 格式:select new Entity(属性1,属性2,... ) from Entity

            StringBuilder sb = new StringBuilder("select new " + clazz.getSimpleName() + " (");
            // 遍历字段,append至 hql语句中
            for (String string : fields) {
                sb.append(string + ",");
            }
            int i = sb.lastIndexOf(",");
            // 去掉最后一个参数后面的逗号
            sb.replace(i, i + 1, "");
            sb.append(") from ");

            // System.out.println(sb.toString() + clazz.getName());
            list = entityManager.createQuery(sb.toString() + clazz.getName(), clazz).getResultList();

        } catch (Exception e) {
            // Log.error("查询异常 info={} ", e.getMessage());
            throw e;
        } finally {
            if (entityManager != null)
                entityManager.close();
        }
        return list;
    }


}

下面格式的HQL语句会报异常
* Error:select 属性1,属性2,… from Entity
* Exception :
* Cannot create TypedQuery for query with more than one return using requested result type

关键在于实体的每一种构造函数都要实现。感觉在属性少的时候还行,多了就会显得臃肿。

投影查询

select new Entity(属性1,属性2... ) from Entity

此语句将查询到的部分字段,自动选择相应的构造方法进行封装。


TestApp.java

@Test
public void testFindField(){
    BrandDao dao  = new BrandDaoImpl();
    List<Brand> list = dao.findProperties("bname");
    for (Brand brand : list) {
        System.out.println(brand.getBname());
    }

}

@Test
public void testFindField2(){
    BrandDao dao  = new BrandDaoImpl();
    List<Brand> list = dao.findProperties("bid","bname");
    for (Brand brand : list) {
        System.out.println(brand.getBid()+":"+brand.getBname());
    }

}

输出

//test1
Hibernate: 
    select
        brand0_.brand_name as col_0_0_ 
    from
        brand brand0_
兰蔻
雅诗兰黛
迪奥
香奈儿
倩碧
欧莱雅
大宝
SK-II
娇兰
纪梵希
YSL

//test2
Hibernate: 
    select
        brand0_.brand_id as col_0_0_,
        brand0_.brand_name as col_1_0_ 
    from
        brand brand0_
1:兰蔻
2:雅诗兰黛
3:迪奥
4:香奈儿
5:倩碧
6:欧莱雅
7:大宝
8:SK-II
9:娇兰
10:纪梵希
11:YSL

新人一枚,如若有误,还请指点。

猜你喜欢

转载自blog.csdn.net/a13465515551d/article/details/82563295