hibernate的NativeSql查询

1、标量查询

1.1

    /*
     * 标量查询
     * 这里hibernate就是通过元数据判断表的字段顺序和类型,然后放到List<Object[]>中
     */
    @SuppressWarnings("unchecked")
    @Test
    public void test1(){
        Session session = HibernateUtil.getSf().getCurrentSession();
        session.beginTransaction();
        String sql="select id,title,createdate,category_id from Topic";
        SQLQuery q= session.createSQLQuery(sql);
        List<Object[]> list= q.list();
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i)[1]);
        }
        session.getTransaction().commit();
    }

而且开启了三级缓存,就是通过nativeSql 同样可以利用

1.2

/*
     * 标量查询
     * 利用元数据判断会浪费性能,可以手动指定
     * 对全部或者部分的标量值不设置类型信息也是可以的。
     */
    @SuppressWarnings("unchecked")
    @Test
    public void test2(){
        Session session = HibernateUtil.getSf().getCurrentSession();
        session.beginTransaction();
        String sql="select id,name,createdate,category_id from Topic";
        SQLQuery q= session.createSQLQuery(sql);
        q.setCacheable(true);
        q.addScalar("id", Hibernate.INTEGER).addScalar("name",Hibernate.STRING)
        .addScalar("createdate",Hibernate.TIMESTAMP).addScalar("category_id",Hibernate.INTEGER);

        List<Object[]> list= q.list();
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i)[1]+" "+list.get(i)[2]);
        }
        session.getTransaction().commit();
    }

2、实体查询

2.1

    /*
     * 实体查询
     * 实体查询有个要求,就是要把所有字段都查出来
     * 假若实体在映射时有一个many-to-one的关联指向另外一个实体,在查询时必须也返回那个实体
     * 如果利用下面的查询,当用到Category时,就会发出语句 1+N问题 懒加载的问题
     */
    @Test
    public void test3(){
        Session session = HibernateUtil.getSf().getCurrentSession();
        session.beginTransaction();
        String sql="select id,name,createdate,category_id from Topic";
        SQLQuery q= session.createSQLQuery(sql).addEntity(Topic.class);

        List<Topic> list= q.list();
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i).getTitle()+" "+list.get(i).getCategory().getName());
        }
        session.getTransaction().commit();
    }

这种返回实体的,如果开通了二级缓存,就是通过nativeSql也是是会缓存的
2.2

/*
     * 实体查询(处理关联实体)@manyToOne
     * 实体查询有个要求,就是要把所有字段都查出来
     * 上面一种情况test3,会造成性能问题(1+N问题)
     * 一种解决办法就是把那个 one的那一方提前取出来
     * 这种情况取出Topic就会同时把Topic类里面关联的category取出来,而且还单独返回一份category
     * 即使 这种情况不返回b的字段,list后还是会返回的
     * 
     * 只要是返回实体的情况,如果不同表字段出现重复,就会引发问题
     */
    @Test
    public void test4(){
        Session session = HibernateUtil.getSf().getCurrentSession();
        session.beginTransaction();
        String sql="select {a.*},{b.*} from Topic a left join Category b on" +
                "  a.category_id=b.id";
        SQLQuery q= session.createSQLQuery(sql).addEntity("a",Topic.class).addJoin("b", "a.category");


        @SuppressWarnings("unchecked")
        List<Object[]> list= q.list();
        for (int i = 0; i < list.size(); i++) {
            Topic t = (Topic) list.get(i)[0];
            Category c = (Category) list.get(i)[1];

            System.out.println(t.getTitle()+" "+t.getCategory().getName()+" "+c.getName());
        }
        session.getTransaction().commit();
    }

2.3

/*
     * 实体查询(处理关联集合)@oneToMany
     * 实体查询有个要求,就是要把所有字段都查出来
     * 
     * 这种情况取出Topic就会同时把Topic类里面关联的category取出来,而且还单独返回一份category
     * 
     */
    @Test
    public void test5(){
        Session session = HibernateUtil.getSf().getCurrentSession();
        session.beginTransaction();
        String sql="select a.id,a.name,b.id,b.title,b.createdate,b.category_id from Category a left join Topic b on" +
                "  a.id=b.category_id";
        SQLQuery q= session.createSQLQuery(sql).addEntity("a11",Category.class).addJoin("b", "a11.topics");

        @SuppressWarnings("unchecked")
        List<Object[]> list= q.list();
        for (int i = 0; i < list.size(); i++) {
            Topic t = (Topic) list.get(i)[1];
            Category c = (Category) list.get(i)[0];

            System.out.println(c.getName()+" "+c.getTopics().size());
        }
        session.getTransaction().commit();
    }

2.4返回多个实体
其实上面的通过addJoin同样返回多个实体

/*
     * 返回多个实体
     * 如果两个表的名字部分相同,那么采用返回实体,会出现属性映射问题 错乱
     * 采用下面方法可以解决
     */
    @Test
    public void test6(){
        Session session = HibernateUtil.getSf().getCurrentSession();
        session.beginTransaction();
        String sql="select {a.*},{b.*} from T_Tree a join T_Tree b on" +
                "  a.pId=b.id";
        SQLQuery q= session.createSQLQuery(sql).addEntity("a",Tree.class).addEntity("b", Tree.class);

        @SuppressWarnings("unchecked")
        List<Object[]> list= q.list();
        for (int i = 0; i < list.size(); i++) {
            Tree t1 = (Tree) list.get(i)[0];
            Tree t2 = (Tree) list.get(i)[1];

            System.out.println(t1.getName()+" "+t2.getName());
        }
        session.getTransaction().commit();
    }
/*
     * 返回多个实体
     * 如果两个表的名字部分相同,那么采用返回实体,会出现属性映射问题 错乱
     * 下面就是解决方式
     */
    @Test
    public void test7(){
        Session session = HibernateUtil.getSf().getCurrentSession();
        session.beginTransaction();
        String sql="select {a.*},{b.*} from Topic a join Category b on a.category_id=b.id";

        SQLQuery q= session.createSQLQuery(sql).addEntity("a",Topic.class).addJoin("b", "a.category");

        @SuppressWarnings("unchecked")
        List<Object[]> list= q.list();
        for (int i = 0; i < list.size(); i++) {
            Topic t1 = (Topic) list.get(i)[0];
            Category t2 = (Category) list.get(i)[1];

            System.out.println(t1.getTitle()+" "+t1.getCategory().getName()+" "+t2.getName());
        }
        session.getTransaction().commit();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值