最近没有在博客上记录学到的知识,到北京一个月了,玩也玩了,转也转了,该消停了;
今天情人节,不对,昨天情人节,现在是情人节的夜晚,炮火连天的紫禁城应该也熄火了吧!
难道真有一天一日,一日就是一天的。。。啊呸!走题了。。。凌晨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();
}
感谢黑马培训视频教程,教了很多不会的知识点,还带着看源码,赞。如果有全集就更好了。。。