标签:
Hibernate 框架学习
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库(对象关系映射)(orm)
数据持久化:将内存中的对象转换到数据库中(硬盘中)
—-hibernate 可以接触 JUNIT 单元测试
——-1.配置使用hibernate 添加hibernate的jar包
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.5.Final</version>
</dependency>
同时添加数据库驱动
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
————————2.下面配置xml文件
http://www.cnblogs.com/pepcod/archive/2013/02/19/2917376.html 参考
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/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://localhost:3306/hibernate</hibernate>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123</property>
<property name="Connection.useUnicode">true</property>
<property name="connection.characterEncoding">utf8</property>
<!-- 方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 控制台能够输出SQL语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 帮你生成对应的表,或者是表的更新 -->
<property name="hibernate.hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>
———————3. 建立对应实体对象并且对实体进行XML文件配置
建立学生类Student 创建 Student.hbm.xml 一个类对应的一个xml文件
http://pmroad.blog.51cto.com/9744929/1591245 参考
<?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 package="com.zr.model">
<class name="Student" table="t_student">
<id name="id" column="sid">
<!-- 主键策略的配置 -->
<generator class="native"></generator>
</id>
<property name="sname"></property>
</class>
</hibernate-mapping>
在这里我们通过配置XML方式对实体进行关系映射
官方推荐的方式 都是采用注解的方式
要通过这个注解的方式配置,必需的熟练XML配置
4.将映射文件加入到sessionfactory配置中
<mapping resource="com/zr/model/Student.hbm.xml" />
5.使用hibernate 一些接口 将数据持久化 (1.读取配置文件 2.创建SessionFactory 3.创建session 4. 在session当中做CRUD的操作)
//读取配置文件,创建sessionFactory工厂
public class Test {
public static void main(String[] args) {
//读取配置文件,创建sessionFactory工厂
Configuration config = (Configuration) new Configuration().configure();
//config.buildSessionFactory() 可以使用,但不建议
// 注册服务
ServiceRegistry sr = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
//创建工厂
SessionFactory sf = config.buildSessionFactory(sr);
//创建session
Session session = sf.openSession();
//在session 中做crud的操作 数据进行持久画
//通过session 开启事务
session.beginTransaction();
//-----------------CRUD操作
Student s= new Student();
s.setSname("wwj");
session.save(s);
//-----------------CRUD操作
//事务的提交
session.getTransaction().commit();
//关闭session
session.close();
//关闭工厂
sf.close();
}
}
—————–使用注解的方式
1.
@Entity
@Table(name="t_teacher")
public class Teacher {
private int tid;
private String tname;
//一定是在get方法上面
@Id
@GeneratedValue(generator="s_native")
@GenericGenerator(name="s_native",strategy="native")
public int getTid() {
return tid;
}
public void setTid(int tid) {
this.tid = tid;
}
@Column(name="t_name")
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
}
注意:对于属性的注解 一定是在get方法上面
2.配置注解的类到config配置文件中
<mapping class="com.zr.model.Teacher"/>
3.测试
—————————————————————————下午
session 的CRUD 基本操作 JUNIT 单元测试
1.对sessionFactory 进行工具类封装
/**
* 通过该工具类生产出唯一一个SessionFactory( 采用单例模式)
* @author Administrator
*
*/
public class HibernateUtil {
private static final SessionFactory sf = bulidSessionFactory();
private HibernateUtil(){};
private static SessionFactory bulidSessionFactory(){
Configuration config = (Configuration) new Configuration().configure();
ServiceRegistry sr = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
return config.buildSessionFactory(sr);
}
public static SessionFactory getSf() {
return sf;
}
}
2.使用JUNIT
2.1 引入junit
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
2.2 为Dao添加测试类
右键指着需要对哪一个dao进行测试 -new - junit case
勾选你需要对该dao的哪些方法进行测试
2.3.session 的crud 操作
public class StudentDaoTest {
private SessionFactory sf = HibernateUtil.getSf();
private Session session;
@Before
public void setSession(){
session = sf.openSession();
session.beginTransaction();
}
@After
public void closeSessionandSf(){
session.getTransaction().commit();
//关闭session
session.close();
//关闭工厂
sf.close();
}
//存 增加 使用save方法
@Test
public void testAddStudent() {
Student s = new Student();
s.setSname("wwj");
session.save(s);
}
//删 先通过ID来查询,在调用delete方法删除对象
@Test
public void testDeleteStudent() {
Student s = (Student) session.get(Student.class, Integer.valueOf(1));
session.delete(s);
}
//修改 先通过ID来查询,直接对对象进行赋值操作
@Test
public void testUpdateStudent() {
Student s = (Student) session.get(Student.class, Integer.valueOf(2));
s.setSname("xyz");
}
//查询 初次接触HQL HQL面向对象语句思维方式
@Test
public void testSelectStudents() {
String hql = "from Student";
Query query = session.createQuery(hql);
List<Student> ss =query.list();
for (Student student : ss) {
System.out.println(student.getSname());
}
}
}
———————————————————- OID 对象映射标示符(掌握) 和主键的生成的策略(掌握)
概念: 1.session 缓存的概念
2. 对象映射标示 OID
在对象的判定上面 是以session缓存中 对象的OID标识符来进行判定,如果缓存中有,那么就在缓存取,没有还得去数据中查找
//测试对象映射标识符
@Test
public void testOID(){
Student s1 = (Student) session.get(Student.class, Integer.valueOf(2));
Student s2 = (Student) session.get(Student.class, Integer.valueOf(3));
Student s3 = (Student) session.get(Student.class, Integer.valueOf(2));
System.out.println(s1==s2);
System.out.println(s1==s3);
}
对应执行的HQL语句
Hibernate: select student0_.sid as sid1_0_0_, student0_.sname as sname2_0_0_ from t_student student0_ where student0_.sid=?
Hibernate: select student0_.sid as sid1_0_0_, student0_.sname as sname2_0_0_ from t_student student0_ where student0_.sid=?
主键生成的策略: 为了保证数据唯一实例
1.increment : 通过 hibernate自身 自动以递增方式生成主键策略
Hibernate: select max(sid) from t_student
Hibernate: insert into t_student (sname, sid) values (?, ?)
2.identity: 采用数据库提供的主键生成机制。(orcale数据库不支持)
3.sequence: 采用数据库提供的主键生成机制 (只支持oracle)
4.hilo: 算法实现的主键生成机制
5.native: 根据数据库自动生成主键策略
hibernate映射关系 一对一 一对多 多对多(配置XML 要么使用注解)(重点)
http://blog.csdn.net/laner0515/article/details/12905711 参考资料
(掌握)事务的隔离级别和hibernate乐观锁和悲观锁 sql语句 for update
http://lavasoft.blog.51cto.com/62575/39398/ XML配置
http://www.cnblogs.com/xiaoluo501395377/p/3374955.html 注解映射
关系映射: 面向对象的思维方式
一共是三种: 一对一 一对一 在数据库中 共用主键 老师下面tid 学生有sid tid 和sid是保持一致(特别难维护)
一对多 ————-》一对多在数据库中 外键关联 老师下面tid 学生有sid和tid (建议一对一也采取这种设计方式)
多对多 多对多在数据库中 有一张三方表 第三方表里面有对应 tid和sid
现在我们使用hibernate 正向开发
一对一 一对多 多对多 都存在双向关联
最后转换代码 :就是在我们xml文件配置对象与对象关联关系
一对一的配置:(双向) (单向删除一方配置即可) (将自身表的主键又做为外键关联另一表的主键 反之另外一张表一样)
public class Person {
private int pid;
private String pname;
private IdCard idcard;
}
public class IdCard {
private int cid;
private String cname;
private Person person;
}
对应XML映射文件:
Person:
<hibernate-mapping package="com.zr.model">
<class name="Person" table="t_person">
<id name="pid">
<generator class="foreign">
<param name="property">idcard</param>
</generator>
</id>
<property name="pname"></property>
<one-to-one name="idcard" constrained="true"></one-to-one>
</class>
</hibernate-mapping>
Idcard:
<hibernate-mapping package="com.zr.model">
<class name="IdCard" table="t_idcard">
<id name="cid" >
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<property name="cname"></property>
<one-to-one name="person" constrained="true"></one-to-one>
</class>
</hibernate-mapping>
注意:如果constrained=true,则表明存在外键与关联表对应,并且关联表中肯定存在对应的键与其对应,
一对多映射:单向
一个订单下有多个商品
public class Order {
private int oid;
private String oname;
}
public class Produce {
private int pid;
private String pname;
private Order order;
}
对应的映射文件
order:
<hibernate-mapping package="com.zr.model">
<class name="Order" table="t_order">
<id name="oid" >
<!-- 主键策略的配置 -->
<generator class="native"></generator>
</id>
<property name="oname"></property>
</class>
</hibernate-mapping>
produce:
<hibernate-mapping package="com.zr.model">
<class name="Produce" table="t_produce">
<id name="pid" >
<generator class="native"></generator>
</id>
<property name="pname"></property>
<many-to-one name="order" column="oid"/>
</class>
</hibernate-mapping>
如果在多的一方保存数据的时候同时也保存一的一方数据,需要设置级联的属性cascade
Cascade 属性值:
none:在保存、删除修改对象的时候,不考虑其附属物的操作
save-update:在保存、更新当前对象时,级联保存、更新附属物。
delete:在删除当前对象时,级联删除附属物。
all: 包含save-update和delete的操作
delete-orphan:删除和当前对象解除关系的附属对象。
一对多映射 双向关联
public class Dad {
private int did;
private String dname;
private Set<Son> sons = new HashSet<Son>();
}
public class Son {
private int sid;
private String sname;
private Dad dad;
}
对应的映射文件:
Dad:
<hibernate-mapping package="com.zr.model">
<class name="Dad" table="t_dad">
<id name="did" >
<!-- 主键策略的配置 -->
<generator class="native"></generator>
</id>
<property name="dname"></property>
<set name="sons" cascade="save-update">
<key column="dadid"></key>
<one-to-many class="com.zr.model.Son"/>
</set>
</class>
</hibernate-mapping>
Son:
<hibernate-mapping package="com.zr.model">
<class name="Son" table="t_son">
<id name="sid" >
<!-- 主键策略的配置 -->
<generator class="native"></generator>
</id>
<property name="sname"></property>
<many-to-one name="dad">
<column name="dadid"/>
</many-to-one>
</class>
</hibernate-mapping>
配置 inverse: 一般是在一的一端设置这个属性 反转
将维护关系交由多的一方进行管理
Hibernate: insert into t_dad (dname) values (?)
Hibernate: insert into t_son (sname, dadid) values (?, ?)
Hibernate: update t_son set dadid=? where sid=? 没有设置
Hibernate: insert into t_dad (dname) values (?)
Hibernate: insert into t_son (sname, dadid) values (?, ?)
多对多 双向关联
public class Plane {
private int pid;
private String pname;
private Set<DaPao> dps;
}
public class DaPao {
private int did;
private String dname;
private Set<Plane> planes;
}
对应的映射文件:
plane:
<hibernate-mapping package="com.zr.model">
<class name="Plane" table="t_plane">
<id name="pid">
<generator class="native"></generator>
</id>
<property name="pname"></property>
<set name="dps" table="d_p" >
<key column="pid" />
<many-to-many
column="did"
class="com.zr.model.DaPao"/>
</set>
</class>
</hibernate-mapping>
dapao:
<hibernate-mapping package="com.zr.model">
<class name="DaPao" table="t_dapao">
<id name="did" >
<!-- 主键策略的配置 -->
<generator class="native"></generator>
</id>
<property name="dname"></property>
<set name="planes" table="d_p" >
<key column="did"/>
<many-to-many
column="pid"
class="com.zr.model.Plane"/>
</set>
</class>
</hibernate-mapping>
一对多的自身双向关联:
public class Func {
private int fid;
private String fname;
private Set<Func> childrenFuncs = new HashSet<Func>();
private Func parentFunc;
}
对应的映射文件:
<hibernate-mapping package="com.zr.model">
<class name="Func" table="t_func">
<id name="fid" >
<generator class="native"></generator>
</id>
<property name="fname"></property>
<many-to-one name="parentFunc" column="parentfid" cascade="save-update" ></many-to-one>
<set name="childrenFuncs" cascade="save-update" inverse="true">
<key column="parentfid"></key>
<one-to-many class="com.zr.model.Func" />
</set>
</class>
</hibernate-mapping>
(掌握)事务的隔离级别和hibernate乐观锁和悲观锁 sql语句 for update
http://blog.csdn.net/jialinqiang/article/details/8723051 悲观锁和乐观锁
http://www.cnblogs.com/jerryxing/archive/2012/04/24/2468999.html 事务的隔离级别
标签:
原文地址:http://blog.csdn.net/nogfexception/article/details/51743691