黑马程序员技术交流社区

标题: [石家庄校区]hibernate框架笔记总结 [打印本页]

作者: 黑马7期班长    时间: 2018-6-27 15:34
标题: [石家庄校区]hibernate框架笔记总结
本帖最后由 小石姐姐 于 2018-6-29 11:17 编辑

[石家庄校区]hibernate框架笔记总结


ORM(Object-Relation-Mapping)框架:对象关系映射框架
是对JDBC的轻量封装
通过操作对象来操作数据库
jar包
required包
驱动包
日志包,日志配置文件(放到src下)
配置文件
映射配置文件

类名.hbm.xml
与实体类放到同一个包下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.cyahua.domain.Customer" table="t_customer" catalog="hibernatetest">
        <id name="id" column="id" length="11">
            <generator class="native"></generator>
        </id>
        <property name="name" column="name" length="20"></property>
        <property name="address" column="address" length="50"></property>
    </class>
</hibernate-mapping>
统一声明包名,这样在<class>中就不需要写类的全名.
关于<class>标签配置
name属性:类的全名称
table 表的名称,可以省略,这时表的名称就与类名一
catalog属性:数据库名称 可以省略.如果省略,参考核心配置文件中url路径中的库名称
关于<id>标签
首先它必须存在。<id>是用于建立类中的属性与表中的主键映射。
name中的属性名称
column表中的主键名称 column它也可以省略,这时列名就与类中属性名称一致
length 字段长度
type属性 指定类型
<generator>它主要是描述主键生成策略.
关于<property>标签
它是描述类中属性与表中非主键的映射关系
核心配置文件
hibernate.cfg.xml
hibernate.properties
放到src下


hibernate中的数据类型

标准SQL数据类型
Java数据类型
Hibernate数据类型
TINYINT
byte、java.lang.Byte
byte
SMALLINT
short、java.lang.Short
short
INGEGER
int、java.lang.Integer
integer
BIGINT
long、java.lang.Long
long
FLOAT
float、java.lang.Float
float
DOUBLE
double、java.lang.Double
double
NUMERIC
java.math.BigDecimal
big_decimal
CHAR(1)
char、java.lang.Character
character
BIT
boolean、java.lang.Boolean
boolean
VARCHAR
java.lang.String
string
CHAR(1)('Y'或'N')
boolean、java.lang.Boolean
yes_no
CHAR(1)('Y'或'N')
boolean、java.lang.Boolean
true_false
DATE
java.util.Date、java.sql.Date
date
TIME
java.util.Date、java.sql.Time
time
TIMESTAMP
java.util.Date、java.sql.Timestamp
timestamp
TIMESTAMP
java.util.Calendar
calendar
DATE
java.util.Calendar
calendar_date
VARBINARY、BLOB
byte[]
binary
CLOB
java.lang.String
text
VARBINARY、BLOB
java.io.Serializable
serializable
CLOB
java.sql.Clob
clob
BLOB
java.sql.Blob
blob
VARCHAR
java.lang.Class
class
VARCHAR
java.util.Locale
locale
VARCHAR
java.util.TimeZone
timezone
VARCHAR
java.util.Currency
currency

hibernate工作原理
由hibernate.cfg.xml中的<mappingresource="com/xx/User.hbm.xml"/>读取解析映射信息。
通过config.buildSessionFactory();//得到sessionFactory。
sessionFactory.openSession();//得到session。
session.beginTransaction();//开启事务。
persistent operate;
session.getTransaction().commit();//提交事务
关闭session;
关闭sessionFactory;

c3p0连接池配置
<!-- 设置连接提供者 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>

<property name="hibernate.c3p0.max_size">20</property> <!-- 最大连接数 -->
<property name="hibernate.c3p0.min_size">5</property> <!-- 最小连接数 -->
<property name="hibernate.c3p0.timeout">50</property> <!-- 超时等待时间 -->
<property name="hibernate.c3p0.idle_test_period">3000</property> <!--空闲连接时间 -->
Seesion
如何解决session的线程不安全问题?
在方法内部创建、使用即可
常用api
sessionFactory.openSeesion();需要手动调用close()方法关闭
sessionFactory.getCurrentSession();提交事务或回滚时自动close,需要在核心配置文件中配置如下属性
<property name="hibernate.current_session_context_class">thread</property>
save()
update()
delete()
get()
load()
saveOrUpdate()
createQuery()操作hql
createSQLQuery()操作本地sql
createCriteria()完成条件查


Transaction
开启事务:        session.beginTransaction()
提交: commit(),session.getTransaction().commit()
回滚 rollback(),session.getTransaction().rollback()
如果没有开启事务,那么session的每一个操作都是一个事务,且事务默认不提交
一对一关系添加关联映射1.在任意一方添加外键,指向另一方的主键.
2.两个主键一致.

在pojo中设置私有对象字段.

class Employee{
    private Archives archives;
}
class Archives{
    provate Employee employee;
}

对多关系添加关联映射(也叫多对一)
1.在多的一方创建外键列指向一的一方的主键.

class Cutomer{
    private Set<Order> orders;
}
class Order{
    private Costomer costomer;
}
一对多的hbm映射文件costomer.hbm.xml配置<!--客户中的订单是多,所以是one-to-many--><set>        <key column="和多的一方共同维护的外键列名称"></key>        <!--指明客户pojo中订单的泛型-->        <one-to-many class="订单的全类名"></one-to-many></set>

order.hbm.xml配置<!--order是多所以用的是many-to-many-->                                                                                                                                        //一般多的一方维护外键<many-to-one name="当前pojo中的客户对象名称" class="指明客户对象类的全路径" column="创建外键列的名称"></many-to-one>

