Hibernate 原生sql

示例

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 {}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值