学习Hibernate的(笔者一共会写四部分)
今天开始学习SSH框架,虽然在网上看到有人评论说SSH不火了,学习SSM吧。 但是,我这个人比较老实(哈哈哈) 先从SSH开始吧(一起学习,一起努力)
1、今天学习了Hibernate的环境配置(我不知道为什么那些网上下载jar包什么的还需要CSDN积分(很烦).......)
先分享一下在后来我们需要用到的东西(网上找的) 其中作者只用到了里边的jar包 如果对下边博客内容有什么问题的可以发消息或者私聊我,我会回复的。
链接: https://pan.baidu.com/s/1QmLyMyFAVpNI0pwqBtQbrg 提取码: ww3k
开始今天的学习之路吧
--------------------------------------------------------------------------
首先,我们要知道两个xml文件的配置
第一个是: 类名+hbm+.xml 这个xml文件应该放在与你要实现的那个类同一目录下
比如(Customer与Customer.hbm.xml是同一目录下)
(1)Customer.hbm.xml文件下的内容是用来与数据库中的信息进行配对的(我在下面贴上Customer的代码)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping> 6 <!-- 建立类与表的映射 --> 7 <class name="Nuc.Test.Customer" table="cst_customer"> 8 <!-- id标签建立类中的属性与表中的主键对应 --> 9 <id name="cust_id" column="cust_id"> 10 <generator class="native"/> <!-- 主键生成策略 --> 11 </id> 12 13 <!-- 建立类中的普通属性和表的字段的对应 --> 14 <property name="cust_name" column="cust_name"></property> 15 <property name="cust_source" column="cust_source"></property> 16 <property name="cust_industry" column="cust_industry"></property> 17 <property name="cust_level" column="cust_level"></property> 18 <property name="cust_phone" column="cust_phone"></property> 19 <property name="cust_mobile" column="cust_mobile"></property> 20 21 </class> 22 </hibernate-mapping>
在上边Customer.hbm.xml的文件配置中我们需要用到约束(我在下边以图片的形式展出<有点简陋>)
------->
----->----->
在这里边你就找到你的约束了
(2)下边我们来介绍hibernate.cfg.xml文件,在这个文件我们也用到了约束,只不过我们这次用的是下边这个文件下的
cfg与configuration对应(与上边给出的一样)
这个文件是对数据库中的url,username,password进行配置的
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 5 <hibernate-configuration> 6 <session-factory> 7 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 8 <property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01</property> 9 <property name="hibernate.connection.username">root</property> 10 <property name="hibernate.connection.password">123456</property> 11 <!-- 第二部分: 配置hibernate信息 可选的--> 12 <!-- 输出底层sql语句 --> 13 <property name="hibernate.show_sql">true</property> 14 <!-- 输出底层sql语句格式 --> 15 <property name="hibernate.format_sql">true</property> 16 <!-- hibernate帮创建表,需要配置之后 17 update: 如果已经有表,更新,如果没有,创建 18 --> 19 <property name="hibernate.hbm2ddl.auto">update</property> 20 <!-- 配置数据库方言 21 在mysql里面实现分页 关键字 limit,只能使用mysql里面 22 在oracle数据库,实现分页rownum 23 让hibernate框架识别不同数据库的自己特有的语句 24 --> 25 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 26 27 <mapping resource="Nuc/Test/Customer.hbm.xml"/> 28 29 </session-factory> 30 </hibernate-configuration>
在写完这两个xml文件之后,我们就可以开始写我们的代码了
(3)我们可以开始写我们的HibernateDemo1类了 下边附上代码(代码里边有解释)
1 package Nuc.Test; 2 3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5 import org.hibernate.Transaction; 6 import org.hibernate.cfg.Configuration; 7 import org.junit.Test; 8 9 /* 10 * Hibernate的入门案例 11 * @autor zsz 12 * */ 13 public class HibernateDemo1 { 14 @Test 15 //保存客户的案例 16 public void demo1(){ 17 //1.加载Hibernate的核心配置文件 18 Configuration configuration = new Configuration().configure(); 19 20 //2.创建SessionFactory对象,类似JDBC中的连接池 21 SessionFactory sessionFactory = configuration.buildSessionFactory(); 22 23 //3.通过SessionFactory获取Session对象,获取JDBC中的Connection 24 Session session = sessionFactory.openSession(); 25 26 //4.手动开启事务 27 Transaction transaction = session.beginTransaction(); 28 29 //5.编写代码 30 31 Customer customer = new Customer(); 32 customer.setCust_name("张三"); 33 34 session.save(customer); 35 36 //6.事务提交 37 transaction.commit(); 38 39 //7.资源释放 40 session.close(); 41 } 42 }
写到这,已经晚上21.37了 今天开始学习的时间并不长,大概晚上8.30开始学习的(其中遇到好几个BugQ=Q),不管怎么说,自己收获也很多
(4)说一下自己的Bug问题
4.1、我在写代码过程中比较着急,没有把类中的属性与数据中的匹配好
4.2、还有在创建数据库的时候主键如果是Int类型,一定要设置自动增加,一定要设置自动增加,一定要设置自动增加。
4.3、写的时候一定要仔细,仔细,仔细
(5)贴一下自己的项目图片,这样有助于大家理解(是不是在这里边还能发现我的学校(嘻嘻) 说不定是一个学校的哦)
lib下一定是这几个jar包,不然可能你在后边书写代码的时候会报错。
Hibernate第一部分
//2018.11.24
//2019.01.26
Hibernate第二部分
em。。。。。自从第一次写完之后,就开始了期末考试,也是自己比较懒,没有认真的去学习完。
现在放寒假了,通过自己的努力,把落下的东西都补回来
1.2持久化类的编写规则
1.2.1(Hibernate专注于的事情)
持久化:将内存中的一个对象持久到数据库当中(过程)
持久化类:一个Java对象与数据库的一个表建立了映射关系,那么这个类就是持久化类
1.2.2规则
(1)对持久化类提供一个无参数的构造方法 Hibernate底层需要使用反射生成实例
(2)属性需要私有,对私有属性提供public的get和set方法
(3)对持久化类提供一个唯一标识OID与数据库主键对应 Java中通过对象的地址来区分是否为同一个对象,数据库中通过是否为主键来确定是否为同一个记录
(4)尽量使用包装类类型(减少歧义) 基本数据类型的默认值是0,有很多的歧义。包装类默认为null(个人理解)
(5)持久化类不要使用final进行修饰 延时加载本身是Hibernate的一个优化的手段,最后返回的是一个代理对象(javassit可以对没有实现接口的类产生代理--使用了非常底层字节码增强技术)。如果不能被继承,不能产生代理对象,那么延时加载也就失效了(优化不好用)。 load与get一致了。
1.3主键的分类
1.3.1自然主键
自然主键:主键的本身就是表中的一个字段(实体中的一个具体的属性)-----身份证号码
1.3.2代理主键
代理主键:主键的本身不是表必须的字段(不是实体中的某个具体的属性)-----ID
实际开发中我们最好使用代理主键
为什么不用自然主键呢?
(1)、一旦自然主键参与到了业务逻辑当中,后期就可能需要修改源代码
(2)、好的程序设计需要满足-----OCP原则 对程序的扩展是open的,对修改源码是close的。
1.3.3主键的生成策略
1、在实际开发中一般不允许用户手动设置主键,一般交给数据库,手动编写程序进行设置,在Hibernate中提供了很多主键的生成策略
Increment Hibernate中提供的一个自动增长机制,适用于short,int,long类型的主键。在单线程中使用
Identity Hibernate中提供的一个自动增长机制,适用于short,int,long类型的主键。使用数据库底层的自动增长机制。(Oracle没有自动增长)
sequence Hibernate中提供的一个自动增长机制,适用于short,int,long类型的主键。采用的是序列的方式。(Oracle支持序列)
uuid 适用于字符串类型主键,使用hibernate随机生成
native 本地策略 可以在identity和sequence之间来进行自动切换
assigned hibernate放弃外键的管理,需要通过自己手动编写程序或者用户自己设置。
foreign 外部的。一对一的一种关联映射的情况下使用
1.4持久化类的三种状态
Hibernate为了更好的去管理持久化类,将持久化类(java类与数据库表建立了映射)分成了三种状态。
状态:
1.4.1瞬时态
没有唯一的标识OID,没有被session管理,称为瞬时态对象。
1.4.2持久态
有唯一的标识OID,被session管理。
1.4.3脱管态
有唯一的标识,但是没有被session管理
1.4.4区分三种状态
新初始化的持久化类--------------瞬时态 Customer cus = new Customer();
有OID,就是session进行操作之后--持久态
session关闭之后-----------------脱管态
1.4.5三种状态的转换
瞬时态对象
获得:直接new一个
状态转换
瞬时-》持久---------save()||saveOrUpdate()
瞬时-》脱管---------设置主键(其实就是设置OID)
持久态对象
获得:查询一下便可获得
get() load() find() iterate()
Customer customer = session.get(Customer.class,1);
状态转换
持久-》瞬时---------delete()
持久-》脱管---------close()、evict(Object obj)、clear()
脱管态对象
获得:Customer customer = new Customer(); customer.setCust_id(1); //设置一个OID
状态转换
脱管-》持久---------update()、saveOrUpdate()__执行update方法、
脱管-》瞬时---------customer.setCust_id(null)
1.4.6持久态对象可以自动更新数据
1.5Hibernate的一级缓存(清除 session.clear()清除所有)
1.5.1什么是缓存
缓存:是一种优化的方式
1.5.2Hibernate提供了两种缓存机制:一级和二级
1.5.2.1一级缓存-----自带的
称为Session级别的缓存,一级缓存生命周期与Session一致(一级缓存是由Session中的一系列的Java集合构成)
1.5.2.2二级缓存
SessionFactory级别的缓存,需要配置的缓存(企业开发一般不用)。
1.5.3结构
1.5.3.1一级缓存的特殊区域:快照区
1.6Hibernate的事务管理
1.6.1什么是事务
事务指的是逻辑上的一组操作,组成这组操作的各个逻辑单元要么全部成不,要么全部失败
1.6.2事务特性
原子性:事务不可分割
一致性:代表事务执行的前后,数据的完整性保持一致
隔离性:代表一个事务执行的过程中,不应该受到其他事务的干扰
持久性:代表事务执行完成后,数据就持久到数据库中
1.6.3安全性问题
读问题
脏读 一个事务读到另一个事务未提交的数据
不可重复读 一个事务读到了另一个事务已经提交的update数据,导致在前一个事务多次查询结果不一致
虚读 一个事务读到另一个事务已经提交的insert数据,导致在前一个事务多次查询结果不一致
写问题
1.6.4读问题的解决
设置事务的隔离级别
Read uncommitted 解决不了
Read committed 可以解决脏读
Reoeatable read 可以解决脏读和不可重复读
Serializable 都可以解决(串行化)