Java三剑客-持久层Hibernate

最近没有在博客上记录学到的知识,到北京一个月了,玩也玩了,转也转了,该消停了;

今天情人节,不对,昨天情人节,现在是情人节的夜晚,炮火连天的紫禁城应该也熄火了吧!

难道真有一天一日,一日就是一天的。。。啊呸!走题了。。。凌晨2点半,睡不着,整理下。。。

信了全栈开发的邪!信了PHP是世界上最好的语言的梗!

同志们,安安心心的将一门主语言研究三年吧,不要好奇,不要追新,要把主语言变成自己最擅长的最熟悉的技能!

 

Java三剑客,好久不见;

持久层:Hibernate

这货是个啥?就是一个持久层的ORM框架;ORM就是对象关系映射,让我们使用对象编程的思维来操作数据表;

hibernate轻量的封装了JDBC,简化了JDBC的编程;

使用的步骤:

1、导入jar包

2、创建实体类与表结构

自然逐渐和代理主键,id就是代理主键;

标识属性尽量使用包装类;

3、创建实体类与数据表的映射文件

<?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.domain.Customer" table="customer">
<id name="cust_id" column="cust_id">
<generator class="native"/>
</id>
<property name="cust_name" column="cust_name"/>
<property name="cust_user_id" column="cust_user_id"/>
</class>
</hibernate-mapping>

class标签中,通过反射获取实体类路径,并与表名称映射好

设置主键(生成策略)及其他非主键属性;

主键生成策略,一般选择native(随本地数据库不同自动选择)或者uuid(随机字符串作为主键);

此时,java类+xml文件就等于了持久化类;

<!-- 配置关联对象 -->
		<!-- 
			set标签:
			    * name属性:多的一方的集合的属性名称.
		 -->
		<set name="linkMans">
			<!-- 
				key标签 :
				    * column属性:多的一方的外键的名称.
			-->
			<key column="lkm_cust_id"></key>
			<!-- 
				one-to-many标签:
				    * class属性:多的一方的类全路径
			 -->
			 <one-to-many class="cn.itcast.domain.LinkMan"/>
		</set>
<!-- 配置关联关系 -->
		<!-- name:角色集合的属性名称   table:-->
		<set name="roles" table="user_role">
			<!-- 当前类中在中间表的外键的名称 -->
			<key column="uno"></key>
			<!-- class:关联的另一方的多的类全路径.column:另一方在中间表中的外键名称: -->
			<many-to-many class="com.itheima.domain.Role" column="rno"></many-to-many>
		</set>

4、创建Hibernate核心配置文件

session-factory中配置数据库4大参数;数据库的类型;可选的配置项;加载映射文件;

<?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>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123</property>
<property name="hibernate.dialect">org.dialect.MySQLDialect</property>
<mapping resource="com/domain/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>

5、搞起

使用Configuration加载配置,从这到获取session封装成一个工具类,并且将session与本地session绑定

private static final Configuration cfg = new Configuration().configure();

构建出SessionFactory

private static final SessionFactory sessionFactory = cfg.buildSessionFactory();

一个数据库一个SessionFactory就好,因为他不是轻量级的;

③获取session对象

Session session =  SessionFactory.openSession();

Session session = SessionFactory.getCurrentSession();

session对象的一级缓存可提升程序性能,自带的不可卸载,生命周期与session一致;

控制缓存:Session.clear();Session.flush();Session.evict(Object entity);

一级缓存成为session级别的缓存,二级缓存成为sessionFactory级别的缓存;

快照机制保证数据发生变化时,可进行同步操作(自动更新);

还有个事务的问题,可以设置数据库隔离级别来避免脏读、虚读、不可重复读;

通过:hibernate.connection.isolation = 4 来配置
* 取值
* 1—Read uncommitted isolation
* 2—Read committed isolation
* 4—Repeatable read isolation
* 8—Serializable isolation

丢失更新的问题:

悲观锁:sql语句后面添加for update 子句;使用session.get(Customer.class, 1,LockMode.UPGRADE); 方法

乐观锁:采用版本号机制,表结构中添加一个version字段,默认0;

绑定本地session:

提供了ThreadLocal方式

需要在hibernate.cfg.xml的配置文件中提供配置
*

<property name="hibernate.current_session_context_class">thread</property>
session.beginTransaction;//开启事务

       try{

       调用dao方法1

       调用dao方法2

    session.getTransaction().commit();//提交事务

       }catch(Exception ex){

              session.getTransaction().rollback();//回滚事务

       }

 

使用SessionFactory的getCurrentSession()方法,获取当前的Session对象。并且该Session对象不用手动关闭,线程结束了,会自动关闭

④完成CRUD操作

save(Object obj);

update(Object obj);

delete(Object obj);

get(Class c,Serializable s);

load(Class c,Serializable s);

saveOrUpdate(Object obj);

Hibernate管理对象包括三种状态:

瞬时状态:没有OID,没有纳入session对象管理,与数据库记录不对应;

持久状态:有持久化标识OID,纳入了session对象管理,new出来了,也session.save(xx)了,有自动更新能力;

托管状态:有OID标识,没有纳入session对象管理,可能与数据库记录对应

Hibernate的查询方式

1)createQuery查询(hql)

Query query = session.createQuery("from Customer where name = ?");//创建语句,?就是下标,:name 就用key
query.setString(0, "小红");//添加条件,这里也可以直接setObject;
List<Customer> list = query.list();//查询
/**
 * 分页
 */
Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();
		
		Query query = session.createQuery("from LinkMan order by lkm_id desc");
		query.setFirstResult(5);
		query.setMaxResults(5);
		List<LinkMan> list = query.list();
		for (LinkMan linkMan : list) {
			System.out.println(linkMan);
		}
		
		tx.commit();

 

2)Criteria查询接口(面向对象,不用语句,就调用方法)

Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("name", "小明"));
criteria.add(Restrictions.eq("age", 30));
List<Customer> list = criteria.list();

3)普通的sql语句查询

SQLQuery sqlQuery = session.createSQLQuery("select * from customer");

List<Object[]> list = sqlQuery.list();

4)OID检索

5)对象导航检索

 

离线检索

@Test
	/**
	 * 离线条件查询:DetachedCriteria(SSH整合经常使用.).
	 * * 可以脱离session设置参数.
	 */
	public void demo6(){
		// 获得一个离线条件查询的对象
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
		detachedCriteria.add(Restrictions.eq("cust_name","小童童"));
		
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();
		
		List<Customer> list = detachedCriteria.getExecutableCriteria(session).list();// 离线条件查询对象与session绑定.
		for (Customer customer : list) {
			System.out.println(customer);
		}
		tx.commit();
	}

 

感谢黑马培训视频教程,教了很多不会的知识点,还带着看源码,赞。如果有全集就更好了。。。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值