ormapping(对象关系映射):数据库操作框架
缺点:
1.因为hql语句是hibernate内部自动生成,程序员干预不了,不可把控
2.功能比较复杂时不建议使用
优点:
1.比较简单。
2.有数据缓存,一级缓存二级缓存 查询缓存。
3.移置性好
jdbc:
缺点:
1.代码繁琐
2.频繁地进行try...catch
3.没有数据缓存
4。移置性不好(更换数据库)
有点:
1.速度比较快
2.把控性比较好
***.hbm.xml(映射文件) 的作用:表与类产生联系
类与表的关系
类中属性与表中字段的关系
类中属性类型与表中字段类型对应
把一对多和多对多关系转化成面向对象的关系
hibernate 配置文件的作用:主要是用来链接数据库的
配置hibernate
1.导入jar包
2.编写实体类
3.建立表与类之间的关系
4.配置hibernate映射文件
/** Hibernate执行流程:
* Configuration:读取并解析配置文件(hibernate.cfg.xml)
* 一个Configuration实例代表hibernate所有的java类到SQL数据库映射的集合
* SessionFactory:读取并解析映射信息(***.hbm.xml)
* 将Configuration对象中的所有配置信息拷贝到SessionFactory的缓存中
* 打开Session,让SessionFactory提供连接。
* SessionFactory factory = con.buildSessionFactory();
* Transaction:开启事务。
* Transaction tr = se.beginTransaction();
* 数据库操作(get,delete,update,save)完成:提交事务、关闭Session
* tr.commit();
* se.close();
* */
/** Hibernate对象三种状态
* save():将对象由瞬时态转变为持久态
* load()/get():获得的对象的状态处于持久态
* find():获得的List集合中的对象的状态处于持久态
* upload()/saveOrUpload()/lock():可将托管状态对象转变为持久态
* close():调用后,Session的缓存会被清空,缓存中所有持久态对象状态都转变为托管态
* 处于托管状态的对象称为游离对象,当游离对象不再被引用时,将被JVM垃圾回收机制清除
* evict():可将Session缓存中一个指定的持久态对象删除,使其转变为托管态对象
* 当缓存中保存了大量持久态对象时,为了节省内存空间,可以调用此方法删除一些持久态对象
* evict()与clear()区别:
* session.evict(obj):会把指定的缓冲对象进行删除
* session.clear():把缓冲区内的全部对象清除,但不包括操作中的对象
如图: Hibernate 的对象的 3 种状态的转变关系
1、person 实体类
Person.java
1 package cn.gs.ly.entity; 2 3 import java.io.Serializable; 4 5 public class Person implements Serializable{ 6 7 private static final long serialVersionUID = 1L; 8 9 private long pid; 10 private String pname; 11 private int page; 12 13 14 public long getPid() { 15 return pid; 16 } 17 public void setPid(long pid) { 18 this.pid = pid; 19 } 20 public String getPname() { 21 return pname; 22 } 23 public void setPname(String pname) { 24 this.pname = pname; 25 } 26 public int getPage() { 27 return page; 28 } 29 public void setPage(int page) { 30 this.page = page; 31 } 32 33 @Override 34 public String toString() { 35 return "Person [pid=" + pid + ", pname=" + pname + ", page=" + page + "]"; 36 } 37 38 }
2、表与类之间关系
Person.hbm.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 6 <!-- 配置表与实体对象的关系 --> 7 <!-- package属性:填写一个包名.在元素内部凡是需要书写完整类名的属性,可以直接写简答类名了. --> 8 <!-- <hibernate-mapping package="cn.gs.ly.entity"> --> 9 <hibernate-mapping> 10 <!-- 11 class:用来描述一个持久化类 ,配置实体与表的对应关系的 12 name:持久化类全名 13 table:数据库中表名,可以不写,默认和实体类名一致 14 --> 15 <class name="cn.gs.ly.entity.Person" table="Person" > 16 <!-- 17 id:标示属性,和数据库中主键对应 18 name: 填写主键对应类属性名 19 column(可选): 填写表中的主键列名.默认值:列名会默认使用属性名 20 type(可选):填写类中列(属性)的类型.hibernate会自动检测实体的属性类型. 21 每个类型有三种填法: java类型|hibernate类型|数据库类型 22 not-null(可选):配置该属性(列)是否不能为空. 默认值:false 23 length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度 24 --> 25 <id name="pid" column="id" type="java.lang.Long"> 26 <!-- generator:主键产生器。 主键生成策略--> 27 <generator class="native"></generator> 28 </id> 29 <!-- 30 property元素:除id之外的普通属性映射 31 name: 填写属性名 32 column(可选): 填写列名 33 type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型. 34 每个类型有三种填法: java类型|hibernate类型|数据库类型 35 not-null(可选):配置该属性(列)是否不能为空. 默认值:false 36 length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度 37 --> 38 <property name="pname" column="name" type="java.lang.String"></property> 39 <property name="page" column="age" type="java.lang.Integer"></property> 40 </class> 41 42 </hibernate-mapping>
3、配置hibernate映射文件
hibernate.cfg.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 4 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 5 6 <hibernate-configuration> 7 <!-- 一个session-factory只能链接一个数据库 --> 8 <session-factory> 9 <!-- 10 进行数据库连接 11 driver:驱动 12 url:地址 13 username:数据库连接用户名 14 password:数据库连接密码 15 数据库方言 16 不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成. 17 sql99标准: DDL 定义语言 库表的增删改查 18 DCL 控制语言 事务 权限 19 DML 操纵语言 增删改查 20 注意: MYSQL在选择方言时,请选择最短的方言. 21 --> 22 <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property> 23 <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property> 24 <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property> 25 <property name="connection.username">liuyang</property> 26 <property name="connection.password">orcl</property> 27 <!-- 28 自动建表 29 ## auto schema export 自动导出表结构. 自动建表 30 #hibernate.hbm2ddl.auto create 自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用) 31 #hibernate.hbm2ddl.auto create-drop 自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用) 32 #hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据). 33 #hibernate.hbm2ddl.auto validate 校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败. 34 --> 35 <property name="hbm2ddl.auto">update</property> 36 37 <!-- 将hibernate生成的sql语句打印到控制台 --> 38 <property name="show_sql">true</property> 39 40 <!-- 添加映射文件 --> 41 <mapping resource="cn/gs/ly/entity/Person.hbm.xml"></mapping> 42 </session-factory> 43 </hibernate-configuration>
4、测试类
1 package cn.gs.ly.entity.test; 2 3 import org.hibernate.Transaction; 4 import java.util.List; 5 6 import org.hibernate.SessionFactory; 7 import org.hibernate.cfg.Configuration; 8 import org.hibernate.classic.Session; 9 import org.junit.After; 10 import org.junit.Before; 11 import org.junit.Test; 12 13 import cn.gs.ly.entity.Person; 14 15 public class createTable { 16 17 SessionFactory factory =null; 18 Session se = null; 19 Transaction tr = null; 20 21 //@Before:读取并解析配置文件、映射信息、打开Session、开启事务 22 @Before 23 public void test1(){ 24 //读取配置文件 //1 创建,调用空参构造 25 Configuration con = new Configuration(); 26 //2 读取指定主配置文件 => 空参加载方法,加载src下的hibernate.cfg.xml文件 27 con.configure(); 28 //创建一个session工厂 //4 根据配置信息,创建 SessionFactory对象 29 factory = con.buildSessionFactory(); 30 //5 获得session 打开一个新的session对象 31 se = factory.openSession(); 32 //开启事务 //开启事务并获得操作事务的tr对象(建议使用) 33 tr = se.beginTransaction(); 34 } 35 //@After:提交事务、关闭Session 36 @After 37 public void afterClose(){ 38 //提交事务 39 tr.commit(); 40 //关闭session 41 se.close(); 42 } 43 44 45 /**向表中插入数据 46 * new 出来的对象为临时态,所以需要se.save()方法将其转为持久态 47 * se.save(p); 48 * */ 49 @Test 50 public void testSave(){ 51 for(int i=0;i<10;i++){ 52 Person p = new Person(); 53 p.setPname("liuyang"+i); 54 p.setPage(20); 55 se.save(p); 56 } 57 } 58 59 /**查询表中所有数据 60 * List<Person> list = se.createQuery("from Person").list(); 61 * createQuery("from TableName") 62 * */ 63 @Test 64 public void testFind(){ 65 //Person是实体类 66 List<Person> list = se.createQuery("from Person").list(); 67 for(Person s:list){ 68 System.out.println("id:"+s.getPid()+" name:"+s.getPname()+" age:"+s.getPage()); 69 } 70 } 71 72 /**通过id查找数据 73 * //get方式是按照主键进行查询 ,第二个参数为主键id 74 * //第二个参数必须和持久化类中的标示符数据类型一致 ,long类型 '1'后面加'L' 75 * Person p = (Person)se.get(Person.class, 1L); 76 * */ 77 @Test 78 public void testFindById(){ 79 /** 80 * 第二个参数必须和持久化类中的标示符数据类型一致 81 * */ 82 Person p = (Person)se.get(Person.class, 1L); //get方式是按照主键进行查询 id 83 System.out.println("id:"+p.getPid()+" name:"+p.getPname()); 84 } 85 86 /**更新数据 87 * 快照比对 88 * hibernate 在关闭session的时候 ,会自动检测处于持久态的实体类 89 * 如果实体化类有变化,则执行update操作,所以持久态更改不需要se.update(p) 90 * 临时状态 修改后需se.update(p)方法转为持久态 91 * */ 92 @Test 93 public void testUpdate(){ 94 Person p = (Person)se.get(Person.class, 1L); //持久化状态 95 //Person p = new Person(); //临时状态 修改后需se.update(p)方法转为持久态 96 //p.setPid(4L); //临时状态 97 p.setPname("LC"); 98 //se.update(p); 99 } 100 101 /**通过主键id 删除一条数据 102 * se.delete(p); 103 * */ 104 @Test 105 public void testDeleteById(){ 106 Person p = (Person)se.get(Person.class, 4L); //get方式是按照主键进行查询 id 107 //Person p = new Person(); 108 //p.setPid(4L); 109 se.delete(p); 110 } 111 112 /**删除表中所有数据 113 * 查询全部,遍历删除 114 * se.createQuery("from TableName"); 115 * se.delete(); 116 * */ 117 @Test 118 public void testDeleteAll(){ 119 //Person是实体类 120 List<Person> list = se.createQuery("from Person").list(); 121 for(Person s:list){ 122 //System.out.println(s); 123 se.delete(s); 124 } 125 } 126 127 //三种状态 128 129 /** 缓冲区内的全部对象清除 clear() 130 * 持久态<-->托管态 131 * session.evict(obj),会把指定的缓冲对象进行清除 132 * session.clear(),把缓冲区内的全部对象清除,但不包括操作中的对象 133 * */ 134 @Test 135 public void testClear(){ 136 Person p = (Person)se.get(Person.class, 1L); 137 p.setPname("LC"); 138 se.clear(); //把session中所有的对象清空后 p转为托管状态 139 se.update(p); //将p托管转为持久太 140 } 141 142 /** 指定的缓冲对象进行清除 evict() 143 * session.evict(obj),会把指定的缓冲对象进行清除 144 * session.clear(),把缓冲区内的全部对象清除,但不包括操作中的对象 145 * */ 146 @Test 147 public void testEvict(){ 148 Person p = (Person)se.get(Person.class, 2L); 149 Person p1 = (Person)se.get(Person.class, 3L); 150 p.setPname("LC2"); 151 p1.setPname("LC3"); 152 se.evict(p); //把session中指定的对象清空 。p托管 p1持久 153 } 154 155 /** New Session 开启一个新Session 156 * 一个对象是否持久化是针对同一个session来说的。一个session只能对应一个事务。 157 * */ 158 @Test 159 public void testNewSession(){ 160 Person p = (Person)se.get(Person.class, 5L); 161 p.setPname("LC0"); 162 tr.commit(); //提交事务 p游离态 163 se.close(); //关闭session 164 165 //一个对象是否持久化是针对同一个session来说的。一个session只能对应一个事务。 166 se = factory.openSession(); //开启一个新session 167 tr = se.beginTransaction(); // 开启事务 168 p.setPage(55); //无法生效 169 } 170 171 /**同时进行多种操作 172 * 插入一条数据,更新一条数据 173 * */ 174 @Test 175 public void testInsertUpdate(){ 176 //插入一条数据 177 Person p = new Person(); 178 p.setPname("superman"); 179 p.setPage(20); 180 se.save(p); 181 //更新一条数据 182 Person p1 = (Person)se.get(Person.class, 6L); 183 p1.setPname("toee"); 184 } 185 186 /**一个错误示例 187 * 错误原因: 188 * 两个持久化对象,操作的标示符的值是一样的 会报错 189 * 190 * */ 191 @Test 192 public void testWrong(){ 193 // Person p = (Person)se.get(Person.class, 5L); 194 // Person p1 = new Person(); 195 // p1.setPid(5L); 196 // se.update(p1); 197 } 198 199 }