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 tableEMPLOYEE (
idINT NOT NULLauto_increment,
first_nameVARCHAR(20) default NULL,
last_nameVARCHAR(20) default NULL,
salaryINT default NULL,PRIMARY KEY(id)
);
create tableCERTIFICATE (
idINT NOT NULLauto_increment,
certificate_nameVARCHAR(30) default NULL,
idxINT default NULL,
employee_idINT default NULL,PRIMARY KEY(id)
);
Certificate.java 。在数据库中 CERTIFICATE 有四个属性,其中 idex 表示证书在 List 中的位置,employee_id 表示归属哪一个员工,这两个数据在 Employee.hbm.xml 中声明,有 hibernate 自动填充。所以,只需要在 Certificate.java 中声明 id, name 属性就可以了。
packagetony.hibernateList;public classCertificate {private intid;privateString name;publicCertificate(){}publicCertificate(String name){this.name =name;
}public intgetId() {returnid;
}public void setId(intid) {this.id =id;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}
}
Employee.java,除了四个基本类型的属性外,还有一个集合属性 List certificates。
packagetony.hibernateList;importjava.util.List;public classEmployee {private intid;privateString firstName;privateString lastName;private intsalary;private Listcertificates;publicEmployee(){}public Employee(String fName, String lName, intsalary){this.firstName =fName;this.lastName =lName;this.salary =salary;
}public intgetId() {returnid;
}public void setId(intid) {this.id =id;
}publicString getFirstName() {returnfirstName;
}public voidsetFirstName(String firstName) {this.firstName =firstName;
}publicString getLastName() {returnlastName;
}public voidsetLastName(String lastName) {this.lastName =lastName;
}public intgetSalary() {returnsalary;
}public void setSalary(intsalary) {this.salary =salary;
}public ListgetCertificates() {returncertificates;
}public void setCertificates(Listcertificates) {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 表示这是一对多的情况。
ManageEmployee.java 是 Employee 及其 Certificate 的操作类。对业务层提供操作 Employee 的接口。仅在 addEmployee 方法做了异常检测和失败回滚处理,其他方法省略,实际代码应加上。
packagetony.hibernateList;importjava.util.List;importorg.hibernate.HibernateException;importorg.hibernate.Session;importorg.hibernate.SessionFactory;importorg.hibernate.Transaction;importorg.hibernate.cfg.Configuration;public classManageEmployee {private staticSessionFactory factory;
{
factory= newConfiguration().configure().buildSessionFactory();
}/*** Add employee and certificate with transaction. Roll back if insert failed
*@paramfname
*@paramlname
*@paramsalary
*@paramcert
*@return
*/
public Integer addEmployee(String fname, String lname, int salary, Listcert){
Session session=factory.openSession();
Transaction tx= null;
Integer employeeID= null;try{
tx=session.beginTransaction();
Employee employee= newEmployee(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();
}returnemployeeID;
}public voidlistEmployee(){
Session session=factory.openSession();
Transaction tx= null;
tx=session.beginTransaction();
List emps = session.createQuery("FROM Employee").list();for(Employee emp : emps){
System.out.println(emp.getId()+ ", " + emp.getFirstName() + ", " + emp.getLastName() + ", " +emp.getSalary());
List certs =emp.getCertificates();for(Certificate cert : certs){
System.out.println(cert.getId()+ " | " +cert.getName());
}
}
tx.commit();
session.close();
}public ListgetAllEmployee(){
Session session=factory.openSession();
Transaction tx= null;
tx=session.beginTransaction();
List emps = session.createQuery("FROM Employee").list();
tx.commit();
session.close();returnemps;
}public void updateEmployee(int employeeId, intsalary){
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(intemployeeId){
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 应用入口类,演示本例子。
packagetony.hibernateList;importjava.util.ArrayList;importjava.util.List;public classApp
{public static voidmain( String[] args )
{
ManageEmployee me= newManageEmployee();
ArrayList 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 employees =me.getAllEmployee();
Employee last2emp= employees.get(employees.size() - 2);
me.deleteEmployee(last2emp.getId());
System.out.println("End");
}
}
hibernate.cfg.xml,存储数据库信息。打开 show_sql 选项,可以输出最终执行的 SQL 语句。
org.hibernate.dialect.MySQLDialect
com.mysql.jdbc.Driver
jdbc:mysql://localhost/hibernateTest
username
password
true
参考资料