(笔记)SSH之Hiberate

来源:互联网 发布:淘宝阿迪达斯高仿店 编辑:程序博客网 时间:2024/05/21 04:02

*1.hiberate步骤:
1)加载包(Hibernate的包、数据库驱动包).
这里写图片描述
2)写hibernate.cfg.xml和hibernate映射文件(类—表);
3)基本代码

Configuration cfg = new Configuration().configure() #加载配置文件
SessionFactory sessionFactory = cfg.buildSessionFactory(); #获取sessionFactory地第一种方式
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();SessionFactory sessionFactory = cfg.buildSessionFactory(sr);  #获取sessionFactory地第二种方式
Session session = sessionFactory.openSession(); #通过sessionFactory获取session
session.beginTransaction(); #开启事务
session.getTransaction().commit(); #提交事务
session.close();  #关闭session

2.Hiberate操作规范
1)获取session。
2)开启事务。
3)业务实现(增删改查)
4)事务提交
5)捕获异常
6)finally中关闭事务、关闭session。

3.configuration
configuration()获取Hiberate的配置
通过sessionFactory的getCurrentSession方法获取session:
1)必须在hibernate.cfg.xml配置文件中配置CurrentSession的级别。current_session_context_class属性指定,thread线程级别,jta用于分布式事务。
2)CurrentSession获取事务一旦执行commit或者rollback操作session会自动关闭。
3)CurrentSession执行get、load方法时必须通过事务执行。

4.Session

     isConnected()连接是否建立     isOpen() 连接是否打开(可用)     get(Class clazz, Serializable id) 从数据库获取指定对象     load(Class theClass, Serializable id) 从数据库获取指定对象

get、load的不同:
1)get立刻发送sql语句查询,如果没有要查询的对象返回null。
2)load是懒加载:不会立刻发送sql,当用到查询对象时在发送sql语句。在发送sql语句之前会得到一个代理对象。

     save(Object object) 将对象存入数据库     saveOrUpdate(Object object)将对象存入数据库,如果对象存在执行update操作。     update(Object object)  执行update操作。
<class name="Person" table="t_person" dynamic-update="true">    <property name="age" update="false"/>    dynamic-update="true":只更新修改过的属性    update="false":该属性不更新    delete(Object object)执行delete操作。    merge(Object object)    persist(Object object)    beginTransaction();开启一个事物,返回一个事物对象Transaction。    getTransaction().commit();获取当前session的事物,并提交。

save方法:立刻执行insert语句,返回标识符ID(持久化标识符)
persist方法:不一定会立刻执行insert语句,不会返回持久化标识。
saveOrUpdate方法:当数据库中没有该对象就执行insert,已经有该对象就执行update。当session中有两个具备相同持久化id的对象时会抛异常。
merge(obj)方法:和saveOrUpdate作用一样,当session中有多个相同持久化id的对象时会将obj的属性更新到所有要修改的对象。

5.对象的三个状态
1)瞬态
仅存在于内存中,数据库没有对应的记录。
2)持久态
通过session获取的对象。该对象与数据库中的记录相对应。当对象处于持久化状态时,对对象的修改会直接影响数据库中的记录。
3)托管态
数据库中有对应记录,该对象没有纳入到session的管理中。
瞬态转持久化:save、persist
托管转持久化:update
持久化转瞬态:delete

6、Transaction简单事物处理

beginTransaction()isActive()rollback()commit()

7.hibernate创建实体对象和表:
1)POJO对象——>表,先对象后表。
2)DB表——>POJO对象,先表后对象。

8.hibernate自动建表:
1)通过SchemaExport来创建。
2)通过hibernate.cfg.xml配置配置hbm2ddl.auto属性实现自动建表。hbm2ddl.auto属性可以设置的值create建表(每次操作都会删除旧表建立新表),update当hibernate-mapping映射文件中的类属有修改的时候自动更新数据库的表字段。

9.通过MyEclipse来生成逆向工程。
1)database视图中添加数据库连接。
2)建立java项目。
3)建立UserLib
4)选择Myeclipse菜单,add Hibernate。
5)db视图,选择要生成类的表,右键——>Hibernate reverse

*10.hibernate关系映射
1)单项关联
1 vs 1 外键关联:

<many-to-one name="类中的属性名" class="属性类型" column="表的外键字段名" unique="必须是true" cascade="级联操作save、save-update、delete、all"></many-to-one>

主键关联:以双方的主键做关联,没有外键字段。在拥有另外一个对象的对象上设置

<one-to-one name="属性名" class="属性的类型" constrained="必须是true"></one-to-one> id生成策略<generator class="foreign">    <param name="property">one-to-one中的属性</param></generator>

1 vs n:一的一端

<set name="persons"  cascade="save-update">   <key column="设置Person的外键字段"></key>   <one-to-many class="Person" /></set>

n vs 1:在多的一端配置

<many-to-one name="room" class="Room" not-null="true" ></many-to-one>

n vs n:一端配置

<set name="users" table="power_user" cascade="save-update">     <key column="pid"></key>     <many-to-many class="User" column="uid"></many-to-many></set>

2)双向关联
1 vs 1

有外键的表的对象设置:<many-to-one name="类中的属性名" class="属性类型" column="表的外键字段名" unique="必须是true" cascade="级联操作save、save-update、delete、all"></many-to-one>无外键的一端设置<one-to-one name="类中的属性名" class="属性类型" property-ref="有外键的对象的外键属性"></one-to-one>主键双向关联一端配:<one-to-one name="属性名" class="属性的类型" constrained="必须是true"></one-to-one> id生成策略 <generator class="foreign">    <param name="property">one-to-one中的属性</param> </generator>主键双向关联另一端配:<one-to-one name="属性名" class="属性的类型" constrained="必须是true"></one-to-one> id生成策略不变

