zoukankan      html  css  js  c++  java
  • [Hibernate] List 映射例子

    List 是 java 集合的一个工具,存储线性的数据,允许重复数据。开发者可以准确控制在 list 那个位置插入数据。本例子演示 Java 的 List 集合和 MySQL 数据库的映射应用。

    使用场景:一个员工有一个或多个证书,对员工以及其拥有的证书进行增删该查操作。这个一个 1 : n的场景。

    代码的目录结构如下:

    hibernate.cfg.xml 存储数据库信息,如数据库类型,账号密码,数据库名称。

    Empoyee.hbm.xml,声明 Employee 对象及其属性和数据库表结构的对应关系。其中,Employee 的属性包括一个 Certificate 的 List 集合。后面详细介绍此文件。

    Employee.java,Employee 实体类。

    Certificate.java, Certificate 实体类。

    ManageEmployee.java,管理 Employee,并对外提供操作 Employee 对象数据的接口。

    App.java,演示本例子。

    代码详情

    EMPLOYEE, CERTIFICATE 在 MySQL 中的建表语句。

    虽然 EMPLOYEE 和 CERTIFICATE 是一对多的关系,在逻辑上 CERTIFICATE.employee_id 指向 EMPLOYEE.id,但是并没用使用外键进行约束,而是通过代码逻辑进行约束。这样的结构更灵活些。

    create table EMPLOYEE (
       id INT NOT NULL auto_increment,
       first_name VARCHAR(20) default NULL,
       last_name  VARCHAR(20) default NULL,
       salary     INT  default NULL,
       PRIMARY KEY (id)
    );
    create table CERTIFICATE (
       id INT NOT NULL auto_increment,
       certificate_name VARCHAR(30) default NULL,
       idx INT default NULL, 
       employee_id INT default NULL,
       PRIMARY KEY (id)
    );

    Certificate.java 。在数据库中 CERTIFICATE 有四个属性,其中 idex 表示证书在 List 中的位置,employee_id 表示归属哪一个员工,这两个数据在 Employee.hbm.xml 中声明,有 hibernate 自动填充。所以,只需要在 Certificate.java 中声明 id, name 属性就可以了。

    package tony.hibernateList;
    
    public class Certificate {
        private int id;
        private String name;
        
        public Certificate(){}
        public Certificate(String name){
            this.name = name;
        }
        
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }

    Employee.java,除了四个基本类型的属性外,还有一个集合属性 List<Certificate> certificates。

    package tony.hibernateList;
    
    import java.util.List;
    
    public class Employee {
        private int id;
        private String firstName;
        private String lastName;
        private int salary;
        private List<Certificate> certificates;
        
        public Employee(){}
        public Employee(String fName, String lName, int salary){
            this.firstName = fName;
            this.lastName = lName;
            this.salary = salary;
        }
        
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getFirstName() {
            return firstName;
        }
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
        public String getLastName() {
            return lastName;
        }
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
        public int getSalary() {
            return salary;
        }
        public void setSalary(int salary) {
            this.salary = salary;
        }
        public List<Certificate> getCertificates() {
            return certificates;
        }
        public void setCertificates(List<Certificate> certificates) {
            this.certificates = certificates;
        }
    }

    Employee.hbm.xml,声明了 Employee 类和数据库 EMPLOYEE 表的映射关系。hbm.xml 虽然作为 java 对象和数据库表的中间层,但是和 java 对象相似些。

    Class 元素是 java 类和数据库表的映射关系,其中 name 是 java 的全路径类名,table 是 MySQL 表名。

    id 元素是 java 类中唯一 ID 属性和数据库表中主键的映射,其中 name 是 java 属性名称,column 是数据库表的列名称,type 是 hibernate 映射类,用于转换 java 和 SQL  数据。

    property 元素是 java 属性和数据库表的列名称的映射。其中 name, column type 的作用和 id 元素的相似。

    list 元素用于声明 Employee 元素和 Certificate 之间的关系。

      cascade 表示在保存 employee 到数据库的同时,也要保存其关联的 certificates 。

      key 声明指向父类的外键。

      list-index 存储当前证书在其集合中的位置。

      one-to-many 表示这是一对多的情况。

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC  "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
    
    <hibernate-mapping>
       <class name="tony.hibernateList.Employee" table="EMPLOYEE">
          <id name="id" type="int" column="id">
             <generator class="native"/>
          </id>
          <list name="certificates" cascade="all">
             <key column="employee_id"/>
             <list-index column="idx"/>
             <one-to-many class="tony.hibernateList.Certificate"/>
          </list>
          <property name="firstName" column="first_name" type="string"/>
          <property name="lastName" column="last_name" type="string"/>
          <property name="salary" column="salary" type="int"/>
       </class>
    
       <class name="tony.hibernateList.Certificate" table="CERTIFICATE">
          <id name="id" type="int" column="id">
             <generator class="native"/>
          </id>
          <property name="name" column="certificate_name" type="string"/>
       </class>
    
    </hibernate-mapping>

    ManageEmployee.java 是 Employee 及其 Certificate 的操作类。对业务层提供操作 Employee 的接口。仅在 addEmployee 方法做了异常检测和失败回滚处理,其他方法省略,实际代码应加上。

    package tony.hibernateList;
    
    import java.util.List;
    
    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;
    
    public class ManageEmployee {
        
        private static SessionFactory factory;
        
        {
            factory = new Configuration().configure().buildSessionFactory();
        }
        
        /**
         * Add employee and certificate with transaction. Roll back if insert failed
         * @param fname
         * @param lname
         * @param salary
         * @param cert
         * @return
         */
        public Integer addEmployee(String fname, String lname, int salary, List<Certificate> cert){
             Session session = factory.openSession();
              Transaction tx = null;
              Integer employeeID = null;
              try{
                 tx = session.beginTransaction();
                 Employee employee = new Employee(fname, lname, salary);
                 employee.setCertificates(cert);
                 employeeID = (Integer)session.save(employee); 
                 tx.commit();
              }catch (HibernateException e) {
                 if (tx!=null) tx.rollback();
                 e.printStackTrace(); 
              }finally {
                 session.close(); 
              }
              return employeeID;
        }
        
        public void listEmployee(){
            Session session = factory.openSession();
            Transaction tx = null;
            
            tx = session.beginTransaction();
            List<Employee> emps = session.createQuery("FROM Employee").list();
            for (Employee emp : emps){
                System.out.println(emp.getId() + ", " + emp.getFirstName() + ", " + emp.getLastName() + ", " + emp.getSalary());
                List<Certificate> certs = emp.getCertificates();
                for (Certificate cert : certs){
                    System.out.println(cert.getId() + " | " + cert.getName());
                }
            }
            tx.commit();
            session.close();
        }
        
        public List<Employee> getAllEmployee(){
            Session session = factory.openSession();
            Transaction tx = null;
            
            tx = session.beginTransaction();
            List<Employee> emps = session.createQuery("FROM Employee").list();
            tx.commit();
            session.close();
            return emps;
        }
        
        public void updateEmployee(int employeeId, int salary){
            Session session = factory.openSession();
            Transaction tx = null;
            
            tx = session.beginTransaction();
            Employee emp = session.get(Employee.class, employeeId);
            emp.setSalary(salary);
            session.update(emp);
            tx.commit();
            session.close();        
        }
        
        public void deleteEmployee(int employeeId){
            Session session = factory.openSession();
            Transaction tx = null;
            
            tx = session.beginTransaction();
            Employee employee = session.get(Employee.class, employeeId);
            session.delete(employee);
            tx.commit();
            session.close();
        }
    }

    App.java 应用入口类,演示本例子。

    package tony.hibernateList;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class App 
    {
        public static void main( String[] args )
        {        
            ManageEmployee me = new ManageEmployee();
            
            ArrayList<Certificate> cert = new ArrayList<>();
            cert.add(new Certificate("MCA"));
            cert.add(new Certificate("MBA"));
            cert.add(new Certificate("PMP"));
            Integer empID1 = me.addEmployee("Manoj", "Kumar", 4000, cert);
            System.out.println(empID1);
    
            cert = new ArrayList<>();
            cert.add(new Certificate("HHH"));
            cert.add(new Certificate("BBB"));
            cert.add(new Certificate("CCC"));
            Integer empID2 = me.addEmployee("TTT", "FFF", 4000, cert);
            System.out.println(empID2);
            
            me.listEmployee();
            
            List<Employee> employees = me.getAllEmployee();
            Employee last2emp = employees.get(employees.size() - 2);
            me.deleteEmployee(last2emp.getId());
            
            System.out.println("End");
        }
    }

    hibernate.cfg.xml,存储数据库信息。打开 show_sql 选项,可以输出最终执行的 SQL 语句。

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    
    <hibernate-configuration>
        <session-factory>
            <property name="hibernate.dialect">
                org.hibernate.dialect.MySQLDialect
            </property>
            <property name="hibernate.connection.driver_class">
                com.mysql.jdbc.Driver
            </property>
    
            <!-- Assume test is the database name -->
            <property name="hibernate.connection.url">
                jdbc:mysql://localhost/hibernateTest
            </property>
            <property name="hibernate.connection.username">
                username
            </property>
            <property name="hibernate.connection.password">
                password
            </property>
    
            <property name="show_sql">true</property>
    
            <!-- List of XML mapping files -->
            <mapping resource="Employee.hbm.xml" />
    
        </session-factory>
    </hibernate-configuration>

    参考资料

    Hibernate - List Mappings, tutorialspoint

  • 相关阅读:
    调整心态,夯实基础
    js实现轮播图动画(更新"旋转木马")
    封装简单动画函数-由简到完善
    纯Css绘制三角形箭头三种方法
    JS实现图片''推拉门''效果
    一个基于 canvas 的画板
    Python 控制台进度条的实现
    Flask博客开发——Tinymce编辑器
    Flask博客开发——登录验证码
    用于水和水蒸汽物性计算的Python模块——iapws
  • 原文地址:https://www.cnblogs.com/TonyYPZhang/p/5988692.html
Copyright © 2011-2022 走看看