ORM(Object/Relationship Mapping):对象/关系映射
利用面向对象思想编写的数据库应用程序最终都是把对象信息保存在关系型数据库中,于是要编写很多和底层数据库相关的SQL语句,如要写insert into 语句写SQL语句有什么不好?
1.不同的数据库使用的SQL语法不同。比如:PL/SQL(ORACAL)与T/SQL(微软)2.同样的功能在不同的数据库中有不同的实现方式。比如分页SQL
3.程序过分依赖SQL对程序的移植及扩展,维护等带来很大的麻烦。
Hibernate
它是Java领域的一款开源的ORM框架技术;对JDBC进行了非常轻量级的对象封装把业务逻辑层生成的对象持久化(或者说对象关系映射)到数据库中的表中其他主流的ORM框架技术:Mybatis EJB TopLink等
编写第一个例子
创建Hibernate的配置文件 hibernate.cfg.xml创建持久化类
创建对象-关系映射文件
通过Hibernate API编写访问数据库的代码
导入jar包(eclipse)
hibernate:hibernate-release-4.2.4.Final\lib\required;Mysql的JDBC:mysql-connecttor-java-5.1.7-bin.jar;
Junit4:junit-4.10.jar
1.生成hibernate配置文档
步骤:http://blog.csdn.net/fxk2006/article/details/4577418配置数据源:【window】-->【Show View】-->【Other…】-->选择DB Browser-->【右键 新建】
引入hibernate配置文件:右键-->MyEclipse-->Add Hibernate Capabilities
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">create</property>
2.生成持久化类和映射文件
步骤:http://blog.sina.com.cn/s/blog_b0f182290102v7ss.html3.配置映射文件 hibernate.cfg.xml
<property name="hibernate.current_session_context_class">thread</property>4.用Junit进行测试,三个注解方法:
@Test:测试方法@Before初始化方法
@After:释放资源
hibernate.cfg.xml常用配置
(1)hibernate.show_sql 编码阶段便于测试(2)hibernate.format_sql 排版问题,建议设置为true
(3)hbm2ddl.auto 可以帮助由 java代码生成数据库脚本,进而生成具体的表结构。create|update|create-drop|validate
(4)hiberante.default_schema 默认的数据库
(5)hibernate.dialect 配置Hibernate数据库方言
hibernate执行流程:
configuration:读取配置文件sessionfactory:读取对象关系映射文件
session:一个操作数据库的对象。和connection是多对一关系,hibernate本身就是对JDBC的封装,故不建议直接使用JDBC的connection
session简介
不启用事务无法保存数据,需要初始化时开启事务,结束时提交事务不使用事务的自动提交方式,记得用session.flush()来输出sql语句,否则添加不成功
public void testStudentSave() {
Students s = new Students(2,"zhangsan","boy","seu",new Date());
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
session.doWork(new Work(){
@Override
public void execute(Connection conn) throws SQLException {
conn.setAutoCommit(true);
}
});
session.save(s);
session.flush();
}
如何获得session对象???
(1)openSessionion(2)getCurrentSession
如果使用getCurrentSession需要在hibernate.cfg.xml文件中进行配置:
如果是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
如果是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
openSession与getCurrentSession的区别:
(1)getCurrentSession在事务提交或者回滚之后会自动关闭,而openSesssion需要你手动关闭。如果使用openSession而没有手动关闭,多次之后会导致连接池溢出!(2)openSession每次创建新的session对象,getCurrentSession使用现有的session对象
openSession 每次使用都是打开一个新的session,使用完需要调用close方法关闭session;
getCurrentSession 是获取当前session对象,连续使用多次时,得到的session都是同一个对象,这就是与openSession的区别之一 ;
一般在实际开发中,往往使用getCurrentSession多,因为一般是处理同一个事务,所以在一般情况下比较少使用openSession;
单表操作
单一主键:
assigned:由java应用程序负责生成(手工赋值)。native:由底层数据库自动生成标示符,如果是MySQL就是increment,如果是ORacle就是sequence,等等
基本类型
映射类型 Java类型 标准SQL类型 描述date java.util.Date或 DATE java.sql.Date 代表日期:yyyy-MM--dd
time java.util.Date或 TIME java.sql.Date 代表时间:hh:mi:ss
timestamp java.util.Date或 TIMESTAMP java.sql.Timestamp 代表时间和日期yyyymmddhhmiss
calendar java.util.Calendar TIMESTAMP 同上
calendar java.util.Calendar DATE 代表日期:yy-MM-dd
对象类型
映射类型 Java类型 标准SQL类型 标准MYSQL类型 标准Oracle类型binary byte[] VARCHAR(或BLOB) BLOB BLOB
text java.lang.String CLOB TEXT CLOB
clob java.sql.Clob CLOB TEXT CLOB
blob java.sql.Blob BLOB BLOB BLOB
1.clob和text对应大文本文件,blob对应大的二进制文件,例如视频音频图片
2.java中的clob对应存储大文本文件,java中的blob对应存储大二进制文件
MySQL不支持标准SQL的CLOB类型,在Mysql中,用TEXT,MEDIUMTEXT及LONGTEXT类型来表示长度超过255的长文本数据
组件属性
就是用一类把几个属性封装在一起用类的对象调用,在配置文件 hibernate.cfg.xml中<component name="address" class="model.Address">
<property name="addr" column="ADDRESS" />
<property name="phone" column="PHONE" />
</component>
单表操作实例
查询单个记录时:get和Load的区别:(1)get在不考虑缓存的情况下,get方法会在调用之后立即向数据库发送sql语句,返回持久化对象。load方法会在调用后返回一个代理对象,该代理对象只保存了实体对象的id,直到使用对象的非主键属性时才会发出sql语句。
(2)查询数据库中不存在的数据时,get方法返回null,load方法抛出异常org.hibernate.ObjectNotFoundException
package Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import model.Address;
import model.Students;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.jdbc.Work;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class StudentTest {
private static SessionFactory sessionFactory;
private static Session session;
@Before
public void beforeClass() {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
session = sessionFactory.getCurrentSession();
session.beginTransaction();
}
@After
public void afterClass() {
sessionFactory.close();
session.getTransaction().commit();
}
@Test
public void testStudentSave() {
Students s = new Students("lily", "bo", new Address("li","hu"),new Timestamp(0));
session.save(s);
}
@Test
public void testStudentGet() {
Students s=(Students) session.get(Students.class, 1);
System.out.println(s);
}
@Test
public void testStudentLoad() {
Students s=(Students) session.load(Students.class, 1);
System.out.println(s);
}
@Test
public void testStudentUpdate() {
Students s=(Students) session.get(Students.class, 1);
s.setGender("girl");
session.update(s);
}
@Test
public void testStudentDelete() {
Students s=(Students) session.get(Students.class, 1);
session.delete(s);
}
}