主键:
主键的规则:不能重复不能修改
主键的分类:
自然主键 表里面有一个字段 符合主键的规则 就直接用这个字段 作为主键 身份证
代理主键 表里没有一个字段 符合主键的规则 自己创建一个id 作为表的主键 这个键叫做代理主键
主键生成策略
1. identity
主键自增 使用数据库中的主键自增
插入时 打印sql时 不会插入id
2. increment
主键自增 由hibernate来管理
插入数据时 会先去数据库中查询当前最大id
然后把查出来的id+1 再插入数据
3. uuid
全球不重复的唯一标识(32位 字符串)
注意:id必须使用字符串类型
4. native(最常用的 三合一)
根据你使用数据库类型来选择使用
下面三个策略之一
所有数据库不是支持identity 就是支持序列
identity + sequence + hilo
5. hilo(高低位算法)
将主键交给hibernate处理 使用自己的算法 帮你维护主键
6. assigned
由你自己维护主键 插入数据时需要有主键
使用的代理主键
7. sequence oracle数据库默认的
<?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 package="com.lanou3g">
<!-- 配置表与实体类的关系
name:实体类全类名
table:表名
package:填包名 填上后 底下再写全类名
可以省略包名
-->
<class name="User" table="user">
<!--
id:表示主键
注意:没有主键 不能使用hibernate
name:表示类中的成员变量名
column:表示这个成员变量所代表的 表中的字段名
-->
<id name="id" column="id">
<!-- 主键的生成策略 主键自增策略 -->
<generator class="native"></generator>
</id>
<!--
property:表示除了主键以外的属性
-->
<property name="username" column="username"></property>
<property name="password" column="password"></property>
</class>
</hibernate-mapping>
主配置文件 文件名: 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>
<!-- hibernate数据库配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate01</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- 加载mysql的方言包 limit -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<!-- 开启打印sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 开启格式化sql语句 -->
<property name="hibernate.format_sql">true</property>
<!-- 自动更新表结构 没有表会帮你创建出来表-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--
设置数据库隔离级别
(etc/hibernate.properties文件)
默认的隔离级别(1|2|4|8)
#hibernate.connection.isolation 4
1.赃读
2.不可重复读
3.幻读(虚读)
隔离级别
READ UNCOMMITED 读未提交 1 2 3 1
READ COMMITED 读已提交 2 3 2
REPEATABLE READ 可重复读 3 4
Serializable 串行化 都能避免 8
隔离级别使用1个字节来存储的
0001
0010
0100
1000
-->
<property name="hibernate.connection.isolation">4</property>
<!-- 映射数据库表对应的 映射文件的路径
注意:路径从包名开始 并且中间使用反斜杠相隔
-->
<mapping resource="com/lanou3g/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Hibernate的三种形态
1.瞬时态
没有ID 没有跟session产生关系
2.持久态
有ID 跟session产生了关系
3.游离态
有ID 没有跟session产生关系
hibernate在操作数据库时 就是将持久态的对象同步到数据库
@Test
public void fun1() {
//保存一个用户
Session session = HibernateUitl.getOpenSession();
Transaction transaction = session.beginTransaction();
User user = new User();//瞬时态
user.setUsername("taylor");
session.save(user);//持久态
transaction.commit();
session.close();//游离态
}
hibernate会在你提交事务之后 把持久态的对象同步到数据库
@Test
public void fun2() {
Session session = HibernateUitl.getOpenSession();
Transaction transaction = session.beginTransaction();
//使用get方法查询一个对象
User user = session.get(User.class, 1);
user.setUsername("swift");
transaction.commit();
session.close();
}
存储时 有两种:
缓存(读写速度快 效率高)
硬盘(读写文件 速度慢)
当你调用get方法去数据库查询时 数据库给你返回的结果集 会被hibernate封装成对象
并且会在缓存中保存一份
当你再次用get方法查询时 hibernate会先到缓存中去查找 有没有该id的对象
有就直接返回缓存中的对象
没有就使用sql语句去操作数据库查询
@Test
public void fun3() {
Session session = HibernateUitl.getOpenSession();
Transaction transaction = session.beginTransaction();
User user1 = session.get(User.class, 1);
User user2 = session.get(User.class, 1);
User user3 = session.get(User.class, 1);
User user4 = session.get(User.class, 1);
User user5 = session.get(User.class, 1);
System.out.println(user2 == user5);
transaction.commit();
session.close();
}
测试时只打印一次sql查询语句
快照:
用get方法查询时
hibernate会把结果集保存到缓存中一份 也会在快照中保存一份
当你最终提交事务操作数据库的时候hibernate会对比缓存与快照中的数据
一样就不存了 反之会同步到数据库
@Test
public void fun4() {
Session session = HibernateUitl.getOpenSession();
Transaction transaction = session.beginTransaction();
User user = session.get(User.class, 1);
user.setUsername("taylorSwift");
user.setUsername("mayDay");
session.update(user);
transaction.commit();
session.close();
}