hibernate入门
框架的概述
框架是软件的半成品,已经完成了相应部分的内容了.只需要实现自己业务即可.
用我们自己的话来说: 框架说白了就是jar包, 方便开发的
Hibernate框架是当今主流的Java持久框架之一 ,由于他具有简单易学.灵活性强,扩展性强等特点,能够大大地简化程序的代码量,提高工作效率,因此受到广大开人员的喜爱.
Hibernate是一个开放源代码的ORM(Object Relational Mapping,对象关系映射)框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以使用对象编程思维来操纵数据库
Hibernate优点
Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码
Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的orm实现,它很大程度的简化了dao层编码工作
Hibernate的性能非常好,它是一个重量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系
ORM的概念
ORM:Object(对象/类) Relational(关系) Mapping(映射)
是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟对象数据库”。
O: Object对象,面向对象语言领域,Java中的JavaBean
R: 关系数据库领域的Relational(数据库中表的结构)
M: 映射Mapping(XML的配置文件)
创建数据库表结构
1 create database demo; 2 use test; 3 CREATE TABLE t_user( 4 `uid` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 5 `uname` VARCHAR(32) NOT NULL , 6 `uage` INT 7 );
创建java项目,导入jar包
1 public class User { 2 3 private Integer uid; 4 private String uname; 5 private Integer uage; 6 public Integer getUid() { 7 return uid; 8 } 9 public void setUid(Integer uid) { 10 this.uid = uid; 11 } 12 public String getUname() { 13 return uname; 14 } 15 public void setUname(String uname) { 16 this.uname = uname; 17 } 18 public Integer getUage() { 19 return uage; 20 } 21 public void setUage(Integer uage) { 22 this.uage = uage; 23 } 24 @Override 25 public String toString() { 26 return "User [uid=" + uid + ", uname=" + uname + ", uage=" + uage + "]"; 27 } 28 29 }
? 1.需要给数据bean中对应表中主键的属性设置为对象(包装)类型,且必须实现序列化接口。? 2.需要提供getter和setter方法。
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 <!--一,class标签用于表示javaBean和表的映射关系: name是类名,table是表名 --> 7 <class name="Demo.bean.User" table="t_user"> 8 <!--1.id用来配置主键 :name是JavaBean里面的字段名,column是表里面的主键列名 --> 9 <id name="uid" column="uid"> 10 <!--1.1 generator主键生成策略 --> 11 <generator class="native"></generator> 12 </id> 13 <!-- 2. 配置普通的字段对应关系 --> 14 <property name="uname" column="uname"/> 15 <property name="uage" column="uage"/> 16 </class> 17 </hibernate-mapping>
? 1.命名规范问题:hibernate命名以类名.hbm.xml
方式命名。
? 2.新建位置规范:通常和java类放到同一个包中。
? 3.dtd头的导入:在 下的org/hibernate包中有对应的dtd头
? 4.在配置关系过程中,几乎所有的name属性指向的都是Java类,column和table指向数据库表。
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 <!--一,必配项 --> 8 <!--1.1数据库的四个基本项 和 数据库方言--> 9 <property name="hibernate.dialect">org.hibernate.dialect.mysqlDialect</property> 10 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 11 <property name="hibernate.connection.url">jdbc:mysql:///demo01</property> 12 <property name="hibernate.connection.username">root</property> 13 <property name="hibernate.connection.password">123456</property> 14 <!--二,选配项 --> 15 <!--三,加载映射关系配置 --> 16 <mapping resource="Demo/bean/User.hbm.xml"/> 17 </session-factory> 18 </hibernate-configuration>
? 命名规范要求:以hibernate.cfg.xml
方式命名
? hibernate.cfg.xml放到src目录中,也就是classpath路径(类根路径)
1 public class UserDao { 2 3 @Test 4 public void addUser(){ 5 //1.创建Configuration对象 6 Configuration configuration = new Configuration(); 7 //2.加载配置 8 configuration.configure(); 9 //3.获得SessionFactory工厂 10 SessionFactory sessionFactory = configuration.buildSessionFactory(); 11 //4.从SessionFactory中打开session 12 Session session = sessionFactory.openSession(); 13 //5.开启事物 14 Transaction transaction = session.beginTransaction(); 15 //6.操作数据库 16 User user = new User(); 17 user.setUname("张三"); 18 user.setUage(18); 19 session.save(user); 20 //6.提交或者回滚事物 21 transaction.commit(); 22 //7.关闭资源 23 session.close(); 24 sessionFactory.close(); 25 } 26 27 }
用来描述Java类和数据库表的对应关系
-
name属性:Java类的全限定名
-
table属性:数据库表的表名
2.id标签
用来描述java类中属性和数据库表的主键的关系
2.1id标签的属性
-
name属性:java类中属性名称
-
column属性或标签:数据库表中的主键的列名
-
type属性:描述java类中属性的类型,hibernate会根据此类型生成对应数据库列的数据库类型
2.2id的子标签
-
generator标签:描述主键的生成策略
3.property标签
用来描述java类中其他属性和数据库表的其他列的关系
-
name属性:java类中属性名称
-
column属性或标签:数据库表中的主键的列名
-
type属性:描述java类中属性的类型,hibernate会根据此类型生成对应数据库列的数据库类型
通过property标签进行配置: 方言
,驱动
,地址
,帐号
,
1 1 <!--1.1数据库的四个基本项 和 数据库方言--> 2 2 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 3 3 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 4 4 <property name="hibernate.connection.url">jdbc:mysql:///demo01</property> 5 5 <property name="hibernate.connection.username">root</property> 6 6 <property name="hibernate.connection.password">123456</property>
1 <mapping resource="demo/bean/User.hbm.xml" />
-
日志显示:hibernate.show_sql
-
1 <!--2.1 执行时候,打印sql语句 --> 2 <property name="hibernate.show_sql">true</property>
-
日志格式化:hibernate.format_sql
-
1 <!--2.2 打印sql语句格式输出 --> 2 <property name="hibernate.format_sql">true</property>
-
-
<!--2.3 配置是否由Hibernate生成表 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- none:不用Hibernate自动生成表(默认) create-drop:每次都会创建一个新的表,执行程序结束后删除这个表. create:每次都会创建一个新的表. update:有(表, 列)就使用, 没有(表, 列)就创建 validate:只会使用原有的表.对映射关系进行校验. -->
1.Configuration
? 配置对象,用来加载Hibernate的核心配置文件.
? Hibernate框架通过该对象来获得对象-关系映射文件中的元数据,以及动态配置Hibernate的属性。
? 可以创建SessionFactory对象。
-
Java代码
1 Configuration configuration = new Configuration();configuration.configure();
-
? 获得Session
? SessionFactory中相当于是连接池,内部获得Session.
? SessionFactory并不是一个轻量级对象. 内部维护连接池和hibernate的二级缓存(企业很少用,redis).
? 一个项目一般只需要创建一个SessionFactory.
-
抽取的HibernateUtils
1 public class HibernateUtils { 2 private final static Configuration configuration; 3 private final static SessionFactory sessionFactory; 4 5 private HibernateUtils() { 6 } 7 8 static { 9 // 1. 创建Configuration对象 10 configuration = new Configuration(); 11 // 2. 加载配置 12 configuration.configure(); 13 // 3. 获得Session工厂 14 sessionFactory = configuration.buildSessionFactory(); 15 } 16 17 public static Session openSession() { 18 // 4. 获得Session 19 return sessionFactory.openSession(); 20 } 21 }
-
? Session对象是Hibernate与数据库交互的桥梁,session对象里面封装了操作数据库的方法(添加,删除,查找,更新等)
? session不是线程安全的(使用时候,不能创建全局的).
? 内部维护Hiberante的一级缓存(优化的手段).
-
常见的操作数据库API
? Serializable save(Object obj); --保存数据,返回值是保存数据返回的id
?
? T get(Class clazz,Serializable id); --根据主键查询对象
? T load(Class clazz,Serializable id); --根据主键查询对象
?
? void update(Object obj); --更新数据
? void delete(Object obj); --删除数据
? Transaction对象代表的是事务对象,事务开启session.beginTransaction();
-
常用API
? commit():提交事务
? rollback():回滚事务
-
特点
? Hibernate框架默认情况下事务不自动提交.需要手动提交事务
? 如果没有开启事务,那么每个Session的操作,都相当于一个独立的事务
? 每段事务操作都是隐含着异常的,需要手动添加try catch
-
测试事物没有自动提交
1 if(session instanceof SessionImpl){ 2 SessionImpl sessionImpl = (SessionImpl) session; 3 Connection connection = sessionImpl.connection(); 4 System.out.println(connection.getAutoCommit());//false 5 }
1.概述
? Hibernate 内部本来就有一套连接池的机制,但是想对于开源的c3p0连接池,性能还是弱一些。 所以一般我们都选择配置c3p0的连接池。 要想配置c3p0连接池,其实要做的工作非常之简单。只需要我们拷贝jar包,并且在核心配置文件中都写几行即可。
2.集成步骤
-
拷贝jar包到项目
jar包的位置位于 : hibernate-release-5.0.7.Final\\lib\\optional\\c3p0\\
- 在核心配置文件 hibernate.cfg.xml中添加以下代码
-
1 <!-- 配置使用c3p0连接池 --> 2 <property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property> 3 <!--下面的都是可选项, 上面的这一行是必须代码!!--> 4 5 <!-- 连接池最大连接数为 10个 --> 6 <property name="hibernate.c3p0.max_size">10</property> 7 <!-- 连接池最少连接数为5个 --> 8 <property name="hibernate.c3p0.min_size">5</property> 9 <!-- 检查连接空闲时间间隔为 120秒。也就是每隔这么多时间就检测是否有连接空闲着 --> 10 <property name="hibernate.c3p0.timeout">120</property>
? 2.如果在集成C3P0的时候出现了如下info日志:
INFO: HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
.? 在主配置文件里面配置:
<property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
就可以解决. 作用是告诉Hibernate使用了第三方连接池, 没必要再通过之前的方式尝试连接数据库.