示例
public List<Map<String, Object>> XXXListMap() {
Session session = null;
List<Map<String,Object>> listInfo = new ArrayList<Map<String,Object>>();
try {
session = getSession();
String sql = "select id, name, ip, selectType, XXXname, XXXpwd, XXXpwd, comm from XXX order by id ";
logger.info("ListMap:"+sql);
SQLQuery q = session.createSQLQuery(sql)
.addScalar("id", StandardBasicTypes.INTEGER)//
.addScalar("name", StandardBasicTypes.STRING)
.addScalar("ip", StandardBasicTypes.STRING)
.addScalar("selectType", StandardBasicTypes.STRING)
.addScalar("XXXname", StandardBasicTypes.STRING)
.addScalar("XXXpwd", StandardBasicTypes.STRING)
.addScalar("XXXpwd", StandardBasicTypes.STRING)
.addScalar("comm", StandardBasicTypes.STRING);
List list = q.list();
for(Object ob : list) {
Map<String, Object> map = new HashMap<String, Object>();
Object[] ob1 = (Object[]) ob;
map.put("id", ob1[0]);
map.put("name", ob1[1]);
map.put("ip", ob1[2]);
map.put("selectType", ob1[3]);
map.put("XXXname", ob1[4]);
map.put("XXXpwd", ob1[5]);
map.put("rule", ob1[6]);
map.put("XXXpwd", ob1[7]);
listInfo.add(map);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (session != null) {
session.close();
}
}
return listInfo;
}
标量查询
最基本的SQL查询就是获得一个标量的列表:
session.createSQLQuery("select * from person_info").list();
session.createSQLQuery("select id,name,age from person_info").list();
指加明确的返回值类型
它们都将返回一个Object数组组成的List,数组每个元素都是person_info表的一个字段值。Hibernate会使用ResultSetMetadata来判定返回的标量值的实际顺序和类型。但是在JDBC中过多的使用ResultSetMetadata会降低程序的性能。所以为了过多的避免使用ResultSetMetadata或者为了指定更加明确的返回值类型,我们可以使用addScalar()方法
session.createSQLQuery("select * from person_inf")
.addScalar("name",StandardBasicTypes.STRING)
.addScalar("age",StandardBasicTypes.INT)
.list();
实体查询
上面的标量查询返回的标量结果集,也就是从resultset中返回的“裸”数据。如果我们想要的结果是某个对象的实体,这是就可以通过addEntity()方法来实现。addEntity()方法可以讲结果转换为实体。但是在转换的过程中要注意几个问题:
1、查询返回的是某个数据表的全部数据列
2、该数据表有对应的持久化类映射
这时才可以通过addEntity()方法将查询结果转换成实体。
session.createSQLQuery("select * from perons_inf").addEntity(Person.class).list;
session.createSQLQuery("select id,name,age from person_inf").addEntity(Person.class).list();
实体映射里的注意
这个查询指定:
1、SQL查询字符串
2、要返回的实体
假设Person被映射为拥有id,name和age三个字段的类,以上的两个查询都返回一个List,每个元素都是一个Person实体。
假若实体在映射时有一个many-to-one的关联指向另外一个实体,在查询时必须也返回那个实体(获取映射的外键列),否则会导致发生一个"column not found"的数据库错误。这些附加的字段可以使用*标注来自动返回,但我们希望还是明确指明,看下面这个具有指向teacher的many-to-one的例子:
session.createSQLQuery("select id, name, age, teacherID from person_info").addEntity(Person.class).list();
单表多表的查询
这样就可以通过person.getTeacher()获得teacher了。
public void entityQuery(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
String sql = "select * from person_info";
List list = session.createSQLQuery(sql).
addEntity(Person.class). //指定将查询的记录行转换成Person实体
list();
for (Iterator iterator = list.iterator();iterator.hasNext();) {
Person person = (Person) iterator.next(); //集合的每个元素都是一个Person对象
System.out.println("name="+person.getName());
System.out.println("age="+person.getAge());
}
tx.commit();
session.close();
}
上面的都是单表查询,如果我们在SQL语句中使用了多表连接,则SQL语句可以选出多个数据表的数据。Hibernate支持将查询结果转换成多个实体。如果要将查询结果转换成多个实体,则SQL字符串中应该为不同数据表指定不同别名,并且调用addEntity()方法将不同数据表转换成不同实体。如下:
public void multiEntityQuery(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
String sql = "select p.*,e.* from person_inf as p inner join event_inf as e" +
" on p.person_id=e.person_id";
List list = session.createSQLQuery(sql)
.addEntity("p",Person.class)
.addEntity("e", MyEvent.class)
.list();
for(Iterator iterator = list.iterator();iterator.hasNext();){
//每个集合元素都是Person、MyEvent所组成的数组
Object[] objects = (Object[]) iterator.next();
Person person = (Person) objects[0];
MyEvent event = (MyEvent) objects[1];
System.out.println("person_id="+person.getId()+" person_name="+person.getName()+" title="+event.getTitle());
}
}
addJoin
通过提前抓取将Event连接获得,而避免初始化proxy带来的额外开销也是可能的。这是通过addJoin()方法进行的,通过这个方法可以将实体的关联实体转换成查询对象。如下:
public void joinQuery(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
String sql = "select p.*,e.* from person_inf as p,event_inf as e where e.person_id=p.person_id";
List list = session.createSQLQuery(sql)
.addEntity("p",Person.class)
.addJoin("e","p.myEvents")
.list();
for(Iterator iterator = list.iterator();iterator.hasNext();){
//每个集合元素都是Person、MyEvent所组成的数组
Object[] objects = (Object[]) iterator.next();
Person person = (Person) objects[0];
MyEvent event = (MyEvent) objects[1];
System.out.println("person_id="+person.getId()+" person_name="+person.getName()+" title="+event.getTitle());
}
}
上面的程序返回的Person对象,其属性myEvent属性已经完全被初始化,不再需要数据库的额外操作,同时将该属性转换成别名为e的实体。也就是说返回的结果是Person、Event对象数组的列表。
执行更新操作
使用SQLQuery执行数据库更新操作比较容易,除了像查询时那样需要指定SQL语句(如有需要还需设置SQL参数)外,仅需调用executeUpdate()方法,即可提交更新操作。代码如下所示:
session.createSQLQuery("update note表名 set createtime = ? where note.id = ?");
query.setDate(0, new Date());
query.setLong(1, 1L);
query.executeUpdate();
executeUpdate方法的返回结果为改变的数据库记录的行数。
处理In字句
List<String> selectTypsList = new ArrayList<>();
for (Map<String, String> map : lineDownOrders) {
if(!StringUtils.isEmpty(map.get("0"))) {
selectTypsList.add(map.get("0"));
}
}
@Override
public void deleteNotInExcel(List<String> selectTypsList) {
Session session = null;
try {
session = getSession();
if(!StringUtils.isEmpty(selectTypsList.toString())) {
String sql = "delete from NET_IPTV_MULTICAST where selectType not in (:selectTypsList)";
logger.info(sql);
logger.info("param:"+selectTypsList.toString());
SQLQuery query = session.createSQLQuery(sql);
query.setParameterList("selectTypsList", selectTypsList);
Integer index = query.executeUpdate();
logger.info("paramIndex:"+index);
}
} catch (Exception e) {
e.printStackTrace();
} finally {}
}