Hibernate 下载和配置
1 .在 Eclipse 的 Marketplace 上搜索下载 Hibernate Tools
Hibernate Tools 是由 JBoss推出的一个Eclipse综合开发工具插件,该插件可以简化ORM框架Hibernate,以及JBoss Seam,EJB3等的开发工作。
就是快速的帮我们生成一些配置文件,不用你自己敲。
Eclipse Version: Neon Release (4.6.0)
安装过程中的 Confirm Select Features 可以选择安装的东西,不要选择太多安装
我选了(网上有只选 Hibernate Tools的)
Hibernate Tools
JBoss JAX-RS Tools
JBoss Maven Project Examples
2 下载 jar 包
我在下载的地址
http://hibernate.org/orm/downloads/
我之前下载的是5.23版本的,后来测试的时候,发现版本兼容问题,我下载了 hibernate-release-4.3.11.Final 的版本
找到 lib/required 的下的 jar 包,复制到项目的 lib 目录下,build path。
4.3.11 jar包下载:http://download.csdn.net/detail/peng_hong_fu/9666103
Hibernate 介绍
1 ORM
对象关系映射(Object Relation Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
2 Hibernate
让程序员彻底抛弃书写 SQL 的思想,完全的使用面向对象思想开发软件。
Hibernate 就是一种可行的 ORM 框架技术。
Hibernate是Java领域的一款开源的ORM框架技术。
Hibernate对JDBC进行了非常轻量级的对象封装。
例如:
我的第一个Hibernate 实例
test 为 Source Folder
步骤:
- 创建 Hibernate 的配置文件
- 创建持久层
- 创建对象-关系映射文件
- 通过Hibernate API 编写访问数据库的代码
MySQL数据库的连接jar包
junit-4 的jar包( eclipse可以 Add Library 进行添加)
hibernate jar 包
1 hibernate的配置文件–hibernate.cfg.xml
hibernate.cfg.xml
<?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="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/hibernate?useUnicod=true&characterEncoding=utf8</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- hibernate属性的配置 -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<!-- 关联JavaBean -->
<mapping resource="Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
要创建和数据库配置信息相同的数据库,表名hibernate,要求支持中文,表什么的不用创建,hibernate会帮你创建。
<property name="hbm2ddl.auto">create</property>
为 create 时,会删除原来的数据,重新创建表
为 update 时,在原有的数据上更新
2 创建持久化对象
Student.java
import java.util.Date;
/**
* Title: Student
* Description:学生类
* @author Peng
* @date 下午6:58:51
*/
public class Student {
private int sid;// 学号
private String name;// 姓名
private String gender;// 性别
private Date birthday;// 出生日期
private String address;// 地址
public Student() {
}
public Student(int sid, String name, String gender, Date birthday, String address) {
super();
this.sid = sid;
this.name = name;
this.gender = gender;
this.birthday = birthday;
this.address = address;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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 "Student [sid=" + sid + ", name=" + name + ", gender=" + gender + ", birthday=" + birthday + ", address="
+ address + "]";
}
}
3 创建关系-对象映射文件
关联 自动创建的JavaBean Student
Student.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 2016-10-26 20:48:21 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="Student" table="STUDENT">
<id name="sid" type="int">
<column name="SID" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="gender" type="java.lang.String">
<column name="GENDER" />
</property>
<property name="birthday" type="java.util.Date">
<column name="BIRTHDAY" />
</property>
<property name="address" type="java.lang.String">
<column name="ADDRESS" />
</property>
</class>
</hibernate-mapping>
4 通过 Hibernate API 编写访问数据库的代码
使用到 Junit 进行测试
@Test:测试方法
@Before:初始化方法
@After : 释放资源
StudentTest.java
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Title: StudentTest
* Description: 测试类
* Company:
* @author Peng
* @date 下午7:07:42
*/
public class StudentTest {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init(){
//创建配置对象
Configuration cfg = new Configuration().configure();
//创建服务注册对象
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
//创建会话工厂对象
sessionFactory = cfg.buildSessionFactory(serviceRegistry);
//会话对象
session =sessionFactory.openSession();
//开启事务
transaction = session.beginTransaction();
}
@After
public void destory(){
transaction.commit();//提交事务
session.close();// 关闭对话
sessionFactory.close();// 关闭会话工厂
}
@Test
public void testSaveStudent(){
//生成学生对象
Student s = new Student(2,"张君宝","男",new Date(),"峨眉山");
session.save(s);//保存对象进数据库
}
}
在 testSaveStudent 方法上右击 Run as –> Junit test
执行测试,控制台输出:
Hibernate:
drop table if exists STUDENT
Hibernate:
create table STUDENT (
SID integer not null,
NAME varchar(255),
GENDER varchar(255),
BIRTHDAY datetime,
ADDRESS varchar(255),
primary key (SID)
)
Hibernate:
insert
into
STUDENT
(NAME, GENDER, BIRTHDAY, ADDRESS, SID)
values
(?, ?, ?, ?, ?)
从上面的控制台输出看出,在使用<property name="hbm2ddl.auto">create</property>
为create 时,每次都是先把表删除,再创建,然后执行 insert 语句。
Session 操作数据库的对象
session可以理解为操作数据库的对象,类似 JDBC 中的 Connection。在 hibernate 中,不建议使用 JDBC的Connection来操作数据库。
使用getCurrentSession要在hibernate.cfg.xml 里配置下面的语句
<property name="hibernate.current_session_context_class">thread</property>
测试session的两种获取方式,区别
SessionTest.java
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.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.junit.Test;
/**
* Title: SessionTest
* Description: 分别用两种方式创建Session对象
* @author Peng
* @date 下午9:06:12
*/
public class SessionTest {
@Test
public void testOpenSession(){
//创建配置对象
Configuration cfg = new Configuration().configure();
//创建服务注册对象
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
//创建会话工厂对象
SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry);
//获取 session 对象
Session session1 = sessionFactory.openSession();
Session session2 = sessionFactory.openSession();
System.out.println(session1==session2);//false
/*if(session!=null){
System.out.println("session创建成功!");
}else{
System.out.println("session创建失败!");
}*/
}
@Test
public void testGetCurrentSession(){
//创建配置对象
Configuration cfg = new Configuration().configure();
//创建服务注册对象
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
//创建会话工厂对象
SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry);
//获取 session 对象
Session session1 = sessionFactory.getCurrentSession();
//getCurrentSession需要在配置文档上配置
Session session2 = sessionFactory.getCurrentSession();
System.out.println(session1==session2);//true
/*if(session!=null){
System.out.println("getCurrentSession创建成功!");
}else{
System.out.println("getCurrentSession创建失败!");
}*/
}
@Test
public void testSaveStudentWidthOpenSession(){
//创建配置对象
Configuration cfg = new Configuration().configure();
//创建服务注册对象
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
//创建会话工厂对象
SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry);
//获取 session 对象
Session session1 = sessionFactory.openSession();
//开启事务
Transaction transaction = session1.beginTransaction();
//生成一个学生对象
Student s = new Student(1,"张君宝","男",new Date(),"峨眉山");
session1.doWork(new Work() {
@Override
public void execute(Connection conn) throws SQLException {
System.out.println("conn hsahcode"+conn.hashCode());
}
});
session1.save(s);
//session1.close();//一直都是打开不同的session会话,不释放,最终session资源会枯竭,连接池溢出
transaction.commit();//提交事务
Session session2 = sessionFactory.openSession();
transaction = session2.beginTransaction();
s = new Student(2,"谢逊","男",new Date(),"花果山");
session2.doWork(new Work() {
@Override
public void execute(Connection conn) throws SQLException {
System.out.println("conn hsahcode"+conn.hashCode());
}
});
session2.save(s);
transaction.commit();//提交事务
}
@Test
public void testSaveStudentWithGetCurrentSession(){
//创建配置对象
Configuration cfg = new Configuration().configure();
//创建服务注册对象
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
//创建会话工厂对象
SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry);
//获取 session 对象
Session session1 = sessionFactory.getCurrentSession();
//开启事务
Transaction transaction = session1.beginTransaction();
//生成一个学生对象
Student s = new Student(1,"张君宝","男",new Date(),"峨眉山");
session1.doWork(new Work() {
@Override
public void execute(Connection conn) throws SQLException {
System.out.println("conn hsahcode"+conn.hashCode());
}
});
session1.save(s);
//session1.close();
transaction.commit();//提交事务
Session session2 = sessionFactory.getCurrentSession();
//开启事务
transaction = session2.beginTransaction();
//生成一个学生对象
s = new Student(2,"张君宝2","男",new Date(),"峨眉2山");
session2.doWork(new Work() {
@Override
public void execute(Connection conn) throws SQLException {
System.out.println("conn hsahcode"+conn.hashCode());
}
});
session2.save(s);
//session2.close();
transaction.commit();//提交事务
}
}
testSaveStudentWidthOpenSession
方法测试结果:
conn hsahcode1802066694
Hibernate:
insert
into
hibernate.STUDENT
(NAME, GENDER, BIRTHDAY, ADDRESS, SID)
values
(?, ?, ?, ?, ?)
conn hsahcode2074658615
Hibernate:
insert
into
hibernate.STUDENT
(NAME, GENDER, BIRTHDAY, ADDRESS, SID)
values
(?, ?, ?, ?, ?)
测试的hashcode不相同的!!!,说明不手动关闭Session的话,会创建行的session,多次创建,会引发连接池的溢出。
testSaveStudentWithGetCurrentSession
方法测试结果:
conn hsahcode223693919
Hibernate:
insert
into
hibernate.STUDENT
(NAME, GENDER, BIRTHDAY, ADDRESS, SID)
values
(?, ?, ?, ?, ?)
conn hsahcode223693919
Hibernate:
insert
into
hibernate.STUDENT
(NAME, GENDER, BIRTHDAY, ADDRESS, SID)
values
(?, ?, ?, ?, ?)
说明,getCurrentSession是使用现有的session对象。(单例模式)
Transcation 事务
hibernate默认不自动提交事务
这里修改方法,让其自动提交。把 @After 下的事务提交注释。
StuddentTest.java
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.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Title: StudentTest
* Description: 测试类,测试事务的提交方式
* Company:
* @author Peng
* @date 下午7:07:42
*/
public class StudentTest {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init(){
//创建配置对象
Configuration cfg = new Configuration().configure();
//创建服务注册对象
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
//创建会话工厂对象
sessionFactory = cfg.buildSessionFactory(serviceRegistry);
//会话对象
session =sessionFactory.openSession();
//开启事务
transaction = session.beginTransaction();
//不开启事务就不能把对象保存到数据库中! hibernate默认不自动提交事务
}
@After
public void destory(){
//transaction.commit();//提交事务//对应更改的地方--2
session.close();// 关闭对话
sessionFactory.close();// 关闭会话工厂
}
@Test
public void testSaveStudent(){
//生成学生对象
Student s = new Student(1,"张君宝","男",new Date(),"峨眉山");
session.doWork(new Work() {//对应更改的地方--2
@Override
public void execute(Connection conn) throws SQLException {
conn.setAutoCommit(true);
}
});
session.save(s);//保存对象进数据库
session.flush();//对应更改的地方--2
}
}
能运行成功,说明,设置自动提交成功。
hibernate基本类型
<property name="birthday" type="java.util.Date">
<column name="BIRTHDAY" />
</property>
type="java.util.Date"
type="date"
type="time"
修改为不同的类型,保存的时间格式不同
hibernate对象类型
blob是二进制类型,如视频、图片等
Student JavaBean类中保存的都是基本类型,现在保存对象类型—图片。
public class Student {
private int sid;// 学号
private String name;// 姓名
private String gender;// 性别
private Date birthday;// 出生日期
private String address;// 地址
private Blob picture;//照片
.
.
更改关系映射文件,删除重新创建。
Student.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 2016-10-27 12:04:02 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="Student" table="STUDENT">
<id name="sid" type="int">
<column name="SID" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="gender" type="java.lang.String">
<column name="GENDER" />
</property>
<property name="birthday" type="java.util.Date">
<column name="BIRTHDAY" />
</property>
<property name="address" type="java.lang.String">
<column name="ADDRESS" />
</property>
<property name="picture" type="java.sql.Blob">
<column name="PICTURE" />
</property>
</class>
</hibernate-mapping>
增加了这个
..
<property name="picture" type="java.sql.Blob">
<column name="PICTURE" />
</property>
测试图片的保存和读取。
把数据表的创建方式改为update,而不是 create
<property name="hbm2ddl.auto">update</property>
用到的图片在D盘的第一级目录下
StudentTest.java
.
.
@Test
public void testWriteBlob() throws Exception{
Student s = new Student(1,"张君宝","男",new Date());
//获得照片
File f =new File("d:"+File.separator+"01.jpg");
//获取照片文件的输入流
InputStream in = new FileInputStream(f);
//创建一个Blob 对象
Blob image = Hibernate.getLobCreator(session)
.createBlob(in,in.available());
//设置照片属性
s.setPicture(image);
//保存学生
session.save(s);
}
@Test
public void testReadBlob() throws Exception{
Student s = (Student) session.get(Student.class, 1);
//获取Blob 对象
Blob image = s.getPicture();
// 获取照片的输入流
InputStream input = image.getBinaryStream();
//创建输出流
File f = new File("d:"+File.separator+"dest.jpg");
//File f = new File("d:/dest2.jpg");
//获得输出流
OutputStream out = new FileOutputStream(f);
//创建缓存区
byte[] buffer = new byte[input.available()];
input.read(buffer);
out.write(buffer);
input.close();
out.close();
}
..
File.separator是分割符,在不同的系统中分隔符不同,
在windows中的文件分隔符是 \ 和 /都可以
但是在Linux中,文件分隔符只能是/
所以用了\的程序在Linux下会出问题。
而File.separator是系统默认的文件分割符号,屏蔽了这些系统的区别。
用File.separator保证了在任何系统下不会出错。
图片的存储类型为 longlob 类型。
hibernate组件类型
实体类中的某个属性属于用户自定义的类的对象
Address.java
//地址类
public class Address {
private String postcode;//邮编
private String phone;//电话
private String address;//地址
public Address() {
}
public Address(String postcode, String phone, String address) {
super();
this.postcode = postcode;
this.phone = phone;
this.address = address;
}
//省略getter 和 setter
@Override
public String toString() {
return "Address [postcode=" + postcode + ", phone=" + phone + ", address=" + address + "]";
}
}
Student.java
public class Student {
private int sid;// 学号
private String name;// 姓名
private String gender;// 性别
private Date birthday;// 出生日期
private Blob picture;//照片
private Address address;//对象类型的数据
public Student() {
}
.
.
修改Student.hbm.xml
,这次直接加就是,下面的语句
<component name="address" class="Address">
<property name="postcode" column="POSTCODE"></property>
<property name="phone" column="PHONE"></property>
<property name="address" column="ADDRESS"></property>
</component>
</class>
</hibernate-mapping>
StudentTest.java
.
.
@Test
public void testSaveStudent(){
//生成学生对象
//Student s = new Student(2,"张君宝","男",new Date(),"峨眉山");
Student s =new Student();
s.setSid(100);
s.setName("张三丰");
s.setGender("男");
Address address = new Address("710068","1215121","西安市");
s.setAddress(address);
s.setBirthday(new Date());
session.save(s);//保存对象进数据库
}
@Test
public void testGetStudent(){
Student s = (Student) session.get(Student.class, 100);
System.out.println(s.toString());
}
.
.
Hibernate的增删改查
StudentTest.java
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Title: StudentTest
* Description: 测试类
* Company:
* @author Peng
* @date 下午7:07:42
*/
public class StudentTest {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init(){
//创建配置对象
Configuration cfg = new Configuration().configure();
//创建服务注册对象
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
//创建会话工厂对象
sessionFactory = cfg.buildSessionFactory(serviceRegistry);
//会话对象
session =sessionFactory.openSession();
//开启事务
transaction = session.beginTransaction();
}
@After
public void destory(){
transaction.commit();//提交事务
session.close();// 关闭对话
sessionFactory.close();// 关闭会话工厂
}
@Test
public void testSaveStudent(){
//生成学生对象
//Student s = new Student(2,"张君宝","男",new Date(),"峨眉山");
Student s =new Student();
s.setSid(100);
s.setName("张三丰");
s.setGender("男");
Address address = new Address("710068","1215121","西安市");
s.setAddress(address);
s.setBirthday(new Date());
session.save(s);//保存对象进数据库
}
@Test
public void testGetStudent(){
Student s = (Student) session.get(Student.class, 100);
//100->>1,没有1的id null
//System.out.println(s.getClass().getName());//Student
System.out.println(s.toString());
}
@Test
public void testLoadStudent(){
//load只有你用的时候才会发生SQL语句,注释掉syso,就不会执行
Student s = (Student) session.load(Student.class, 100);
//100->>1,没有1的id 异常ObjectNotFound
System.out.println(s.getClass().getName());//Student_$$_jvst8e2_0 代理对象
//System.out.println(s.toString());
}
@Test
public void testUpdateStudent(){
Student s = (Student) session.load(Student.class, 100);
s.setGender("女");
session.update(s);
}
@Test
public void testDeleteStudent(){
Student s = (Student) session.load(Student.class, 100);
session.delete(s);
}
}
总结
对象关系映射(Object Relation Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
Hibernate多对一,一对多
http://www.cnblogs.com/zilong882008/archive/2011/11/05/2236559.html