封装数据时候,我们都是双向关联,这种写法比较繁琐...

双向关联测试问题:必须配置表自自动刷新表结构<property name="hibernate.hbm2ddl.auto">update</property>我创建了一个客户,客户有三个订单,相互创建关系,如果在配置文件中不配置cascade="save-update"属性也可以执行成功,首先插入了一个costomer对象,让后三个订单,最后更新订单表中的外键,这样的话,属实浪费资源.问题:cascade的作用是什么?问题:could not execute statement        无法执行语句

单项关联测试org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: cn.hibernate.domain.Customer如果不设置 cascade="save-update"就会报上面错误,代表一个持久化对象关联了一个瞬时对象一般在多的一方设置cascade="save-update",因为多的一方设置delete,他会将一的一方也会删除,将一的一方删除,随之又会将一的一方的所有关联字段都会删除.

级联删除在操作级联删除的前提条件必须将设置级联,这样保证数据完整性.在一的一方设置 cascade="delect" 级联删除在删除用户时候,底层是先查询出来该用户,在查询该所属该用户的所有订单,先设置为null,然后在逐个删除.

注解开发如何配置实体类@Entity@Table(name="表名称",catalog="数据库名称")@id@GeneraterValue(strategy=GenerationType.IDENTITY)@Column(name="列名称",length=.nullable="true")@Temporal//日期@Transient 忽略字段如果不想在数据库中生成那个字段

主键生成策略为UUID@ID@genericGenerator(name="myuuid",strastegy="uuid").....

Hibernate检索方式概述1.对象导航图检索方式通过映射关系,通过导航方式,检索他关联的持久化对象信息.例如Customer c = session.get(Customer.class,2);c.getOrders().size();

2.oid检索方式Session.get(Customer.class,3);session.load(Order.class,1);通过先获取oid操作持久化对象.

3.hql检索方式1.重点:hql基本语法 String sql= "from Customer";Query query = session.createQuery(sql);List<Customer> list = query.list();2.排序 desc降序 asc升序String sql ="from Order order by money";(根据对象属性)3.条件查询(查询价格大于2000)String sql = "from Order where  money >?";Qeruy query = session.createQuery(sql);query.setParameter(0,/范围/);query.list();4.分页检索String sql="form Order";Query query = session.createQuery(sql);query.setFirstResult((2-1)*9);query.setMaxResult(9);List<Order> list = query.list(); 5.分组String sql = "select sum(money) from Order group by c";(根据c)6.投影查询(查找指定的字段)String sql = "select new Customer(name,address) from Costomer";注意:必须提供无参构造和指定的构造.7.命名查询:现将hql语句定义出来,通过Session.getNameQuery("名称");声明位置:1.在对应的hbl.xml中配置<query name="名称">        from Costomer</query>2.在实体中定义方法@Qeruy(name="方法名称","");

4.qbc检索方式query by criteria,一种更加面想对象的检索方式criteria对象qbc步骤:1.得到对象session.createCriteria();2.设定条件3.调用list()1)基本检索@Test//查询所有客户 public void Test1(){    Session session = HibernateUtils.openSession();    session.beginTransaction();    Criteria criteria = session.createCriteria(Customer.class);    List<Custeria>list = criteria.list();    session.getTransaction().commit();    session.close();}2)排序检索@Test//根据订单价格排序puiblic void Test(){    Session session = HibernateUtils.openSession();    session.beginTransaction();    Criter criter = session.createCriteria(Order.class);    criter.addOder(org.hibernate.criterion.Order.desc("money"));    List<Order> list = criter.list();    System.out.println(list);    session.getTransaction().commit();    session.close();}3)条件检索@Test//查询名称叫张某public void Test3(){    Session session = HibernateUtils.openSession();    session.beginTransaction();           //查询名称叫张_的人           Session session = session.createCriteria(Customer.calss);           Criterion like = Restrictions.like("name","张_");           criter.add(like);           Customer customer = criteria.list();&criteria.uniqueResult();           System.out.println(customer);    session.getTransaction().commit();    session.close();}多个条件检索:!!!统计查询Object obj = criteria.setProjection(Projections.rowCount()).uniqueResult();System.out.prinln(obj) ---204)离线条件查询DetachedCriteria dc = DetachedCriteria.()

三种主键开发一对一注解两种外键映射(主要),主键映射,在任意一方添加一列作为外键在一方创建外键列@JoinColumn(name="外键名称")在另一方放弃对外键列的维护@OneToOne(targetEntity=目标实体.class,mappedBy="另一方的字段类")

一对多主键一的一方配置@OneToMany(targetEntity=多的一方的.class,mappedBy="外键交给多的一方管理",orphanRemoval)多的一方配置@ManyToOne(targetEntity="一的一方的.class")@JoinColumn(name="外键名称")级联操作根据实际情况而定@Cascade(CascadeType.SAVE-UPDATE)

事务四种隔离级别READ_UNCOMMITED 读取未提交,它引发所有的隔离问题READ_COMMITTED 读已提交,阻止脏读,可能发生不可重复读与虚读.REPEATABLE_READ 重复读 阻止脏读,不可重复读 可能发生虚读SERIALIZABLE 串行化 解决所有问题 不允许两个事务,同时操作一个目标数据。 (效率低下)ORACLE 默认的是事务隔离级别 READ_COMMITTEDMYSQL 默认的事务隔离级别 REPEATABLE_READ









作者: ziyouxingzhe    时间: 2019-6-14 15:08
不错,很详细




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2