Hibernate笔记

来源:互联网 发布:德国开山刀网站淘宝 编辑:程序博客网 时间:2024/06/17 04:43

—- 本文例子中存在user,userinfo,linkman表,且关联

Hibernate入门代码

//加载src目录下的配置文件Configuration configuration = new Configuration().configure();//创建SessionFactory对像SessionFactory factory = config.buildSessionFactory();//创建Session对象Session session = factory.openSession();//开启事务Transaction tr = session.beginTransaction();User user = new User();user.setUsername("某某");session.save(user);tr.commit();session.close();factory.close();

Hibernate映射配置文件模型

<hibernate-mapping>    <class name="JavaBean全限定名" table="表名" catelog="数据库名称:基本省略不写">        <id name="JavaBean属性名" column="数据库表字段名" length="字段长度:数据库未创建时最好指定">            <generator class="主键生成策略">            <!--             * increment':适用于short,int,long作为主键,不是数据库自动增长            * identity:适用于short,int,long作为主键,必须用在支持自增的数据库            * sequence:适用于short,int,long作为主键,序列增长,oracle可用            * uuid:适用于char,varchar类型的主键,随机字符串            * native:适用于short,int,long作为主键,本地策略,自动匹配主键生成策略            * assigned:手动管理主键             -->        </id>        <version name="JavaBean中的version属性">        <property name="JavaBean属性名" column="数据库表字段名" length="长度:省略" type="类型:省略"/>        <!--         * Hibernatenate的数据类型        type="string"        * Java的数据类型             type="java.lang.String"        * 数据库字段的数据类型            <column name="name" sql-type="varchar">        -->    </class>    <!-- 在一对多,多对多的环境中,JavaBean中的集合需要手动new来初始化 -->    <!-- 一对多的配置 -->    <set name="JavaBean中集合名" cascade="级联保存" inverse="是否放弃维护外键">        <!--         -- cascade的取值        * none                  -- 不使用级联        * save-update           -- 级联保存或更新        * delete                -- 级联删除        * delete-orphan         -- 孤儿删除.(注意:只能应用在一对多关系)        * all                   -- 除了孤儿之外的所有        * all-delete-orphan     -- 所有情况        -->        <key column="外键字段名"></key>    </set>    <!-- 多对一的配置 -->    <many-to-one name="JavaBean属性名" class="属性的全路径" column="外键的字段"></many-to-one>    <!-- 多对多的配置,必须有一方放弃维护外键,否则会冲突报错 -->    <set name="集合的名称" table="中间表的名称" cascade="级联保存" inverse="是否放弃维护外键">        <key column="中间表的外键"/>        <many-to-many class="集合中对象的全路径" column="中间表的外键"></many-to-many>    </set></hibernate-mapping>

Hibernate核心配置文件

<hibernate-configuration>    <session-factory>        <property name="hibernate.connection.driver_class">数据库驱动</property>        <property name="hibernate.connection.url">数据库地址</property>        <property name="hibernate.connection.username">用户名</property>        <property name="hibernate.connection.password">密码</property>        <property name="hibernate.dialect">数据库方言</property>        <property name="hibernate.show_sql">显示sql:true</property>        <property name="hibernate.format_sql">格式化sql:true</property>        <property name="hibernate.hbm2ddl.auto">通过映射转成DDL语句</property><!--            * create        -- 每次都会创建新的表,测试时才用            * create-drop   -- 每次都会创建新的表,执行结束后删除表,测试时才用            * update        -- 如果有表使用原来的表,如果没有创建新的表,同事更新表结构            * validate      -- 如果有表使用原来的表,并校验映射配置文件与表结构是否一致,否则报错-->        <mapping resource="映射配置文件路径">    </session-factory></hibernate-configuration>

HIbernate查询之HQL

基本查询

session.createQuery("from JavaBean类名").list();

使用别名

session.createQuery("from JavaBean类名" a).list();
session.createQuery("select a from JavaBean类名" a).list();

排序查询

  • 升序
    session.createQuery("from JavaBean类名" order by id).list();
  • 降序
    session.createQuery("from JavaBean类名" order by id desc).list();

分页查询

Hibernate框架提供了两个方法
setFirstResult(a) //从哪条记录开始,如果查询的是第一条,值是0’
setMaxResults(b) //每页查询的记录条数’
session.createQuery(“from JavaBean类名”).setFirstResult(a).setMaxResults(b).list();

带条件的查询

  • setParameter(“?开始的位置,默认0开始”,”参数的值”);不用考虑参数的具体类型
  • 按位置绑定参数的条件查询(指定下标,默认从0开始)
  • 按名称绑定参数的条件查询(HQL中的?换成 :名称 的方式)
  • 示例代码
//按位置绑定参数的条件查询Query query = session.createQuery("from User where username like ? order by id desc");query.setParameter(0,"%某某%");//按名称绑定参数的条件查询Query query = session.createQuery("from User where username like :aaa order by id desc");query.setParameter("aaa","%某某%");

投影查询

