(笔记)SSH之Hiberate

*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支持的函数

max、min、avg、sum、count、upper、lower

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开始
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值