一,简介
hibernate是一个开源的ORM框架,它对我们的jdbc进行了轻量级的对象封装,它将我们的POJO与数据库表简历映射关系,是一个全自动的ORM框架;hibernate可以自动生成SQL语句,自动执行,是的开发人员可以向使用面向对象编程思维来操作数据库
hibernate专门用来操作数据库的框架
二,ORM框架
对象关系映射(Object Relational Mapping),把对象模型表示的对象映射到基于SQL的关系型数据库结构中,在操作具体的实体对象时,就可以和数据库交互,
ORM是对象和数据库表的中间桥梁,对象和表就可以相互关联了;
hibernate只是ORM框架技术的中一种实现
三,持久化
是将程序数据在持久状态和瞬时状态切换的机制,通常就是将内存中的对象数据持久化到数据库中进行永久的保存;
Student stu=new Student() //内存,运行快,断电后数据会被清空
四、hibernate工作流程
configuration:配置对象,加载hibernate.cfg.xml总配置文件,xxx.bbm.xml实体类和数据库表的映射配置;
sessionFactory:会话工厂,创建会话对象,一个数据库只能有一个会话工厂
session:会话对象,当做jdbc中的connection,执行增删改查操作
transaction:事务对象,提交和回滚事务
五、eclipse安装Jboss工具
http://tools.jboss.org/downloads/jbosstools/neon/4.4.4.Final.html
eclipse – help – install new software
选择子选项中:hibernate tools
六、hibernate入门
1、新建数据库
2、创建userInfo表
create table userInfo(
id int not null primary key auto_increment,
no char(4) not null unique,
name varchar(20) not null,
pwd varchar(20) not null,
sex int not null,
age int not null
)
insert into userInfo values(0,'U001','小明','123456',1,20);
insert into userInfo values(0,'U002','小红','123456',0,18);
insert into userInfo values(0,'U003','小方','123456',1,21);
select * from userInfo;
3、导入jar
https://hibernate.org/orm/releases/
5.2.17.Final
4、生成hibernate.cfg.xml
上图配置中,不要配置session factory name的数据;
<?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>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate-test?charsetEncoding=utf-8</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
</session-factory>
</hibernate-configuration>
5、UserInfo实体类
@Setter
@Getter
public class UserInfo {
private int id;
private String no;
private String name;
private String pwd;
private int sex;
private int age; }
6、UserInfo.hbm.xml
你的实体类名.hbm.xml
选择po包,右键 – new - hibernamte – hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2019-4-25 16:42:25 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<!-- name:类全名 table:数据库中的表名 -->
<class name="com.yujun.maven.po.UserInfo" table="USERINFO">
<!-- id:主键列 name:实体类中属性名 type:实体类中属性的类型 -->
<id name="id" type="int">
<!--column:数据库表的列 name:列名 -->
<column name="ID" />
<!-- generator:主键生成策略 identity表示自增-->
<generator class="identity" />
</id>
<!-- property:普通属性 name:实体类的属性名 type:实体类的属性的类型 -->
<property name="no" type="java.lang.String">
<!--column:数据库表的列 name:列名 -->
<column name="NO" />
</property>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="pwd" type="java.lang.String">
<column name="PWD" />
</property>
<property name="sex" type="int">
<column name="SEX" />
</property>
<property name="age" type="int">
<column name="AGE" />
</property>
</class>
</hibernate-mapping>
7、xxx.hbm.xml添加到hibernate.cfg.xml
在hibernate.cfg.xml的session-Factory节点中添加下面配置
<!-- 添加映射文件 -->
<mapping resource="com/yujun/maven/po/UserInfo.hbm.xml"/>
注意的是,包名之间的“/”不要改成“.”
8、添加案例
public class Demo1 { public static void main(String[] args) { //1 配置对象
Configuration config = new Configuration().configure(); //内部加载hibernate.cfg.xml
//2工厂对象
SessionFactory factory = config.buildSessionFactory();
//3会话对象
Session session = factory.openSession();
//4事务对象
Transaction tran = session.beginTransaction(); //添加
//创建对象,并给对象属性赋值
UserInfo user = new UserInfo();
user.setAge(22);
user.setName("小黑3");
user.setNo("U006");
user.setPwd("123456");
user.setSex(1); //保存
session.save(user); //提交事务
tran.commit();
//关闭会话
session.close();
System.out.println("over....");
} }
七、maven-hibernate入门
https://search.maven.org/artifact/org.hibernate/hibernate-core/5.2.17.Final/jar
1、添加hibernate核心依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.17.Final</version>
</dependency>
如果想要在控制台输出原生的SQL语句,需要再hibernate.cfg.xml中配置
<!-- 是否显示SQL语句 true-显示 -->
<property name="hibernate.show_sql">true</property>
2、添加
public class Demo1 { public static void main(String[] args) {
// 1配置对象
Configuration config = new Configuration().configure();
// 2会话工厂
SessionFactory factory = config.buildSessionFactory();
// 3会话对象
Session session = factory.openSession();
// 4事务对象
Transaction tran = session.beginTransaction(); // 添加
// 创建对象,并给对象属性赋值
UserInfo user = new UserInfo();
user.setAge(22);
user.setName("小黑5");
user.setNo("U008");
user.setPwd("123456");
user.setSex(1); // 保存
session.save(user); // 提交事务
tran.commit();
// 关闭会话
session.close();
System.out.println("over....");
System.exit(0);
} }
3、修改
public class Demo2 { public static void main(String[] args) {
//1配置对象
Configuration config = new Configuration().configure();
//2会话工厂
SessionFactory factory = config.buildSessionFactory();
//3会话对象
Session session = factory.openSession(); //修改、删除之前都应该先查询出相应的对象,然后再操作
//修改
//根据id查询一个实体对象
UserInfo info = session.get(UserInfo.class, 100);
if(info != null){
//4事务
Transaction tran = session.beginTransaction();
System.out.println(info);
info.setName("小黑1"); session.update(info); //提交
tran.commit();
}else{
System.out.println("当前数据不存在");
} //关闭
session.close();
System.out.println("over.....");
System.exit(0); } }
修改时,我们只需要给对象的属性重新赋值即可,不要修改的字段我们保持不变,最终就能达到修改的效果;
4、删除
public class Demo3 { public static void main(String[] args) {
// 1配置对象
Configuration config = new Configuration().configure();
// 2会话工厂
SessionFactory factory = config.buildSessionFactory();
// 3会话对象
Session session = factory.openSession(); //删除
UserInfo info = session.get(UserInfo.class, 6);
if(info != null){
// 4事务
Transaction tran = session.beginTransaction();
session.delete(info);
tran.commit();
}else{
System.out.println("数据不存在...");
} session.close();
System.out.println("over.....");
System.exit(0);
} }
5、查询
//hql查询,hql中的UserInfo是实体类名,不是数据库中的表名;id是实体类中的属性名
Query<UserInfo> query = session.createQuery("from UserInfo where id<=?", UserInfo.class);
//给?赋值,下标从0开始
query.setParameter(0, 5);
List<UserInfo> list = query.list(); //获取query对象中集合数据
list.forEach(System.out::println);
八、hibernate实例状态
hibernate将java对象分为4中状态:
(1) 临时/瞬时状态(transient)
(2) 持久化状态(persistent)
(3) 删除状态(delete)
(4) 游离状态(detached)
1、瞬时状态
没有OID,没有在session缓存,数据库中也没有与之对应的记录 – 公司未入职的员工
Student s = new Student();
比如上述的s学生对象就是一个瞬时对象
2、持久化状态
有OID,有session缓存,数据库中有与之对应的记录 -- 公司的在职员工
3、删除状态
有OID,没有session缓存,数据库中没有与之对应的记录 -- 公司的离职员工
4、游离状态
有OID,没有session缓存,数据库中有与之对应的记录 -- 公司的请假员工
5、与四种状态对应的方法
5.1 save(重点)
就是将新创建的对象,添加到数据库中;
将瞬时状态的对象,变成持久化状态
5.2 persist
基本和save方法差不多,唯一区别就是此方法持久化的对象不能有OID
5.3 update(重点)
更新数据,将一个游离状态对象转为持久化对象
5.4 saveOrUpdate
同时包含之前介绍的save和update方法的功能,当对象是瞬时,那么执行save;当对象是游离时,那么执行update
5.5 delete(重点)
删除
5.6 evict
删除session缓存中对象,变成游离状态
5.7 merge
合并对象到数据库
5.8 get和load(重点)
面试题:hibernate中get和load方法的区别?
相同:
两者都是根据ID查询出相应的对象数据;
不同:
(1)若数据库中有和传入的ID相匹配的数据时,get方法立即加载并发送sql语句从数据库获取数据;而load采用延迟加载的方式来获取数据,即只有当需要使用对象的属性或方法时才会发送SQL语句去数据库中查询数据;
(2)若数据库中没有和传入的ID相匹配的数据时,get方法返回null,load方法会抛异常(调用load方法时没有问题的,而是在调用返回代理对象的属性或方法时抛异常);
(3)若在使用返回对象的属性前将session关闭,那么load方法会抛异常(LazyInitialedExceptioin懒加载异常),因为load方法返回的是一个代理对象,当hibernate向代理对象中填充属性时,由于session被关闭,那么无法加载数据从而抛出懒加载异常;
九、新版本写法
public class Demo7 {
public static void main(String[] args) {
//注册对象
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
//会话工厂
SessionFactory factory = new MetadataSources(registry).buildMetadata().buildSessionFactory(); Session session = factory.openSession();
UserInfo info = session.get(UserInfo.class, 2);
System.out.println(info);
session.close();
System.exit(0);
}
}