您的位置:首页 > 其它

hibernate学习记录

2018-03-13 22:23 246 查看
Class.hbm.xml

关系配置
<class>
<!-- 集合,一对多关系,在配置文件中配置 -->
<!--
name属性:集合属性名
column属性: 外键列名
class属性: 与我关联的对象完整类名
-->
<!--
级联操作:   cascade
save-update: 级联保存更新
delete:级联删除
all:save-update+delete
级联操作: 简化操作.目的就是为了少些两行代码.
结论: 简化操作.一定要用,用save-update,不建议使用delete.
-->
<!-- inverse属性: 配置关系是否维护.
true: customer不维护关系
false(默认值): customer维护关系

inverse属性: 性能优化.提高关系维护的性能.
原则: 无论怎么放弃,总有一方必须要维护关系.
一对多关系中: 一的一方放弃.也只能一的一方放弃.多的一方不能放弃.
-->
<!--
lazy属性: 决定是否延迟加载
true(默认值): 延迟加载,懒加载
false: 立即加载
extra: 极其懒惰
fetch属性: 决定加载策略.使用什么类型的sql语句加载集合数据
select(默认值): 单表查询加载
join: 使用多表查询加载集合
subselect:使用子查询加载集合
-->
<!-- batch-size: 抓取集合的数量为3.
抓取客户的集合时,一次抓取几个客户的联系人集合.
-->
<set name="linkMens" lazy="" fetch="" batch-size= "" inverse="true" cascade="delete"  >
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>
<!-- 多对一 -->
<!--
name属性:引用属性名
column属性: 外键列名
class属性: 与我关联的对象完整类名
-->
<!--
级联操作:   cascade
save-update: 级联保存更新
delete:级联删除
all:save-update+delete
级联操作: 简化操作.目的就是为了少些两行代码.
结论: 简化操作.一定要用,用save-update,不建议使用delete.
-->
<!-- 多的一方: 不能放弃维护关系的.外键字段就在多的一方.  -->
<many-to-one name="customer" column="lkm_cust_id" class="Customer"  >
</many-to-one>
<!-- 多对多关系表达 -->
<!--
name: 集合属性名
table: 配置中间表名
key
|-column:外键,别人引用"我"的外键列名
class: 我与哪个类是多对多关系
column:外键.我引用比人的外键列名
-->
<!-- cascade级联操作:
save-update: 级联保存更新
delete:级联删除
all:级联保存更新+级联删除
结论: cascade简化代码书写.该属性使不使用无所谓. 建议要用只用save-update.
如果使用delete操作太过危险.尤其在多对多中.不建议使用.
-->
<set name="roles" table="sys_user_role" cascade="save-update" >
<key column="user_id" ></key>
<many-to-many class="Role" column="role_id" ></many-to-many>
</set>
<!-- 使用inverse属性
true: 放弃维护外键关系
false(默认值):维护关系

结论: 将来在开发中,如果遇到多对多关系.一定要选择一方放弃维护关系.
一般谁来放弃要看业务方向. 例如录入员工时,需要为员工指定所属角色.
那么业务方向就是由员工维护角色. 角色不需要维护与员工关系.角色放弃维护
-->
<set name="users" table="sys_user_role" inverse="true" >
<key column="role_id" ></key>
<many-to-many class="User" column="user_id" ></many-to-many>
</set>
</class>


关联例子

