一,简介
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); } }