Hibernate(Hql)

16 篇文章 0 订阅
5 篇文章 0 订阅

Hql语句
Hibernate query language

单表
持久化类

string

obj

list

/*
     * 带参数的查询
     */
    @Test
    public void testQueryClasses_Parameter_1(){
        Session session = sessionFactory.openSession();
        Query query = session.createQuery("from Classes where name=?");
        query.setString(0, "java");
        List<Classes> classesList = query.list();
        session.close();
    }

    /*
     * 带参数的查询
     *    好处:在写hql语句的参数,参数可以是一个变量
     */
    @Test
    public void testQueryClasses_Parameter_2(){
        Session session = sessionFactory.openSession();
        Query query = session.createQuery("from Classes where name=:name");
        query.setString("name", "php");
        List<Classes> classesList = query.list();
        session.close();
    }

一对多

/**
     * 一对多的查询
     *    等值链接
     */
    @Test
    public void testQueryClassesAndStudent(){
        Session session = sessionFactory.openSession();
        List<Object[]> classesList = session.createQuery("from Classes c,Student s where c.cid=s.classes.cid").list();
        for(Object[] objects:classesList){
            Classes classes = (Classes)objects[0];
            Student student = (Student)objects[1];
            System.out.println(classes.getName());
            System.out.println(student.getName());
        }
        session.close();
    }

等值连接

内连接

迫切内连接

迫切左外连接

error
该hql语句是不能运行的,因为fetch的结构是Classes包含set的students集合,而select后的结构是把classes中的name和student中的name查询出来,这两个结构是矛盾的。
如果在select语句中有带构造函数的查询,则在from后面不能接fetch,如果在from后面有fetch,则不能写select

说明:
如果查询的是一些字段,则利用带select的查询,这个时候就不能用fetch。
如果查询的是一个对象的所有的字段,则用from后面跟fetch,这个时候不能用select查。

多对多

/**
     * 多对多
     *     迫切左外链接,查询course中所有记录
     */
    @Test
    public void testQueryLeftCourse(){
        Session session = sessionFactory.openSession();
        List<Course> courses = session.createQuery("from Course c left outer join fetch c.students s").list();
        session.close();
    }

ddd

/**
     * 多对多
     *     迫切左外链接,查询所有的学生,并查询course
     */
    @Test
    public void testQueryLeftStudent(){
        Session session = sessionFactory.openSession();
        List<Student> students = session.createQuery("from Student s left outer join fetch s.courses c").list();
        session.close();
    }

dddsc

/**
     * 多对多
     * 查询student中的name和course中的name
     * 多对多一些字段来自于两张表的查询
     * 并将结果放入userBean中
     */
    @Test
    public void testQueryPropertyFromStudentAndCourse(){
        Session session = sessionFactory.openSession();
        List<UserBean> userBeanList = session.createQuery("select new cn.itcast.sh08.hibenate.hql.UserBean(c.name,s.name) " +
                                                          "from Courses c inner join c.students s").list();
        session.close();
    }

一对多结合多对多

public class Student implements Serializable{
    private Long sid;
    private String name;
    private Set<Course> courses;
    private Classes classes;
/**
     * 查询所有的学生,并把学生的课程信息和相关的班级信息查询出来
     */
    @Test
    public void testQueryStudentAndCourseAndClasses(){
        Session session = sessionFactory.openSession();
        List<Student> students = session.createQuery("from Student s left outer join fetch s.courses c left outer join fetch s.classes cc").list();
        Set<Student> students2 = new HashSet<Student>(students);
        System.out.println(students2.size());
        session.close();
    }

总结
1、如果需要查询一个对象,则不用带select,如果两张表以上,则用fetch查询
2、如果需要查询几个字段,则用带构造函数的查询,不能加fetch
3、在hql语句中,from后面跟的都是持久化对象,其他的部分都是属性,而不是字段

查询缓存
用意
一级缓存和二级缓存可以称为对象缓存。
查询缓存是数据缓存,能够按照需求加载数据,把数据加载到缓存中。

步骤

1、查询缓存是建立在二级缓存基础之上的
2、在hiberante.cfg.xml文件中

<!-- 
        开启查询缓存
     -->
    <property name="cache.use_query_cache">true</property>

3、编程
queryCache

qc
所以要想使用查询缓存,两次的hql语句必须一样。

分页

/**
     * 分页
     */
    @Test
    public void testDispage(){
        Session session = sessionFactory.openSession();
        Query query = session.createQuery("from Classes");
        query.setFirstResult(1);//起始位置
        query.setMaxResults(2);//每页显示的最大的记录数
        List<Classes> classesList = query.list();
        for(Classes classes:classesList){
            System.out.println(classes.getCid());
        }
        session.close();
    }

Query.list和query.iterator

Query.iterator
queryIterator

List是n+1条查询
先查询classes表中的所有的记录,再根据每一个cid查询student表
Query.iterator是需要的时候才要加载数据

重点
1、hiberante的加载流程
2、hibernate的关系
3、inverse和 cascade
4、hibernate如何提高性能
1、一对多,多的一方维护关系
2、懒加载
3、抓取策略
4、Hql语句
5、Query.list方法和query.iterator方法的恰当的使用
6、客户端代码如何写

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值