hibernate学习记录
2018-03-13 22:23
246 查看
Class.hbm.xml
关联例子
hibernate.cfg.xml
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);查使用时加载
例子:
HQL例子
Criteria查询(单表条件查询)
原生SQL查询
hibernate是一款orm框架
orm:object relationg mapping. 对象关系映射
HQL查询-hibernate Query Language(多表查询,但不复杂时使用)
Criteria查询(单表条件查询)
原生SQL查询(复杂的业务查询)
hql多表(略)
hibernate过滤
悲观锁在session.method里加锁就行 安全,并发效率低
乐观锁在class.hbm.xml里<id>后加<version> 安全比悲观低,并发高
关系配置 <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> 安全比悲观低,并发高
相关文章推荐
- Hibernate-多种关联学习记录详解
- 【hibernate】学习期间总结与记录
- Hibernate学习及问题记录(1)——纠结的第一战
- Hibernate学习-03:入门案例(CRUD(增删改查)操作之添加记录)
- hibernate的QBC查询学习记录
- Hibernate学习记录1 基本概念
- JPA学习记录二(搭建一个JPA+hibernate实例)
- hibernate学习记录6
- Hibernate学习记录2 HQL常规操作
- hibernate学习记录3
- 我的Hibernate学习记录(二)
- Hibernate学习记录
- Jersey+Spring+Hibernate集成学习记录
- 【ssh2学习记录】3、关于ssh2框架整合以及hibernate的一些总结
- hibernate多表查询学习记录
- Hibernate 学习记录 4
- hibernate学习记录
- hibernate学习记录1
- 我的Hibernate学习记录(二)
- Hibernate学习记录2