一:主键生成策略种类
1:程序员自己控制 assigned(必须指定主键的值)
2:数据库控制 {(mysql对应)identify, (oracle对应)sequence}
3:跨数据库 native(只需要改变配置的方言即可)
4:hibernate (increment,uuid,uuid.hex)
5:自定义 identifygrentor接口(企业开发用的最多)
详细解释:. 主键生成器要求
2.1 assigned
数据类型不限、保存前必须赋值
2.2 identity(重点掌握)
数字,无需赋值
2.3 sequence(重点掌握)
数字,无需赋值, 默认使hibernate_sequence这个序列,
也可以通过sequence/sequence_name参数赋值
2.4 increment
数字,无需赋值
2.5 uuid/uuid.hex (是由容器自动生成的一个32位的字符串,.hex代表的是十六进制)
32位的字符串,无需赋值,
2.6 native(重点掌握)
等于identity+sequence
3. 自定义主键生成器
3.1 *.hbm.xml指定主键生成器类
<generator class="xxx.MyTsGenerator"/>
3.2 创建主键生成器类
实现org.hibernate.id.IdentifierGenerator接口即可,并还可以实现org.hibernate.id.Configurable接口来读取一些配置信息
PersistentIdentifierGenerator.TABLE
PersistentIdentifierGenerator.PK
assigned、native、自定义主键
三:报错
根事务提交的错误(没有动态事务所以要开启动态事务)
解决:工具类中加入如下代码 开启动态事务
session.beginTransaction();
2:实体类的映射文件中的table 属性name的值没有与数据库表的
四:案列
工具类:
package com.zking.two.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/** 工具类的用途
* 1:方便获取session会话,用来操作数据库
* 2:用来检验所有映射的配置文件配置是否准确
* @author Administrator
*
*/
public class SessionFactoryUtil {
private static SessionFactory sessionFactory;
//创建一个本地session
static {
Configuration cfg=new Configuration().configure("hibernate.cfg.xml");
sessionFactory=cfg.buildSessionFactory();
}
//获取session
public static Session getSession() {
//拿本地的session
Session session = sessionFactory.getCurrentSession();
//判断,如果本地会话为空的话就创建一个本地的会话
if(session==null) {
session=sessionFactory.openSession();
}
return session;
}
//关闭session
public static void closeSession() {
Session session = sessionFactory.getCurrentSession();
if(session!=null&&session.isOpen()) {
session.close();
}
}
/**
* 根事务提交的错误(没有动态事务所以要开启动态事务)
* Exception in thread "main" org.hibernate.HibernateException: Calling method 'isConnected' is not valid without an active transaction (Current status: NOT_ACTIVE)
* @param args
*/
public static void main(String[] args) {
Session session = SessionFactoryUtil.getSession();
//开启动态事务
session.beginTransaction();
System.out.println(session.isConnected());
SessionFactoryUtil.closeSession();
System.out.println(session.isConnected());
}
}
dao方法
package com.zking.two.dao;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.zking.two.entity.Student;
import com.zking.two.entity.Worker;
import com.zking.two.util.SessionFactoryUtil;
public class IdentifierDao {
public Integer addStudent(Student student) {
Session session = SessionFactoryUtil.getSession();
Transaction transaction = session.beginTransaction();
//save方法返回的是序列化的接口 可以强制转化为id对应的类型 即student的id
Integer sid =(Integer) session.save(student);
transaction.commit();
session.close();
return sid;
}
public String addWorker(Worker worker) {
Session session = SessionFactoryUtil.getSession();
Transaction transaction = session.beginTransaction();
//save方法返回的是序列化的接口 可以强制转化为id对应的类型 即student的id
String wid =(String) session.save(worker);
transaction.commit();
session.close();
return wid;
}
}
实体类对应的映射类
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!--
table:实体类对应的表明
name:实体类的全类名
-->
<class name="com.zking.two.entity.Student" table="t_hibernate_student">
<id name="sid" type="java.lang.Integer" column="sid">
<!-- 程序员自己控制(必须指定主键的值) -->
<!-- <generator class="assigned" /> -->
<!-- 数据库控制 -->
<!-- mysql数据库 <generator class="identity" /> -->
<!-- <generator class="sequence" >
orcal数据库 可以指定序列
<param name="sequence_name">xxxs</param>
</generator> -->
<!-- 实现跨数据库主键生成策略 只需要改主配置文件的方言即可(这种设计值运用于数字类型的)-->
<!-- <generator class="native"> </generator> -->
<!-- 交给hibernate来控制主键生成 -->
<generator class="increment"> </generator>
</id>
<property name="sname" type="java.lang.String"
column="sname">
</property>
</class>
</hibernate-mapping>
entity
package com.zking.two.entity;
public class Student {
private Integer sid;
private String sname;
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
}
主配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 1. 数据库相关 -->
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置本地事务(No CurrentSessionContext configured!) -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 2. 调试相关 -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- 讲解主键生成策略所配置的文件-->
<mapping resource="com/zking/two/entity/Student.hbm.xml"></mapping>
<mapping resource="com/zking/two/entity/Worker.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>