1 vs n(n vs 1)

多的一端:<many-to-one name="room" class="Room" not-null="true" ></many-to-one>一的一端<set name="persons" inverse="true" cascade="save-update">   <key column="多的一端的外键字段"></key>   <one-to-many class="Person" /></set>PS:一旦一的一端使用了inverse(控制反转),一的一端就失去了控制权(由多的一端去发送sql语句)。如果使用了控制反转,在一的一端不应该做任何操作。

n vs n

两头配置<set name="users" table="power_user" cascade="save-update">    <key column="pid"></key>    <many-to-many class="User" column="uid"></many-to-many></set>PS:一端设置级联,另一端要inverse=“true”。

11.区分单向和双向关联:
1)A类中的属性是否包含另一个实体类B,如果A类中有B类对象B类中没有A类对象,就是单向关联。如果A类中有B类对象,B类中有A类对象,就是双向关联。
2)表中看外键。A表中有外键映射B表主键,B表没有外键,就是单向关联。A表中有外键映射B表主键,B表有外键映射A表的主键,就是双向关联。还有其他情况不在举例。

12.区分多的一端与一的一端:
1)看表。表中外键字段允许重复的是多的一端。不允许重复的是一的一端。
2)看java对象。有Set集合的是一,有单个对象是多(一对一除外)。

13.hibernate继承映射
1)所有类一张表(子类、父类在一张表)
父类配置xxx.hbm.xml映射文件

<class name="Person" table="ex_person">        <id name="id" column="pid">            <generator class="native">            </generator>        </id>        <!--鉴别器,用来区分表中的记录是哪个子类-->        <discriminator column="自定义字段名" type="string"></discriminator>        <property name="name"  length="20" not-null="true" />       <!--对子类的描述-->        <subclass name="类名" discriminator-value="鉴别器的鉴别标识(自定义)">            <!-- 子类的属性-->            <property name="banji"></property>       </subclass>       <subclass name="Worker" discriminator-value="w">            <property name="job"></property>       </subclass>    </class>

2)每个类一张表(父类一张表、子类一张表)

<class name="Person" table="ex_person">        <id name="id" column="pid">            <generator class="native">            </generator>        </id>        <property name="name"  length="20" not-null="true" />        <!--对子类的描述-->        <joined-subclass name="Student" table="t_student">            <!--子表的主键,不是类中的属性,与父类的主键自动做外键映射-->            <key column="sid"></key>            <property name="banji"></property>        </joined-subclass>         <joined-subclass name="Worker" table="t_worker">            <key column="wid"></key>            <property name="job"></property>        </joined-subclass></class>

3)父类子类一张表(父类属性和子类属性一张表)

<!--将父类声明为抽象,不建立父表--><class name="Person"  abstract="true">        <id name="id" column="pid">            <generator class="uuid">            </generator>        </id>        <property name="name"  length="20" not-null="true" />        <union-subclass name="Student" table="t_student">            <property name="banji"></property>        </union-subclass>        <union-subclass name="Worker" table="t_worker">                <property name="job"></property>        </union-subclass></class>

list映射

<list name="类中list的属性名" table="t_teacher_student" cascade="save-update">    <key column="自定义主键名"></key>    <index column="自定义排序字段"></index>    <many-to-many class="Student" column="s_id"></many-to-many></list> 

Map集合映射

<map name="类中Map属性名" table="m_map">    <key column="表的主键"></key>    <map-key column="字段名(保存map的key)" type="string"></map-key>    <element column="字段名(保存map的value)" type="string"></element></map>

*14HQL(hibernate查询语言)
1)HQL查询

通过session获取Query对象,通过Query的list方法获得查询结果。session.createQuery("HQL语句").list();

2)HQL说明

from 类名;将获取到指定对象的所有记录,返回的list集合自动封装为指定类的对象select 属性名1,属性名2,....属性n  from 类名;返回的list集合的每一个集合对象是一个Object数组select new 构造方法(参数查询字段) from 类名;select new Person(name,address) from Person;select new com.vo.PersonVO(name,address) from Person;返回new的对象的集合,如果new的对象不是查询对象(from后面的对象),要用完全限定名;

3)条件查询

session.createQuery("from Person  where name=?").setParameter(0, "scott3").list();session.createQuery("from Person  where name=:n").setParameter("n", "scott3").list();session.createQuery("from Person  where name=:n").setString("n", "scott3").list();session.createQuery("from Person  where name like :n").setParameter("n", "s%").list();session.createQuery("from Person  where age>?").setInteger(0, 30).list();session.createQuery("from Person  where id>10 and age>30").list();session.createQuery("select p.name,a.addr from Person p,Address a where p.address.id=a.id").list();session.createQuery("from Person where id in :id").setParameterList("id", list).list();

3)HQL支持的函数

maxminavgsum、count、upperlower

4)Iterator和list

session.createQuery("from Person").iterate();session.createQuery("from Person").list();
  • list不查询hibernate缓存,直接发送sql语句到数据库

  • iterator先发送sql语句查询对象的id,根据id查找hibernate缓存,如果有直接从缓存获取,没有则每个id发送一条sql查询,将查询结果加入缓存。

5)HQL的insert、update、delete
不推荐使用hql做增加、删除、修改。

  • insert相当于复制,对于有主外键关联关系的对象支持不好。
  • update和delete会有缓存问题。
insert into TempTable(msg) select t.msg from TempTable t where id=1#增加delete Person where id=6#删除update Person set name=? where id=10#更新

6)分组,排序,分页

select count(id) from Person group by age #分组from Person order by id desc  #排序session.createQuery("from Person").setMaxResults(int一页显示多少条).setFirstResult(页数*一页多少条).list(); #分页,页数从0开始