转自
Hibernate就是对数据库进行封装,使得程序员可以直接操作对象而不用写具体的数据库操作。
ORM(Object Relation Mapping,对象关系映射)的作用是在关系型数据库和对象之间做了一个映射。从对象(Object)映射到关系(Relation),再从关系映射到对象。这样,我们在操作数据库的时候,不需要再去和复杂SQL打交道,只要像操作对象一样操作它就可以了(把关系数据库的字段在内存中映射成对象的属性)。
Hibernate是一个开放源代码的ORM框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的ORM框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
Hibernate的核心:
从上图中,我们可以看出Hibernate六大核心接口,两个主要配置文件,以及他们直接的关系。Hibernate的所有内容都在这了。那我们从上到下简单的认识一下,每个接口进行一句话总结。
1、Configuration接口:负责配置并启动Hibernate
2、SessionFactory接口:负责初始化Hibernate
3、Session接口:负责持久化对象的CRUD操作
4、Transaction接口:负责事务
5、Query接口和Criteria接口:负责执行各种数据库查询
注意:Configuration实例是一个启动期间的对象,一旦SessionFactory创建完成它就被丢弃了。
《》
首先建一个hibernate.cfg.xml文件
com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=UTF-8 jdbc:mysql:///hibernate?useUnicode=true&characterEncoding=UTF-8 root 123456 org.hibernate.dialect.MySQLDialect true true create
写一个学生类
实体类和数据库中的表相对应
import java.util.Date;public class Students { private int sid; private String sname; private String gender; private Date birthday; private String address; public Students() { } public Students(int sid, String sname, String gender, Date birthday, String address) { super(); this.sid = sid; this.sname = sname; this.gender = gender; this.birthday = birthday; this.address = address; } public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Students [sid=" + sid + ", sname=" + sname + ", gender=" + gender + ", birthday=" + birthday + ", address=" + address + "]"; } }
创建对象-关系映射配置文件,后缀是.hbm.xml
使用 junit 测试:
@Test 测试注释标签 测试方法
@Before 初始化方法 执行测试方法之前会执行这个方法
@After 释放资源 执行测试方法之后会执行这个方法
import java.sql.Connection;import java.sql.SQLException;import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.jdbc.Work;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;public class StudentsTest { private SessionFactory sessionFactory; private Session session; private Transaction transaction; @Before public void init() { // 创建配置对象 Configuration config = new Configuration().configure(); // 创建服务注册对象 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); // 创建会话工厂对象 sessionFactory = config.buildSessionFactory(serviceRegistry); // 创建会话对象 session = sessionFactory.openSession(); // session = sessionFactory.getCurrentSession(); // 开启事务 transaction = session.beginTransaction(); } @After public void destroy() { transaction.commit(); // 提交事务 session.close(); // 关闭会话 sessionFactory.close(); // 关闭会话工厂 } @Test public void testSaveStudents() { Students s = new Students(1, "段文弱", "男", new Date(), "天朝"); session.save(s); }}
Hibernate执行流程
session是一个操纵数据库对象,session与connection是多对一的关系。
session默认事务不是自动提交。需要Transaction提交。transaction.commit();
可以通过设置doWork()变成自动提交(不推荐)
session.doWork(new Work(){ @Override public void execute(Connection connection) throws SQLException { connection.setAutoCommit(true); }});
获得session:
1.openSession 每次都获得一个新的session,需要手动关闭
2.getCurrentSession 使用现有的session对象,需要在hibernate.cfg.xml中配置
<property name="hibernate.current_session_context_class">thread</property>
在事务提交或者回滚之后会自动关闭,(所以啊……不需要关闭……会有错误!错了好多次才反应过来!
基本数据类型:
时间类型:
对象类型
1.clob和text对应大文本文件,blob对应大的二进制文件,例如视频音频图片
2.java中的clob对应存储大文本文件,java中的blob对应存储大二进制文件
MySQL不支持标准SQL的CLOB类型,在Mysql中,用TEXT,MEDIUMTEXT及LONGTEXT类型来表示长度超过255的长文本数据
@Testpublic void testWriteBlob() throws IOException { Students s = new Students(100, "段文弱", "男", new Date(), "天朝"); File file = new File("E:"+File.separator+"图片"+File.separator+"bobo.jpg"); // 获得照片文件的输入流 InputStream input = new FileInputStream(file); // 创建一个Blob对象 Blob image = Hibernate.getLobCreator(session).createBlob(input, input.available()); // 设置照片属性 s.setPicture(image); session.save(s);}@Testpublic void testReadBlob() throws Exception { Students s = (Students)session.get(Students.class, 1); Blob image = s.getPicture(); InputStream input = image.getBinaryStream(); File file = new File("E:"+File.separator+"bobo.jpg"); OutputStream output = new FileOutputStream(file); // 创建缓冲区 byte[] buffer = new byte[input.available()]; //System.out.println(input.available()); input.read(buffer); output.write(buffer); input.close(); output.close();}
组件属性:某个属性是用户自定义的对象
会在数据库中将自定义类中的属性也当做一个字段。
增删改查:
Students s = new Students();//增加数据session.save(s);// 获取 Object get/load(Class, 主键)Students s = (Students)session.get(Students.class, 1);Students s = (Students)session.load(Students.class, 1);// 修改session.update(s);// 删除session.delete(s);
get load区别:
1.get调用后立即发出sql语句,并返回对象。load调用后返回代理对象,保存了实体对象id,直到使用了对象的非主键属性时才发出sql语句
2.当查询到数据为空时,get返回null,load返回objectNotFound异常