实体类规范(javaBean规范)
1.提供无参构造方法
2.成员变量私有化提供get/set方法
double 表示学分 0-100.0 没考试 0
Double 有null值 缺考 用空值表示0分
3.基本数据类型尽量使用包装类型(可以多表示一个值null例如考试分数 缺考和0分)
4.实体中必须要提供一个与表中的主键相对应的属性id
hibernate是通过主键来区别对象是否相同
5.不要使用final修饰实体类(代理对象是要继承该类的)
主键的类型
1.自然主键
输入人的时候 人的身份证号 保证了 非空不重复 复合主键的贴点
但是身份证号 本身是业务字段 可以作为主键使用 叫做自然主键
2.代理主键(常用)
当找不到主键的时候(没有业务字段符合主键的规则)
搞一个没有任何意义的主键id列 作为主键 就是为了非空不重复 叫做代理主键
主键生成策略(7种)
identity:主键自增 有数据库来维护主键 录入的时候不需要指定主键
increment:主键自增 由hibernate来维护主键 每次插入前会先查询表中 id
最大值 +1 作为新主键
效率不高每次都要查询 如何10个人同时要保存 可能会出现线程问题
sequence:Oracle中的主键生策略 序列
hilo:高低位算法(数据库中的主键自增算法原理)由hiernate来维护主键hibernate自己算一下(无意义)
native:hilo +sequence + identity 自动三选一 检测你是什么数据库
mysql就identity Oracle就sequence 如果没有就 用hilo 但是世界上没有一个 不支持自增和序列的数据库 其实就是2 选1
uuid:产生一个随机的字符串作为主键 主键类型必须为string类型
assigned:自然主键生成策略(没策略)hibernate不会管理 由开发人自己录入
三种状态
1.瞬时态 没有id 没有和session关联(这里的关联是指和缓存关联)
2.持久态 有id 有关联(这里的关联是指和缓存关联)
3.游离态 有id 没有关联(这里的关联是指和缓存关联)
测试:save get 多次 打印的语句
结论:就是将我们想要同步数据库的数据 所对应的对象转换成持久态
/* hibernate中对象的三种状态
*
*/
@Test
public void fun(){
//获取session
Session session = HibernateUtils.getSession();
//开启事物
Transaction transaction = session.beginTransaction();
//包裹语句
//*******************************
User user = new User(); //瞬时态 没有id 没有和session关联
user.setUsername("wl");
user.setPassword("123456");
session.save(user); //持久态 有id 有和session关联
// update delete get 这三个方法是从 什么态 转 成什么态
//*********************************
//提交事务
transaction.commit();
//关闭资源
session.close(); //游离态 有id 没有和session关联
}
一级缓存与快照(系统实现的 将以下的实现的原理)
1一级缓存测试 get多次 打印的语句
@Test
public void fun2(){
//获取session
Session session = HibernateUtils.getSession();
//开启事物
Transaction transaction = session.beginTransaction();
//包裹语句
//*******************************
//测试一下hibernate 中的缓存
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);
//1.生成几条sql语句
//2.下面打印的结果
//思考:为什么?
//hibernate 的缓存机制
//第一次 再一次
System.out.println(user2==user5);
//*********************************
//提交事务
transaction.commit();
//关闭资源
session.close(); //游离态 有id 没有和session关联
}
@Test
//快照测试
public void fun4(){
//获取session
Session session = HibernateUtils.getSession();
//开启事物
Transaction transaction = session.beginTransaction();
//包裹语句
//*********************************
User user = session.get(User.class, 1);
user.setUsername("pp");
user.setUsername("dpp");
session.update(user);
//*********************************
//提交事务
transaction.commit();
//关闭资源
session.close(); //游离态 有id 没有和session关联
}
3.测试
瞬时态 -> 游离态->持久态
new对象 -> 设置id -> update -> get
事物
Transaction transaction = session.beginTransaction();
//包裹语句
//*********************************
User user = new User();//瞬时态 没有id 和session中的缓存 没有关联
user.setId(1); // 游离态 有id 和session中的缓存 没有关联
//从数据库返回结果集 是保存进缓存和快照中
//update 时 把这个要更新的对象 放入缓存中(跟快照没关系)
session.update(user); //持久态 有id 和session中的缓存 有关联
//get查询时 去缓存中 查找 看有没有该id的对象
User u = session.get(User.class, 1);
//问:打印几条语句 为什么
//*********************************
//当事物提交的时候
//hibernate 会 对比 快照 和缓存中的对象是否相同
//不相同 会把缓存中的对象 同步到数据库
//提交事务
transaction.commit();
//关闭资源
session.close(); //游离态 有id 没有和session关联
}
指定事物的隔离级别
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driverproperty>
<property name="hibernate.connection.username">rootproperty>
<property name="hibernate.connection.password">123456property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/a_hibernate_01property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialectproperty>
<property name="hibernate.show_sql">trueproperty>
<property name="hibernate.format_sql">trueproperty>
<property name="hibernate.hbm2ddl.auto">updateproperty>
<property name="hibernate.connection.isolation">4property>
<property name="hibernate.current_session_context_class">threadproperty>
1.脏读
2.可重复读
3.幻读
READ UNCOMMITTED 读未提交 1 2 3
READ COMMITTED 读已提交 2 3
REPEATABLE READ 可重复读 3
SERIALIZABLE 串行化(只能一个一个的访问:效率非常的低)
-->
<mapping resource="com/lanou3g/User.hbm.xml"/>
session-factory>
hibernate-configuration>
设置可以获取当前session 与当前线程绑定的
1.thread
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driverproperty>
<property name="hibernate.connection.username">rootproperty>
<property name="hibernate.connection.password">123456property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/a_hibernate_01property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialectproperty>
<property name="hibernate.show_sql">trueproperty>
<property name="hibernate.format_sql">trueproperty>
<property name="hibernate.hbm2ddl.auto">updateproperty>
<property name="hibernate.connection.isolation">4property>
<property name="hibernate.current_session_context_class">threadproperty>
<mapping resource="com/lanou3g/User.hbm.xml"/>
session-factory>
hibernate-configuration>
注意:
1.配置配置文件
2.调用getCurrentSession获取session 当事务提交 session会自动关闭 不需要手动关闭
创建实体类
public class User {
private int id;
private String username;
private String password;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(int id, String username, String password) {
super();
this.id = id;
this.username = username;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
}
}
简单的分装一个获取session的方法
/*
* 简单封装
*/
public class HibernateUtils {
// 把sessionFactory写成成员变量
private static SessionFactory sessionFactory;
static {
// 加载配置文件
Configuration configuration = new Configuration().configure();
// 创建session工厂
sessionFactory = configuration.buildSessionFactory();
}
// 返回session的方法
public static Session getSession() {
return sessionFactory.openSession();
}
// 返回当前session的方法
public static Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
获取session
public class UserDao {
public void saveUser(User user) {
//获取当前的session
Session session = HibernateUtils.getCurrentSession();
session.save(user);
}
}
获取当前的session
public class UserService {
private UserDao dao = new UserDao();
public void addUser(User user) {
//获取当前的session
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//调用dao层方法失败了怎么办?
try {
dao.saveUser(user);
} catch (Exception e) {
//可以使用异常来处理. 失败之后会报个异常.
e.printStackTrace();
//直接回滚事物 rollback
transaction.rollback();
}
transaction.commit();
}
}