//3操作
Customer c = new Customer();
c.setCust_name("课");
LinkMan lm1 = new LinkMan();
lm1.setLkm_name("王");
LinkMan lm2 = new LinkMan();
lm2.setLkm_name(
11f5c
"刘");
//表达一对多,客户下有多个联系人
(如果客户放弃维护与联系人的关系. 维护关系的代码可以省略)
c.getLinkMens().add(lm1);
c.getLinkMens().add(lm2);
//表达对对对,联系人属于哪个客户
lm1.setCustomer(c);
lm2.setCustomer(c);
session.save(c);
session.save(lm1);(未级联都得保存)
session.save(lm2);
//3操作
//1> 获得要操作的客户对象
Customer c = session.get(Customer.class,1l);
//2> 创建联系人
LinkMan lm1 = new LinkMan();
lm1.setLkm_name("好");
//3> 将联系人添加到客户,将客户设置到联系人中
c.getLinkMens().add(lm1);
lm1.setCustomer(c);
//4> 执行保存
session.save(lm1);
//3操作
//1> 获得要操作的客户对象
Customer c = session.get(Customer.class,1l);
//2> 获得要移除的联系人
LinkMan lm = session.get(LinkMan.class, 3l);
//3> 将联系人从客户集合中移除
c.getLinkMens().remove(lm);
lm.setCustomer(null);


Customer.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">
<!-- 配置表与实体对象的关系 -->
<!-- package属性:填写一个包名.在元素内部凡是需要书写完整类名的属性,可以直接写简答类名了. -->
<hibernate-mapping package="cn.example.domain" >
<!--
class元素: 配置实体与表的对应关系的
name: 完整类名
table:数据库表名
-->
<class name="Customer" table="cst_customer" >
<!-- id元素:配置主键映射的属性
name: 填写主键对应属性名
column(可选): 填写表中的主键列名.默认值:列名会默认使用属性名
type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
每个类型有三种填法: java类型|hibernate类型|数据库类型
not-null(可选):配置该属性(列)是否不能为空. 默认值:false
length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度
-->
<id name="cust_id"  >
<!-- generator:主键生成策略.就是每条记录录入时,主键的生成规则.(7个)
identity : 主键自增.由数据库来维护主键值.录入时不需要指定主键.
sequence: Oracle中的主键生成策略.
increment(了解): 主键自增..
hilo(了解): 高低位算法.主键自增.由hibernate来维护.开发时不使用.
native:hilo+sequence+identity 自动三选一策略.
uuid: 产生随机字符串作为主键. 主键类型必须为string 类型.
assigned:自然主键生成策略. hibernate不会管理主键值.由开发人员自己录入.

-->
<generator class="native"></generator>
</id>
<!-- property元素:除id之外的普通属性映射
name: 填写属性名
column(可选): 填写列名
type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
每个类型有三种填法: java类型|hibernate类型|数据库类型
not-null(可选):配置该属性(列)是否不能为空. 默认值:false
length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度
-->
<property name="cust_name" column="cust_name" >
<!--  <column name="cust_name" sql-type="varchar" ></column> -->
</property>
<property name="cust_source" column="cust_source" ></property>
<property name="cust_industry" column="cust_industry" ></property>
<property name="cust_level" column="cust_level" ></property>
<property name="cust_linkman" column="cust_linkman" ></property>
<property name="cust_phone" column="cust_phone" ></property>
<property name="cust_mobile" column="cust_mobile" ></property>

</hibernate-mapping>


hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--
#hibernate.dialect org.hibernate.dialect.MySQLDialect
#hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
#hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
#hibernate.connection.driver_class com.mysql.jdbc.Driver
#hibernate.connection.url jdbc:mysql:///test
#hibernate.connection.username gavin
#hibernate.connection.password
-->
<!-- 数据库驱动 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 数据库url -->
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_32</property>
<!-- 数据库连接用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 数据库连接密码 -->
<property name="hibernate.connection.password">1234</property>
<!-- 数据库方言
不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成.
sql99标准: DDL 定义语言  库表的增删改查
DCL 控制语言  事务 权限
DML 操纵语言  增删改查
注意: MYSQL在选择方言时,请选择最短的方言.
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

