一:基本开发流程:
-->导入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的执行效率! 配置一对多与多对一,这种叫“双向关联” 只配置一对多, 叫“单项一对多” 只配置多对一, 叫“单项多对一” 注意: 配置了哪一方,哪一方才有维护关联关系的权限!