这里采用的是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
新人一枚,如若有误,还请指点。