<!-- #hibernate.show_sql true
#hibernate.format_sql true
-->
<!-- 将hibernate生成的sql语句打印到控制台 -->
<property name="hibernate.show_sql">true</property>
<!-- 将hibernate生成的sql语句格式化(语法缩进) -->
<property name="hibernate.format_sql">true</property>
<!--
## auto schema export  自动导出表结构. 自动建表
#hibernate.hbm2ddl.auto create      自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用)
#hibernate.hbm2ddl.auto create-drop 自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用)
#hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
#hibernate.hbm2ddl.auto validate    校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败.
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 指定hibernate操作数据库时的隔离级别
#hibernate.connection.isolation 1|2|4|8
0001    1   读未提交
0010    2   读已提交
0100    4   可重复读
1000    8   串行化
-->
<property name="hibernate.connection.isolation">4</property>
<!-- 指定session与当前线程绑定 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 引入orm元数据
路径书写: 填写src下的路径
-->
<mapping resource="cn/example/domain/Customer.hbm.xml" />

</session-factory>
</hibernate-configuration>


API:

Configuration功能: 配置加载类.用于加载主配置,orm元数据加载

(Configuration).configure():读取指定主配置文件 => 空参加载方法,加载src下hibernate.cfg.xml文件

根据配置信息,创建 SessionFactory对象

SessionFactory sf = conf.buildSessionFactory();

SessionFactory功能: 用于创建操作数据库核心对象session对象的工厂.

简单说功能就一个—创建session对象

注意:1.sessionfactory 负责保存和使用所有配置信息.消耗内存资源非常大.

2.sessionFactory属于线程安全的对象设计.

结论: 保证在web项目中,只创建一个sessionFactory.

打开一个新的session对象

Session session =sf.openSession();

获得一个与线程绑定的session对象

Session session =sf.getCurrentSession();

session对象功能: 表达hibernate框架与数据库之间的连接(会话).session类似于JDBC年代的connection对象. 还可以完成对数据库中数据的增删改查操作.session是hibernate操作数据库的核心对象

session获得操作事务的Transaction对象

session.save(class);增

session.delete(class);删

session.update(class);改

session.saveorupdate(class);

session.get(Customer.class, 1l);查

session.load(Customer.class, 1l);查使用时加载

获得操作事务的tx对象(未开启事物,建议使用下一种)
Transaction tx = session.getTransaction();
开启事务并获得操作事务的tx对象(建议使用)
Transaction tx2 = session.beginTransaction();


例子:

public void fun(){
//1 创建,调用空参构造
Configuration conf = new Configuration().configure();
//2 根据配置信息,创建 SessionFactory对象
SessionFactory sf = conf.buildSessionFactory();
//3 获得session
Session session = sf.openSession();
//4 session获得操作事务的Transaction对象
//获得操作事务的tx对象
//Transaction tx = session.getTransaction();
//开启事务并获得操作事务的tx对象(建议使用)
Transaction tx2 = session.beginTransaction();
//----------------------------------------------
//1 获得要修改的对象
Customer c = session.get(Customer.class, 1l);
//2 修改
c.setCust_name("程序员");
//3 执行update
session.update(c);
//----------------------------------------------
tx2.commit();//提交事务
session.close();//释放资源
sf.close();//释放资源
}


HQL例子

问号占位符
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer where cust_id = ? "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
//query.setLong(0, 1l);
query.setParameter(0, 1l);
//3> 根据查询对象获得查询结果
Customer c = (Customer) query.uniqueResult();

System.out.println(c);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联


//命名占位符
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer where cust_id = :cust_id "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
query.setParameter("cust_id", 1l);
//3> 根据查询对象获得查询结果
Customer c = (Customer) query.uniqueResult();

System.out.println(c);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联


//分页
//1> 书写HQL语句
String hql ="from Customer order by cust_id asc"; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置分页信息 limit ?,?
query.setFirstResult(1);
query.setMaxResults(1);
//3> 根据查询对象获得查询结果
List<Customer> list =  query.list();


Criteria查询(单表条件查询)