只需要查询几个字段,不需要查询所有字段

//查询多个字段Query query = session.createQuery("select u.username,u.uid,u.user_level from User u");List<User> list = query.list();/*查询两个字段在持久化类(JavaBean)中提供对应字段的构造方法*/Query query = session.createQuery("select new User(u.uid,u.username) from User u where username");List<User> list = query.list();

聚合函数查询

//获取总记录数(count(*))List<Number> list = session.createQuery("select count(u) from User u").list;Long count = list.get(0).longValue();//获取某一列数据的和List<Number> list = session.createQuery("select sum(u.uid) from User u").list;Long count = list.get(0).longValue();

QBC检索方式

QBC:Query By Criteria 按条件进行查询,完全面向对象

1. 简单查询

Criteria criteria = session.createCriteria(User.class);List<User> list = criteria.list;

2.排序查询

使用addOrder方法

Criteria criteria = session.createCriteria(User.class);criteria.addOrder(Order.desc("uid"));List<User> list = criteria.list;

3.分页查询

Criteria criteria = session.createCriteria(User.class);criteria.addOrder(Order.desc("uid"));criteria.setFirstResult(0);criteria.setMaxResults(3);List<User> list = criteria.list;

4.条件查询

使用add方法,使用Restriction工具类来设置条件

方法 应用 Restriction.eq 相等 Restriction.gt 大于 Restriction.ge 大于等于 Restriction.lt 小于 Restriction.le 小于等于 Restriction.between 在之间 Restriction.like 模糊查询 Restriction.in 范围 Restriction.and 并且 Restriction.or 或者
Criteria criteria = session.createCriteria(User.class);criteria.addOrder(Order.desc("uid"));criteria.add(Restriction.or(Restriction.eq("username","某某"),Restriction.gt("uid",3L)));List<User> list = criteria.list;

5.聚合函数

Projection接口

Criteria criteria = session.createCriteria(User.class);criteria.setProjection(Projection.rowCount());List<Number> list = criteria.list;Long count = list.get(0).longValue();

若不再使用聚合,需要置空
criteria.setProjection(null);

6.离线条件查询

不需要使用Session对象,只是在查询的时候使用Session对象即可

//创建离线条件查询对象DetachedCriteria criteria = DetachedCriteria.forClass(User.class);criteria.add(Restrictions.eq("username","某某"));List<User> list = criteria.getExecutableCriteria(session).list();

7.多表查询

内连接,默认返回Object数组

//select * from user a,userinfo b where a.uid = b.uidQuery query = session.createQuery("from User u inner join u.userinfo");List<Object[]> list = query.list();//有重复结果

迫切内连接,返回实体对象

//select * from user a,userinfo b where a.uid = b.uidQuery query = session.createQuery("from User u inner join fetch u.userinfo");List<User> list = query.list();//放入set集合中去重复Set<User> set = new HashSet<User>(list);

外联接from User u left/right join fetch u.userinfo


HIbernate查询之SQL

Query query = session.createSQLQuery("select * from user where username = ?");query.setParameter(0,"某某");//把数据封装到指定实体对象query.addEntity(User.class);List<User> list = query.list();

HIbernate查询之延迟加载

先获取到代理对象,当真正使用到该对象中的属性时,才会发送sql语句,提升程序的性能

1.类级别的延迟加载

hibernate默认已开启延迟加载,需使用session.load方法

//没有延迟加载User user = session.get(User.class,1L);String username = user.getUsername(); //使用session.load方法,默认使用延迟加载User user = session.load(User.class,1L); //不发送sql语句//Hibernate.initialize(user);初始化对象,延迟加载失效String username = user.getUsername(); //发送sql语句

<class>标签上配置lazy="false",使延迟加载失效

2.关联级别的延迟加载

查询某个用户,当查看用户详情时是否延迟加载,User与Linkman

//User与Linkman相关联,默认开启延迟加载User user = session.get(User.class,1L); //发送sql语句,查询user,若不延迟也会查询linkmanInteger size = user.getLinkman().size(); //发送sql语句,查询linkman

3.关联级别的优化策略

<set>标签上使用fetchlazy属性
fetch 属性 : 查询语句的形式
lazy 属性 : 是否采用延迟加载

开发中正常使用默认值

  • fetch的取值
    • select: 默认,发送查询语句
    • join : 连接查询,发送的是一条迫切左外连接!!!配置了join,lazy就失效了
    • subselect: 子查询,发送一条子查询查询其关联对象
  • lazy的取值
    • true : 默认,延迟
    • false : 不延迟
    • extra : 及其懒惰,user.getLinkman().size()只会使用count(*)查询数量,不会查询整个linkman

<many-to-one>标签上使用fetchlazy属性

  • fetch的取值
    • select : 默认,发送查询语句
    • join : 连接查询,发送的是一条迫切左外连接!!!配置了join,lazy就失效了
  • lazy的取值
    • false : 不延迟
    • proxy : 默认值,使用代理,由另一端<class>上的lazy决定,两者取值相同