一、主键映射
1.1 SQL语句设置主键
+++ SQL设置简单主键
CREATE TABLE `emp` (
`e_name` varchar(255) NOT NULL,
`e_card_id` varchar(255) NOT NULL,
`e_birth` datetime DEFAULT NULL,
PRIMARY KEY (`e_name`)
)
+++ SQL设置复合主键
CREATE TABLE `emp` (
`e_name` varchar(255) NOT NULL,
`e_card_id` varchar(255) NOT NULL,
`e_birth` datetime DEFAULT NULL,
PRIMARY KEY (`e_name`,`e_card_id`)
)
1.2 主键的作用
+++ 一个表中只能有一个主键
+++ 什么要设置主键?
数据库存储的数据都是有效的,必须保持数据的唯一性。
+++ 在数据库表中,为什么常把id作为主键。
因为表中通常找不到合适的列作为唯一列即主键,所以引入了id。
因为id是数据库系统维护,可以保证唯一,所以就把这列作为主键!
+++ 设置主键的方式
设计数据库表结构时,我们有两种方式来设置主键。
===》方式一:引入id列。
id由数据库来维护。可以确保数据的唯一性。
===》方式二:复合主键。
即多列的值作为一个主键,从而确保数据的唯一性。
引入id作为主键,其实id是没有任何意义的。它只是确保了数据的唯一性。
在实际复杂的表结构中,我们为了提高数据库的效率。一般不会选用id作为主键。
1.3 主键映射
+++ 简单主键映射
<!-- 主键 ,映射-->
<id name="empId" column="id">
<generator class="uuid"/>
</id>
+++ 复合主键映射
1.设置主键实体,实现Serializable接口。
2.设置实体。
3.配置映射
<!-- 复合主键 ,映射 -->
<composite-id name="keys">
<key-property name="name" column="e_name"></key-property>
<key-property name="cardId" column="e_card_id"></key-property>
</composite-id>
+++ 无主键映射
二、 主键映射 (一) --简单主键映射
<!-- 主键 ,映射-->
<id name="empId" column="id">
<generator class="uuid"/>
</id>
2.1 主键生成策略
主键的生成策略
identity 自增长(mysql,db2)。
返回的标识符是 long,short 或者 int 类型的。
sequence 自增长(序列)(oracle), oracle中自增长是以序列方法实现。
返回的标识符是 long,short 或者 int 类型的。
native 自动选择id生成策略【会根据底层数据库自增长的方式选择identity或sequence】
如果是mysql数据库, 采用的自增长方式是identity
如果是oracle数据库, 使用sequence序列的方式实现自增长
increment 自增长
会有并发访问的问题,一般在服务器集群环境使用会存在问题。
返回的标识符是 long,short 或者 int 类型的。
实现原理:
查询id的最大值,然后max(id)+1
assigned 指定主键生成策略为手动指定主键的值
uuid 指定uuid随机生成的唯一的值。string类型
foreign (外键的方式, one-to-one讲)
+++ 主键自增长,返回short、int、long类型数据。
适合于mysql数据库。
<id name="id" column="u_id" >
<generator class="identity"/>
</id>
+++ 主键自增长,返回short、int、long类型数据。
适合于oracle数据库。
<id name="id" column="u_id" >
<generator class="sequence"/>
</id>
+++ 主键自增长,返回short、int、long类型数据。
会根据底层数据库自动选择sequence和identity。
<id name="id" column="u_id" >
<generator class="native"/>
</id>
2.2 案例:简单主键映射
===> SQL
CREATE TABLE `emp` (
`u_id` int(11) NOT NULL AUTO_INCREMENT,
`e_name` varchar(255) DEFAULT NULL,
`e_card_id` varchar(255) DEFAULT NULL,
`e_birth` datetime DEFAULT NULL,
PRIMARY KEY (`u_id`)
)
===> EmpEntity.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="org.jsoft.demo" >
<class name="EmpEntity" table="emp">
<!-- 主键 ,映射 -->
<id name="id" column="u_id" >
<generator class="native"/>
</id>
<!-- 非主键,映射 -->
<property name="name" column="e_name"></property>
<property name="cardId" column="e_card_id"></property>
<property name="birth" column="e_birth"></property>
</class>
</hibernate-mapping>
===> src/hibernate.cfg.xml
<!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节点代表一个数据库 -->
<session-factory >
<!-- 1. 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/js</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!--
数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2. 其他相关配置 -->
<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql -->
<property name="hibernate.format_sql">false</property>
<!-- 2.3 自动建表 -->
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- 3. 加载所有映射 -->
<mapping resource="org/jsoft/demo/EmpEntity.hbm.xml"/>
</session-factory>
</hibernate-configuration>
===> EmpEntity.java
public class EmpEntity {
private int id;
private String name;
private String cardId;
private Date birth;
private String desc;
...
}
===> Demo.java
public class Demo {
public static SessionFactory sf;
static {
sf=new Configuration()
.configure()
.buildSessionFactory();
}
@Test
public void testAdd() {
Session session = sf.openSession();
Transaction tr = session.beginTransaction();
EmpEntity emp=new EmpEntity();
emp.setId(12);
emp.setName("111");
emp.setCardId("320321010000000");
emp.setBirth(new Date());
session.save(emp);
tr.commit();
}
}
三、主键映射 (二) – 复合主键映射
1.自定义主键类,实现Serializable接口。
2.自定义实体类。
3.配置映射文件。
4.使用
主键类实现Serializable接口的原因:
主键查询时,传入的主键要实现Serivliable接口。
session.get(EmpEntity.class,Serializable id)
===> CompositeKeys.java
public class CompositeKeys implements Serializable{
private String name;
private String cardId;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
}
===> EmpEntity.java
public class EmpEntity {
private CompositeKeys keys;
private Date birth;
private String desc;
public CompositeKeys getKeys() {
return keys;
}
public void setKeys(CompositeKeys keys) {
this.keys = keys;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
===> hibernate.cfg.xml
<!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节点代表一个数据库 -->
<session-factory >
<!-- 1. 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/js</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!--
数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2. 其他相关配置 -->
<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql -->
<property name="hibernate.format_sql">false</property>
<!-- 2.3 自动建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 3. 加载所有映射 -->
<mapping resource="org/jsoft/demo/EmpEntity.hbm.xml"/>
</session-factory>
</hibernate-configuration>
===> EmpEntity.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="org.jsoft.demo" >
<class name="EmpEntity" table="emp">
<!-- 复合主键 ,映射 -->
<composite-id name="keys">
<key-property name="name" column="e_name"></key-property>
<key-property name="cardId" column="e_card_id"></key-property>
</composite-id>
<!-- 主键 ,映射
<id name="id" column="u_id" >
<generator class="uuid2"/>
</id>
-->
<!-- 非主键,映射 -->
<property name="birth" column="e_birth"></property>
</class>
</hibernate-mapping>
===> App.java
public class Demo {
public static SessionFactory sf;
static {
sf=new Configuration()
.configure()
.buildSessionFactory();
}
@Test
public void testAdd() {
Session session = sf.openSession();
Transaction tr = session.beginTransaction();
CompositeKeys keys=new CompositeKeys();
keys.setName("111");
keys.setCardId("111");
EmpEntity emp=new EmpEntity();
emp.setKeys(keys);
emp.setBirth(new Date());
session.save(emp);
tr.commit();
}
@Test
public void testGet() {
Session session = sf.openSession();
Transaction tr = session.beginTransaction();
CompositeKeys keys=new CompositeKeys();
keys.setName("111");
keys.setCardId("111");
EmpEntity entity=(EmpEntity) session.get(EmpEntity.class, keys);
System.out.println(entity);
}
}
四、主键映射(三)-Hibernate映射无主键的数据库表
1.自定义实体类,实现Serializable接口。
2.配置映射文件。
3.使用
===> LogEntity.java
public class LogEntity implements Serializable{
private String name;
private String age;
private String content;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
===> LogEntity.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="org.jsoft.entity" >
<class name="LogEntity" table="log">
<composite-id >
<key-property name="name" column="name"></key-property>
<key-property name="age" column="age"></key-property>
<key-property name="content" column="content"></key-property>
</composite-id>
</class>
</hibernate-mapping>
===> bean.xml
<!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 >
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">false</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<mapping resource="org/jsoft/entity/LogEntity.hbm.xml"/>
</session-factory>
</hibernate-configuration>```