//HQL语句中,不可能出现任何数据库相关的信息的
// >                gt
// >=               ge
// <                lt
// <=               le
// ==               eq
// !=               ne
// in               in
// between and      between
// like             like
// is not null      isNotNull
// is null          isNull
// or               or
// and              and
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//添加查询参数 => 查询cust_id为1的Customer对象
criteria.add(Restrictions.eq("cust_id", 1l));
//执行查询获得结果
Customer c = (Customer) criteria.uniqueResult();
//分页
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//设置分页信息 limit ?,?
criteria.setFirstResult(1);
criteria.setMaxResults(2);
//执行查询
List<Customer> list = criteria.list();


//查询总记录数
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//设置查询的聚合函数 => 总行数
criteria.setProjection(Projections.rowCount());
//执行查询
Long count = (Long) criteria.uniqueResult();


//离线Criteria
//Service/web层
DetachedCriteria **dc**  = DetachedCriteria.forClass(Customer.class);
dc.add(Restrictions.idEq(6l));//拼装条件(全部与普通Criteria一致)
//dao层
Criteria c = **dc**.getExecutableCriteria(session);


原生SQL查询

//1 书写sql语句
String sql = "select * from cst_customer where cust_id = ? ";
//2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
query.setParameter(0, 1l);
//指定将结果集封装到哪个对象中
query.addEntity(Customer.class);
//3 调用方法查询结果(query.list()没有指定addEntity返回Object[])
List<Customer> list = query.list();


//Hibernate Utils
public class HibernateUtils {
private static SessionFactory sf;
static{
//1 创建,调用空参构造
Configuration conf = new Configuration().configure();
//2 根据配置信息,创建 SessionFactory对象
sf = conf.buildSessionFactory();
}
//获得session => 获得全新session
public static Session openSession(){
//3 获得session
Session session = sf.openSession();
return session;
}
//获得session => 获得与线程绑定的session
public static Session getCurrentSession(){
//3 获得session
Session session = sf.getCurrentSession();
return session;
}
}


hibernate是一款orm框架

orm:object relationg mapping. 对象关系映射

HQL查询-hibernate Query Language(多表查询,但不复杂时使用)

Criteria查询(单表条件查询)

原生SQL查询(复杂的业务查询)

hql多表(略)

//----------------------------------------------------
String hql = " from Customer c right join c.linkMens ";
(left join)(inner join)
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
//HQL 迫切内连接 => 帮我们进行封装.返回值就是一个对象
public void fun2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql = " from Customer c inner join fetch c.linkMens ";

Query query = session.createQuery(hql);

List<Customer> list = query.list();


//集合级别的关联
//fetch:select 单表查询
//lazy:true 使用时才加载集合数据.
//集合级别的关联
//fetch:select 单表查询
//lazy:false 立即记载集合数据

//集合级别的关联
//fetch:select 单表查询
//lazy:extra 极其懒惰.与懒加载效果基本一致. 如果只获得集合的size.只查询集合的size(count语句)

//集合级别的关联
//fetch:join    多表查询
//lazy:true|false|extra 失效.立即加载.

//fetch: subselect 子查询
//lazy: true 懒加载

//fetch: subselect 子查询
//lazy: false 立即加载

//fetch: subselect 子查询
//lazy: extra 极其懒惰
<!--
fetch 决定加载的sql语句
select: 使用单表查询
join : 多表查询
lazy  决定加载时机
false: 立即加载
proxy: 由customer的类级别加载策略决定.
-->
<many-to-one name="customer" column="lkm_cust_id" class="Customer" fetch="join" lazy="proxy"  >
</many-to-one>

//fetch:select  单表查询
//lazy:proxy
//customer-true 懒加载

//fetch:join    多表
//lazy: 失效

//fetch:select  单表查询
//lazy:proxy
//customer-false 立即加载


hibernate过滤

悲观锁在session.method里加锁就行 安全,并发效率低

乐观锁在class.hbm.xml里<id>后加<version> 安全比悲观低,并发高
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: