Hibernate (一)
1 JDBC的优缺点
- 优点:
- 直接底层操作,提供了简单、便捷的访问数据库的方法,跨平台比较强。
- 灵活性比较强,可以写复杂的SQL。
- 缺点:
- JDBC没有做到面向对象的编程,使得程序员的思考还停留在SQL之上。
- 操作比较频繁,很多代码需要重复的写很多次。
- 如果遇到批量操作,频繁的和数据库进行交互,容易造成效率的下降。
2 Hibernate的优缺点
- 优点:
- 面向对象编程
- 缓存
- 一级缓存
- 二级缓存
- 查询缓存
- 代码操作比较简单
- 平台的移植性比较强
- 缺点:
- 如果该项目对SQL的优化要求比较高,不适合用Hibernate。
- 如果数据库的数据量比较大,也不适合用Hibernate。
- 如果表和表之间的关系比较复杂,也不能用Hibernate。
3 Hibernate的使用场合
- 表的关系不是很复杂
- 数据量不是很大
4 Hibernate的入门案例
4.1 导入jar包
4.2 编写hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <!-- 一个sessionFactory就代表一个数据库的描述 --> <session-factory> <!-- 链接数据库的用户名 --> <property name="connection.username">root</property> <!-- 链接数据库的密码 --> <property name="connection.password">root</property> <!-- 链接数据库的驱动 --> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- 链接数据库的url --> <property name="connection.url"> jdbc:mysql://localhost:3306/hibernate </property> <!-- 方言 告诉hibernate用什么样的数据库,将来会生成什么样的sql语句 --> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <!-- hibernate对表的策略 validate 在hibernate容器启动的时候,根据映射文件和持久化类校验表 create 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表 create-drop 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表,销毁的时候删除表 update 检查,如果和映射文件不一致,则更新表的结构,如果没有表,则会创建表 --> <property name="hbm2ddl.auto">update</property> <property name="show_sql">true</property> <property name="format_sql">true</property> </session-factory> </hibernate-configuration>
4.3 编写持久化类和映射文件
- Person.java
package com.xuweiwei.vo; import java.io.Serializable; /** * 实体类 */ public class Person implements Serializable { private Long pid; private String name; private String sex; public Long getPid() { return pid; } public void setPid(Long pid) { this.pid = pid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
- Person.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <!-- class元素代表持久化类 name属性为类的全名 table属性为表的名字,默认值类名 --> <class name="com.xuweiwei.vo.Person" table="person"> <!-- id为主键元素 name 标识符属性 column 对应表的字段 type 类型 length 数据库中pid的长度 --> <id name="pid" column="pid"> <!-- 主键生成策略 需要通过什么样的方式产生主键 --> <generator class="native"/> </id> <!-- property代表普通的属性 --> <property name="name" column="name"/> <property name="sex" column="sex"/> </class> </hibernate-mapping>
- hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <!-- 一个sessionFactory就代表一个数据库的描述 --> <session-factory> <!-- 链接数据库的用户名 --> <property name="connection.username">root</property> <!-- 链接数据库的密码 --> <property name="connection.password">root</property> <!-- 链接数据库的驱动 --> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- 链接数据库的url --> <property name="connection.url"> jdbc:mysql://localhost:3306/hibernate </property> <!-- 方言 告诉hibernate用什么样的数据库,将来会生成什么样的sql语句 --> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <!-- hibernate对表的策略 validate 在hibernate容器启动的时候,根据映射文件和持久化类校验表 create 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表 create-drop 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表,销毁的时候删除表 update 检查,如果和映射文件不一致,则更新表的结构,如果没有表,则会创建表 --> <property name="hbm2ddl.auto">update</property> <property name="show_sql">true</property> <property name="format_sql">true</property> <mapping resource="com/xuweiwei/vo/Person.hbm.xml"/> </session-factory> </hibernate-configuration>
4.4 测试
- 示例:
package com.xuweiwei.test; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.junit.Test; public class TestPerson { @Test public void testCreateTable(){ //创建Configuration对象并加载hibernate.cfg.xml文件 Configuration configuration = new Configuration().configure(); //创建SessionFactory对象 SessionFactory sessionFactory = configuration.buildSessionFactory(); } }
- 如果你想看的仔细的话,可以在类路径下加入log4j.properties
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file hibernate.log ### #log4j.appender.file=org.apache.log4j.FileAppender #log4j.appender.file.File=hibernate.log #log4j.appender.file.layout=org.apache.log4j.PatternLayout #log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change 'info' to 'debug' ### log4j.rootLogger=debug, stdout #log4j.logger.org.hibernate=info log4j.logger.org.hibernate=debug ### log HQL query parser activity #log4j.logger.org.hibernate.hql.ast.AST=debug ### log just the SQL #log4j.logger.org.hibernate.SQL=debug ### log JDBC bind parameters ### log4j.logger.org.hibernate.type=info #log4j.logger.org.hibernate.type=debug ### log schema export/update ### log4j.logger.org.hibernate.tool.hbm2ddl=debug ### log HQL parse trees #log4j.logger.org.hibernate.hql=debug ### log cache activity ### #log4j.logger.org.hibernate.cache=debug ### log transaction activity #log4j.logger.org.hibernate.transaction=debug ### log JDBC resource acquisition #log4j.logger.org.hibernate.jdbc=debug ### enable the following line if you want to track down connection ### ### leakages when using DriverManagerConnectionProvider ### #log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
4.5 CRUD操作
- 示例:增加
package com.xuweiwei.test; import com.xuweiwei.vo.Person; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.Test; public class TestPerson { @Test public void testCreateTable(){ //创建Configuration对象并加载hibernate.cfg.xml文件 Configuration configuration = new Configuration().configure(); //创建SessionFactory对象 SessionFactory sessionFactory = configuration.buildSessionFactory(); } @Test public void testInsert(){ //创建Configuration对象并加载hibernate.cfg.xml文件 Configuration configuration = new Configuration().configure(); //创建SessionFactory对象 /** * 1.SessionFactory是单例的 * 2.Hibernate的配置文件的信息、映射文件的信息、持久化类的信息全部在SessionFactory中 * 3.sessionFactory封装的信息是公共的数据 * 4.sessionFactory本身是线程安全的 */ SessionFactory sessionFactory = configuration.buildSessionFactory(); //创建session对象 Session session = sessionFactory.openSession(); //开启事务 Transaction tx = session.beginTransaction(); Person p = new Person(); p.setName("丁希希"); p.setSex("女"); session.save(p); //提交事务 tx.commit(); session.close(); sessionFactory.close(); } }
- 示例:根据指定的id查询对象
@Test public void testQuery(){ Configuration configuration = new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Person p = (Person) session.get(Person.class,1L); System.out.print(p.getPid()+":"+p.getName()+":"+p.getSex()); tx.commit(); session.close(); sessionFactory.close(); }
- 示例:查询所有的对象
@Test public void testAllQuery(){ Configuration configuration = new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Query query = session.createQuery("from Person"); List<Person> list = query.list(); for(Person p :list){ System.out.print(p.getPid()+":"+p.getName()+":"+p.getSex()); } tx.commit(); session.close(); sessionFactory.close(); }
@Test public void testAllQuery(){ Configuration configuration = new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); SQLQuery query = session.createSQLQuery("select * from person"); query.addEntity(Person.class); List<Person> list = query.list(); for(Person p :list){ System.out.print(p.getPid()+":"+p.getName()+":"+p.getSex()); } tx.commit(); session.close(); sessionFactory.close(); }
@Test public void testAllQuery(){ Configuration configuration = new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Criteria criteria = session.createCriteria(Person.class); List<Person > peoples = criteria.list(); for(Person p :peoples){ System.out.println(p.getPid()+":"+p.getName()+":"+p.getSex()); } tx.commit(); session.close(); sessionFactory.close(); }
- 示例:更新
@Test public void testUpdate(){ Configuration configuration = new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Person p = (Person) session.get(Person.class,1L); p.setName("丁希希是我公司的前端妹子"); tx.commit(); session.close(); sessionFactory.close(); }
- 示例:删除
@Test public void testDelete(){ Configuration configuration = new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Person p = (Person) session.get(Person.class,1L); session.delete(p); tx.commit(); session.close(); sessionFactory.close(); }
4.6 主键生成策略(在*.hbm.xml中配置)
- 封装Hibernate工具类:HibernateUtil.java
package com.xuweiwei.util; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** * Hibernate工具类 */ public class HibernateUtil { public static SessionFactory sessionFactory; static{ Configuration configuration = new Configuration().configure(); sessionFactory = configuration.buildSessionFactory(); } public static SessionFactory getSessionFactory(){ return sessionFactory; } }
- increment
/** * select max(pid) from person * insert into person(name, sex, pid) values (?, ?, ?) * 1.先查询表中主键的最大值 * 2.把最大值+1作为新的主键 * 即便在程序中设置主键也不起作用,原因参考1和2 * * 主键必须是数字类型 */ @Test public void testIncrement(){ SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Person p = new Person(); p.setName("许威威"); p.setSex("男"); session.save(p); tx.commit(); session.close(); sessionFactory.close(); }
- assigned
/** * 该策略必须通过程序设置 */ @Test public void testAssigned(){ SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Person p = new Person(); p.setPid(1L); p.setName("许威威"); p.setSex("男"); session.save(p); tx.commit(); session.close(); sessionFactory.close(); }
- identity
/** * 利用数据库的主键自动增长,数据库的类型必须支持自动增长才行 */ @Test public void testIdentity(){ SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Person p = new Person(); p.setName("许威威"); p.setSex("男"); session.save(p); tx.commit(); session.close(); sessionFactory.close(); }
- native:会根据不同的数据库判断底层的主键生成策略
- uuid:是由Hibernate内部产生的
/** * uuid */ @Test public void testUuid(){ SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Person p = new Person(); p.setName("许威威"); p.setSex("男"); session.save(p); tx.commit(); session.close(); sessionFactory.close(); }
- sequence:Oracle中支持的自动增长机制
5 各个类或接口的作用
5.1 Configuration
- 用来加载hibernate.cfg,xml文件。
5.2 SessionFactory
- SessionFactory是单例的。
- Hibernate的配置文件的信息、映射文件的信息、持久化类的信息全部在SessionFactory中。
- SessionFactory封装的信息是公开的数据。
- SessionFactory本身是线程安全的。
5.3 Session
- CRUD操作都是由Session来完成的。
- Session是一个接口,实现类是SessionImpl。
- 在创建SessionImpl的时候,传递了一个参数为Connection,所以在Hibernate编程的时候,创建Session就相当于打开了一个连接。
- 当关闭Session的时候,相当于关闭了一个连接。
5.4 Transaction
- 事务是由Session来产生的
- 事务默认是关闭的,必须手动开启
6 Hibernate的加载流程
7 对象的状态
7.1 三种对象的定义和区别
- 【注意】如果一个对象的状态是持久态,那么数据库中不一定有对应的值。
- 比如:
session.save(p);
- 这个时候的对象的状态是持久态,但是数据库中是没有对应的值。
//提交事务 tx.commit();
- 这个时候对象的状态是持久态,但是数据库中有对应的值。
- 瞬时态对象和脱管态对象的区别:
- 瞬时太对象是从new创建的。
- 脱管态对象是从持久态转换过来的。
7.2 对象的状态转换
7.3 对象状态的示例
- 示例:
@Test public void testInsert(){ //创建Configuration对象并加载hibernate.cfg.xml文件 Configuration configuration = new Configuration().configure(); //创建SessionFactory对象 /** * 1.SessionFactory是单例的 * 2.Hibernate的配置文件的信息、映射文件的信息、持久化类的信息全部在SessionFactory中 * 3.sessionFactory封装的信息是公共的数据 * 4.sessionFactory本身是线程安全的 */ SessionFactory sessionFactory = configuration.buildSessionFactory(); //创建session对象 Session session = sessionFactory.openSession(); //开启事务 Transaction tx = session.beginTransaction(); Person p = new Person();//顺时态对象 p.setName("许威威");//顺时态对象 p.setSex("男");//顺时态对象 session.save(p);//持久态对象 //提交事务 tx.commit();//持久态对象 session.close();//脱管态对象 sessionFactory.close(); }
- 示例:
@Test public void testUpdate(){ Configuration configuration = new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Person p = (Person) session.get(Person.class,1L);//持久态对象 p.setName("呵呵");//持久态对象 //session.update(p); 将一个对象变为持久化状态,此时,p已经是持久态对象,所以可以不需要写update方法 tx.commit(); session.close(); sessionFactory.close(); }
- 示例:
@Test public void testUpdate(){ Configuration configuration = new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Person p = (Person) session.get(Person.class,1L);//持久态对象 p.setName("呵呵");//持久态对象 session.evict(p);//把持久态对象变为了脱管态对象,所以不会更新 session.update(p);//把脱管态对象变为了持久态对象 tx.commit(); session.close(); sessionFactory.close(); }
- 示例:
@Test public void testUpdate(){ Configuration configuration = new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Person p = (Person) session.get(Person.class,1L);//持久态对象 p.setName("呵呵");//持久态对象 session.clear();//把person对象从hibernate中清空 session.update(p); tx.commit(); session.close(); sessionFactory.close(); }
- 总结:
- 可以通过session的save/update/get等方法把一个对象变为持久态对象。持久态对象仅仅说明了该对象进入了Hibernate的区域,和数据库一点点关系也没有,和数据库有关系的是事务。
- 可以通过session的close/evict/clear等方法,将持久态对象变为脱管态对象。
Hibernate (一)的更多相关文章
- hibernate多对多关联映射
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
- 解决 Springboot Unable to build Hibernate SessionFactory @Column命名不起作用
问题: Springboot启动报错: Caused by: org.springframework.beans.factory.BeanCreationException: Error creati ...
- hibernate多对一双向关联
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
- Hibernate中事务的隔离级别设置
Hibernate中事务的隔离级别,如下方法分别为1/2/4/8. 在Hibernate配置文件中设置,设置代码如下
- Hibernate中事务声明
Hibernate中JDBC事务声明,在Hibernate配置文件中加入如下代码,不做声明Hibernate默认就是JDBC事务. 一个JDBC 不能跨越多个数据库. Hibernate中JTA事务声 ...
- spring applicationContext.xml和hibernate.cfg.xml设置
applicationContext.xml配置 <?xml version="1.0" encoding="UTF-8"?> <beans ...
- [原创]关于Hibernate中的级联操作以及懒加载
Hibernate: 级联操作 一.简单的介绍 cascade和inverse (Employee – Department) Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似 ...
- hibernate的基本xml文件配置
需要导入基本的包hibernate下的bin下的required和同bin下optional里的c3p0包下的所有jar文件,当然要导入mysql的驱动包了.下面需要注意的是hibernate的版本就 ...
- Maven搭建SpringMVC+Hibernate项目详解 【转】
前言 今天复习一下SpringMVC+Hibernate的搭建,本来想着将Spring-Security权限控制框架也映入其中的,但是发现内容太多了,Spring-Security的就留在下一篇吧,这 ...
- 1.Hibernate简介
1.框架简介: 定义:基于java语言开发的一套ORM框架: 优点:a.方便开发; b.大大减少代码量; c.性能稍高(不能与数据库高手相比,较一般数据库使用者 ...
随机推荐
- liveshow回顾
在2017年8月14号的一天接到一个即看即买的项目,大致功能如下 1.现场走秀直播同步到H5页面 2.实时显示直播间人数 3.点赞并实时显示给用户 4.在某个时间点,可以全体推送一些消息给所有用户 5 ...
- ionic滑动框 ---轮播图(ion-slide-box) 的使用
1. html : <ion-slide-box auto-play="true" slide-interval=3000 show-pager="false&qu ...
- addEventListener attachEvent和解决IE 6 7 8 this指向错误
[JS] addEventListener attachEvent和解决IE 6 7 8 this指向错误 电梯直达 1# php 发表于 2014/4/13 01:17 | 只看该作者 ...
- python2.7源码编译安装
最近学习docker容器,因为平时用的linux发型版都是centos6系列,所有pull了一个centos:6.6的景像,运行景像,进入容器后,发现其默认的python环境是2.6,为了更好的兼容我 ...
- HDU1465-装错信封-递推
不容易系列之一 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- JSON对象添加删除属性
假如目前我们有如下一个Json对象 var jsonObj={ 'param1':22, 'param2' :33 }; 增加属性: 我们现在向该对象jsonObj中添加一个新的属性字段:param3 ...
- JAVA代码实现嵌套层级列表,POI导出嵌套层级列表
要实现POI导出EXCEL形如 --A1(LV1) ----B1(LV2) ----B2(LV2) ------C1(LV3) ------C2(LV3) ----B3(LV2) --A1(LV1)
- c#委托事件入门--第二讲:事件入门
上文 c#委托事件入门--第一讲:委托入门 中和大家介绍了委托,学习委托必不可少的就要说下事件.以下思明仍然从事件是什么.为什么用事件.怎么实现事件和总结介绍一下事件 1.事件是什么:. 1.1 NE ...
- kafka producer生产数据到kafka异常:Got error produce response with correlation id 16 on topic-partition...Error: NETWORK_EXCEPTION
kafka producer生产数据到kafka异常:Got error produce response with correlation id 16 on topic-partition... ...
- API接口安全性设计
http://www.jianshu.com/p/c6518a8f4040 接口的安全性主要围绕Token.Timestamp和Sign三个机制展开设计,保证接口的数据不会被篡改和重复调用,下面具体来 ...