Hibernate开发流程

Posted 染红の街道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate开发流程相关的知识,希望对你有一定的参考价值。

一:基本开发流程:

  -->导入jar包,hibernate.jar + required + jpa + 数据库驱动包

  -->对实体类进行映射,写配置文件

  -->src目录下添加hibernate.cfg.xml文件

    数据库相关配置,其他相关配置(是否显示sql,是否自动建表等),映射文件加载

  -->测试DAO

二:hibernate程序执行流程

  

 

三:hibernate.cfg.xml配置详解

 1  <!DOCTYPE hibernate-configuration PUBLIC
 2         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 3         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 4 
 5 <hibernate-configuration>
 6     <session-factory>
 7         
 8         <!-- 1,数据库信息设置 -->
 9         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
10         <property name="hibernate.connection.username">root</property>
11         <property name="hibernate.connection.password">7758</property>
12         <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
13         <!-- 数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql -->
14         <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
15 
16         
17         <!-- 2,其他相关配置 -->
18         <!-- 2.1,是否显示sql语句 -->
19         <property name="hibernate.show_sql">true</property>
20         <!-- 2.2,是否格式化显示sql语句 -->
21 <!--         <property name="hibernate.format_sql">true</property> -->
22         <!-- 
23             3.3,是否自动建表:
24                 ①create 每次执行sql语句都建表,若果已存在就先删除再创建
25                  ②update 如果表不存在则创建
26                  ③create-drop 每次创建sessionFacrory都会创建表,close之后删除
27                  ④validate 严格检验,如果表和映射文件不同时报错,测试环节使用
28          -->
29         <property name="hibernate.hbm2ddl.auto">update</property>
30                 
31         <!-- 3,加载映射文件 -->
32         <mapping resource="hibernate/User.hbm.xml"/>
33 
34     </session-factory>
35 </hibernate-configuration>

四:数据表和实体类的映射

  ①:单表映射

 1 public class User {        
 2 private String id;
 3         private String pwd;
 4     private String name;
 5     private String phone;
 6     private String email;
 7     private String img;    
 8         .... 
 9 }
