码迷,mamicode.com
首页 > Web开发 > 详细

hibernate学习笔记(1)

时间:2016-06-24 15:20:25      阅读:346      评论:0      收藏:0      [点我收藏+]

标签:

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. 测试

—————–使用注解的方式

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 事务的隔离级别

hibernate学习笔记(1)

标签:

原文地址:http://blog.csdn.net/nogfexception/article/details/51743691

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!