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

[Hibernate] List 映射例子的更多相关文章

  1. [Hibernate] 注解映射例子

    Hibernate 注解(Hibernate Annotation) 是一种比较新的方式,通过在 java 简单类增加注解,来声明 java 类和数据库表的映射,作用和 xml 文件相似.hibern ...

  2. hibernate集合映射inverse和cascade详解

    hibernate集合映射inverse和cascade详解   1.到底在哪用cascade="..."? cascade属性并不是多对多关系一定要用的,有了它只是让我们在插入或 ...

  3. web进修之—Hibernate 关系映射(3)

    概述 Hibernate的关系映射是Hibernate使用的难点或者是重点(别担心,不考试哦~),按照不同的分类方式可以对这些映射关系做一个分类,如: 按对象对应关系分: 一对一 多对一/一对多 多对 ...

  4. Hibernate集合映射

    可以在Hibernate中映射持久类的集合元素. 您需要从以下类型之一声明持久类中的集合类型: java.util.List java.util.Set java.util.SortedSet jav ...

  5. 关于hibernate字段映射@colunm出现的问题以及jpa驼峰大写转_小写的问题探究

    关于hibernate字段映射@colunm出现的问题以及jpa驼峰大写转_小写的问题探究2018年04月24日 15:47:26 守望dfdfdf 阅读数:735 标签: @colunmhibern ...

  6. hibernate的映射类型

    hibernate的映射类型 hibernate MySQL映射类型 1.Hibernate的映射类型 hibernate mysql映射类型 Hibernate 映射类型 Java 类型 标准 SQ ...

  7. Hibernate关联映射关系

    Hibernate关联映射关系 一.双向一对多关联映射关系:当类与类之间建立了关联,就可以方便的从一个对象导航到另一个或另一组与它关联的对象(一对多双向关联和多对一双向关联是完全一样的) 1.1创建实 ...

  8. 攻城狮在路上(壹) Hibernate(九)--- Hibernate的映射类型

    Hibernate采用映射类型作为Java类型和SQL类型的桥梁,对应type属性.分为两种:内置映射类型和客户化映射类型.一.内置映射类型: 1.Java基本类型的Hibernate映射类型: Ja ...

  9. Hibernate注解映射sequence时出现无序增长问题+hibernate 映射 oracle ID自动增长:

    Hibernate注解映射sequence时出现无序增长问题+hibernate 映射 oracle ID自动增长: 通过Hibernate注解的方式映射oracel数据库的sequence主键生成器 ...

随机推荐

  1. mysql locktables

    SELECT      r.trx_id waiting_trx_id,      r.trx_mysql_thread_id waiting_thread,      TIMESTAMPDIFF(  ...

  2. Struts2默认拦截器配置

    http://blog.csdn.net/axin66ok/article/details/7321430

  3. iOS7初体验(1)——第一个应用程序HelloWorld

    iOS7 Beta已经发布了,迫不及待地下载了iOS 7及Xcode 5并体验了一下.先做一个简单的Hello World看看都有哪些变化吧. 1. 启动Xcode5-DP: 2. 从菜单选择File ...

  4. An App ID with Identifier 'xxxxxx’ is not available. Please ....

    1.完全关闭Xcode; 2.找到钥匙串,将钥匙串(Keychain)中的对应证书移除: 3.再次打开Xcode,通过 Preferences - Account 4. 删除原先的账号重新登录, 搞定 ...

  5. ITEXTSHARP学习整理

    学习的版本iTextSharp.5.5.5. 关于获取PDF中的图片资源 /// <summary> /// 将PDF中的图片资源转换成二进制 /// </summary> / ...

  6. [转]Mysql导入导出工具Mysqldump和Source命令用法详解

    Mysql本身提供了命令行导出工具Mysqldump和Mysql Source导入命令进行SQL数据导入导出工作,通过Mysql命令行导出工具Mysqldump命令能够将Mysql数据导出为文本格式( ...

  7. 仿小米网jQuery全屏滚动插件fullPage.js

    演 示 下 载   简介 如今我们经常能见到全屏网站,尤其是国外网站.这些网站用几幅很大的图片或色块做背景,再添加一些简单的内容,显得格外的高端大气上档次.比如 iPhone 5C 的介绍页面,QQ浏 ...

  8. javascript——迭代方法

    <script type="text/javascript"> //五个迭代方法 都接受两个参数:要在每一项上运行的函数 和 运行该函数的作用域(可选) //every ...

  9. linxu 挂载分区

    1. 添加新硬盘 设置 -> Storage -> SATA控制器->右击,选择“添加虚拟硬盘” 然后,根据需求创建合适的硬盘 2. 重启虚拟机 查看现有系统的磁盘空间 sudo f ...

  10. dede导航设置成单页面内容

    有时顶级导航可能就是一个单页面 如公司简介 联系我们等 方法一:直接在导航栏填写内容 常规设置 二高级选项设置模板 三 填写页面内容 四 模板页面调用 内容 可在栏目模板中用{dede:field.c ...