10 
11 
12 <?xml version="1.0"?>
13 <!DOCTYPE hibernate-mapping PUBLIC 
14     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
15     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
16 
17 <hibernate-mapping package="hibernate">
18     
19     <class name="hibernate.User" table="User2">
20         
21         <!-- 
22             主键的配置:
23                 1,单主键配置:name,column,type,length
24                 2,主键自增长策略:<generator class="增长策略"></generator>
25                     assigned:表示手动指定主键,也可以不写generator标签
26                     identity:mysql,db2数据库采用此方式
27                     sequence:自增长,Oracle采用此模式,所有表使用一个sequence
28                     native:根据底层数据库实现自动选择方式
29                     increment:不建议使用,当并发处理时可能出现问题
30                 3,联合主键,观看User2.hbm.xml
31          -->
32         <id name="id" column="id">
33             <generator class="assigned"></generator>
34         </id>
35         
36         <!-- 
37             非主键的映射:property标签
38             name:    ==对象属性名
39             column:    ==表的列名
40                 可以不写(默认与对象属性名相同);
41                 尽量不要使用关键字,如果使用加上转义符(``),例如`desc`
42              type:    ==需要映射的表字段类型(不写默认与实体类属性格式相同)
43              length:    ==格式的长度,只针对字符类型长度;例如可以指定字符长度不超过20
44              unique:    ==该列值是否唯一
45          -->
46         <property name="pwd" column="pwd" ></property>
47         <property name="name" column="name" length="20" unique="true"></property>
48         <property name="phone" column="phone"></property>
49         <property name="email" column="email"></property>
50         <property name="img" column="img"></property>
51         
52     </class>
53 
54 
55 </hibernate-mapping>

  ②联合主键

 1 //联合主键,需要实现serialiazable
 2 public class UserMulKey implements Serializable {
 3     private String id;
 4     private String pwd;
 5         。。。
 6  7 //实体类
 8 public class User2 {
 9     private UserMulKey mulKey;
10     private String name;
11     private String phone;
12     private String email;
13     private String img;
14         。。。
15
 1 。。。
 2         <!-- 
 3             联合主键的配置:
 4          -->
 5         <composite-id name="mulKey">
 6             <key-property name="id" column="id" length="20"></key-property>
 7             <key-property name="pwd" column="pwd" length="20"></key-property>
 8         </composite-id>
 9 
10 。。。

  ③关联映射(1:N | N:1)

public class Dept {

    private int deptId;
    private String deptName;
    // 【一对多】 部门对应的多个员工
    private Set<Employee> emps = new HashSet<Employee>();
    
public class Employee {

    private int empId;
    private String empName;
    private double salary;
    // 【多对一】员工与部门
    private Dept dept;

Dept.hbm.xml    
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.b_one2Many">
    
    <class name="Dept" table="t_dept">
        <id name="deptId">
            <generator class="native"></generator>
        </id>    
        <property name="deptName" length="20"></property>
        
        <!-- 
            一对多关联映射配置  (通过部门管理到员工)
            Dept 映射关键点:
            1.  指定 映射的集合属性: "emps"
            2.  集合属性对应的集合表: "t_employee"
            3.  集合表的外键字段   "t_employee. dept_id"
            4.  集合元素的类型
            
         -->
         <set name="emps">   <!-- table="t_employee" -->
              <key column="dept_id"></key>
              <one-to-many class="Employee"/>
         </set>
         
         
    </class>
    

</hibernate-mapping>


Employee.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.b_one2Many">
    
    <class name="Employee" table="t_employee">
        <id name="empId">
            <generator class="native"></generator>
        </id>    
        <property name="empName" length="20"></property>
        <property name="salary" type="double"></property>
        
        <!-- 
            多对一映射配置
            Employee 映射关键点:
            1.  映射的部门属性  :  dept
            2.  映射的部门属性,对应的外键字段: dept_id
            3.  部门的类型
         -->
         <many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>
         
    </class>
    

</hibernate-mapping>

测试

public class App {
    
    private static SessionFactory sf;
    static {
        sf = new Configuration()
            .configure()
            .addClass(Dept.class)   
            .addClass(Employee.class)   // 测试时候使用
            .buildSessionFactory();
    }

    // 保存, 部门方 【一的一方法操作】
    @Test
    public void save() {
        
        Session session = sf.openSession();
        session.beginTransaction();
        
        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("应用开发部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        dept.getEmps().add(emp_zs);
        dept.getEmps().add(emp_ls);

        // 保存
        session.save(emp_zs);
        session.save(emp_ls);
        session.save(dept); // 保存部门,部门下所有的员工  
        
        session.getTransaction().commit();
        session.close();
        /*
         *  结果
         *  Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            Hibernate: insert into t_dept (deptName) values (?)
            Hibernate: update t_employee set deptId=? where empId=?    维护员工引用的部门的id
            Hibernate: update t_employee set deptId=? where empId=?
         */
    }
    // 【推荐】 保存, 部员方 【多的一方法操作】
    @Test
    public void save2() {
        
        Session session = sf.openSession();
        session.beginTransaction();
        
        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("综合部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        emp_zs.setDept(dept);
        emp_ls.setDept(dept);
        
        
        // 保存
        session.save(dept); // 先保存一的方法
        session.save(emp_zs);
        session.save(emp_ls);// 再保存多的一方,关系回自动维护(映射配置完)
        
        session.getTransaction().commit();
        session.close();
        /*
         *  结果
         *  Hibernate: insert into t_dept (deptName) values (?)
            Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            少生成2条update  sql
         */
    }
    
}

总结:
  在一对多与多对一的关联关系中,保存数据最好的通过多的一方来维护关系,这样可以减少update语句的生成,从而提高hibernate的执行效率!
    
配置一对多与多对一,这种叫“双向关联”
只配置一对多,           叫“单项一对多”
只配置多对一,           叫“单项多对一”

注意:
    配置了哪一方,哪一方才有维护关联关系的权限!

 

以上是关于Hibernate开发流程的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate开发流程

具有运行时 pojos 的带有 Hibernate 的 OSGi 片段包

hibernate

VSCode自定义代码片段——git命令操作一个完整流程

SSH(Struts2+Spring+Hibernate)框架搭建流程

VSCode自定义代码片段15——git命令操作一个完整流程