- 第1课 课程内容
- 1、 HelloWorld
- a) Xml
- b) Annotction
- 2、 Hibernate原理模拟-什么是O/RMapping以及为什么要有O/RMapping
- 3、 常风的O/R框架
- 4、 Hibernate基础配置
- 5、 Hibernate核心接口介绍
- 6、 对象的三种状态
- 7、 ID生成策略
- 8、 关系映射
- 9、 Hibernate查询(HQL)
- 10、 在Struts基础上继续完美BBS2009
- 11、 性能优化
- 12、 补充话题
结合struts与hibernate后程序的架构如下:
Hibernate UML图
![](http://hi.csdn.net/attachment/201111/19/0_1321668544xDS3.gif)
hibernate下载网站
http://www.hibernate.org
Download hibernate-search-4.0.0.Beta2-dist.zip (25.3 MB) ----->说明 Beta 版本是测试版本,不能正常使用
hibernate-distribution-3.6.8.Final-dist.zip 以zip结尾的是windows下的版本 final表示版本号 正式版
hibernate-distribution-3.6.8.Final-dist.tar.gz 以gz结尾的是linux下的版本
compatibility matrix 兼容性矩阵
例如: 就是你下载的 hibernate core 版本是3.2.6 GA 对应的Annotations注解包就应该是2.2.x, 3.3.x
下载的是3.3.2对应的就是3.4.x : 不过下面有好消息说明的是3.5.x 过后会把 core 、Annotations、EntityManager 包放在一起
please note that as of 3.5.x hibernate core,hibernate annotations and hibernate entitymanager are all versioned and released together whcih greatly simplifies this matrix
hibernate 做日志的时候有到的是 SLF4J
http://www.slf4j.org/
hibernate-annotations-3.4.0.GA 中文版文档目录
D:\java rj\ssh\hibernate\hibernate-annotations-3.4.0.GA\doc\reference\zh_cn\html_single\index.html
hibernate-(distribution)core 中文版文档目录
D:\java rj\ssh\hibernate\hibernate-distribution-3.3.2.GA\documentation\manual\zh-CN\html_single\index.html
——————————————————
第3课 风格
1、 先脉络,后细节
2、 先操作、后原理
3、 重Annotation,轻xml配置文件
a) JPA (可以认为EJB3的一部分)
b) Hibernate– extension
第4课 资源
a) hibernate-distribution-3.3.2.GA-dist.zip
b) hibernate-annotations-3.4.0.GA.zip
c) slf4j-1.5.10.zip (hibernate内部日志用)
2、 hibernatezh_CN文档
3、 hibernateannotateon references
第5课 环境准备
1、 下载hibernate3.3.2
2、 下载hibernate-annotations-3.4.0
3、 注意阅读hibernate compatibility matrix
4、 下载slf4j 1.5.8
第6课 第一个示例Hibernate HelloWorld
1、 建立新的java项目,名为hibernate_0100_HelloWorld
2、 学习建立User-liberary-hibernate,并加入相应的jar包
a) 项目右键-build path-configure build path-add library
b) 选择User-library ,在其中新建library,命名为hibernate
c) 在该library中加入hibernate所需的jar名
i. Hibernatecore
ii. /lib/required
iii. Slf-nopjar
3、 引入mysql的JDBC驱动名
4、 在mysql中建立对应的数据库以及表
a) Create databasehibernate;
b) Usehibernate;
c) Createtable Student (id int primary key, name varchar(20),age int);
5、 建立hibernate配置文件hibernate.cfg.xml
a) 从参考文档中copy
b) 修改对应的数据库连接
c) 注释提暂时不需要的内容
6、 建立Student类
7、 建立Student映射文件Student.hbm.xml
a) 参考文档
8、 将映射文件加入到hibernate.cfg.xml
a) 参考文档
9、 写测试类Main,在Main中对Student对象进行直接的存储测试
第一项目
加入jar文件
先new一个libraries
再加入jar包 Add JARs
bytecode 生成二进制字节码的要的jar包
optional 可选的
required 必须的 (全部导入)
之所以要从新在官网下载是因为
lib目录下只定义了slf4就的api 没有定实现 (就犹如你拿到了接口没有拿到实现) 因此要运行必须到slf4j官网去下载
http://www.slf4j.org/dist/ slf4j 要与hibernate的api名称一致
需要的slf4j下面的包是 slf4j-nop-1.5.8.jar
以上是最原始的hibernate 需要的包,如果还需要annotation的话还需要它的3个包
在项目里面选择如下:
选择项目---> 右键 build path ---> Add Libraries --->User Library
选择hibernate 点击Finish 完成
还需要和数据库建立联系 因此还需要mysql 的一个数据包mysql-connector-java-5.1.18-bin.jar
- drop table student;
- create database hibernate;
- use hibernate;
- create table student;
- create table student (
- id int primary key,
- name varchar(20),
- age int
- );
- <hibernate-mapping package="org.hibernate.tutorial.domain">
- <class name="Event" table="EVENTS">
- <id name="id" column="EVENT_ID">
- <generator class="native"/>
- </id>
- <property name="date" type="timestamp" column="EVENT_DATE"/>
- <property name="title"/>
- </class>
- </hibernate-mapping>
class里面的 name指的是类名 而table 是指数据库里面的表名 如果表名与类名一样 可以不写table名 数据库不区分大小写
id 是指主键名 (primay key) column是指可以指定数据库id名 而name是指类名的属性 一样可以不写 column
property 是指类名里面的属性
事例如下:
- <hibernate-mapping package="com.demo.hibernate.model">
- <class name="Student">
- <id name="id"></id>
- <property name="name"/>
- <property name="age"/>
- </class>
- </hibernate-mapping>
- //Student 类
- package com.demo.hibernate.model;
- public class Student {
- private int id;
- private String name;
- private int age;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
- <!-- hibernate.hbm.xml -->
- <?xml version='1.0' encoding='utf-8'?>
- <!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
- <hibernate-configuration>
- <session-factory>
- <!-- Database connection settings -->
- <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
- <property name="connection.url">jdbc:mysql://localhost/hibernate</property>
- <property name="connection.username">root</property>
- <property name="connection.password">root</property>
- <!-- JDBC connection pool (use the built-in) -->
- <!-- <property name="connection.pool_size">1</property> -->
- <!-- SQL dialect -->
- <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
- <!-- Enable Hibernate's automatic session context management -->
- <!-- <property name="current_session_context_class">thread</property> -->
- <!-- Disable the second-level cache -->
- <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
- <!-- Echo all executed SQL to stdout -->
- <property name="show_sql">true</property>
- <!-- Drop and re-create the database schema on startup -->
- <!-- <property name="hbm2ddl.auto">update</property> -->
- <mapping resource="com/demo/hibernate/model/Student.hbm.xml"/>
- </session-factory>
- </hibernate-configuration>
- <!-- 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">
- <hibernate-mapping package="com.demo.hibernate.model">
- <class name="Student">
- <id name="id"></id>
- <property name="name"/>
- <property name="age"/>
- </class>
- </hibernate-mapping>
- //StudentTest
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.cfg.Configuration;
- import com.demo.hibernate.model.Student;
- public class StudentTest {
- public static void main(String[] args) {
- Student s = new Student();
- s.setId(1);
- s.setName("s1");
- s.setAge(1);
- Configuration cfg = new Configuration();
- SessionFactory sf = cfg.configure().buildSessionFactory();
- Session session = sf.openSession();
- session.beginTransaction();
- session.save(s);
- session.getTransaction().commit();
- session.close();
- sf.close();
- }
- }
建立Annotation版本的HellWorld
注意:要求hibernate3.0版本以后支持
引入annotation jar包
- package com.demo.hibernate.model;
- import javax.persistence.Entity;
- import javax.persistence.Id;
- @Entity //实体类
- public class Teacher {
- private int id;
- private String name;
- private String title;
- @Id //主键
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getTitle() {
- return title;
- }
- public void setTitle(String title) {
- this.title = title;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
- <!-- hibernate.hbm.xml -->
- <mapping class="com.demo.hibernate.model.Teacher"/>
- //TeacherTest
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.cfg.AnnotationConfiguration;
- import org.hibernate.cfg.Configuration;
- import com.demo.hibernate.model.Teacher;
- public class TeacherTest {
- public static void main(String[] args) {
- Teacher t = new Teacher();
- t.setId(1);
- t.setName("t1");
- t.setTitle("中级");
- Configuration cfg = new AnnotationConfiguration();
- SessionFactory sf = cfg.configure().buildSessionFactory();
- Session session = sf.openSession();
- session.beginTransaction();
- session.save(t);
- session.getTransaction().commit();
- session.close();
- sf.close();
- }
- }
Annotation 与影视文件不一致的有:
1、不需要建立映射文件
2、hibernate.hbm.xml 里面用.
3、Configuration 里面创建用AnnotationConfiguration()
敲. (点) 提示设置如下: Auto activation triggers for Java .
第8课 什么是O/R Mapping
一、 定义:
ORM(ObjectRelational Mapping)---是一种为了解决面向对象与关系型数据库存在的互不匹配的现象的技术。简单说:ORM是通过使用描述对象和数据库之间映射的元数据,将Java程序中的对象自动持久化到关系数据中。本质上就是将数据从一种形式转换到另外一种形式。
分层后,上层不需要知道下层是如何做了。
分层后,不可以循环依赖,一般是单向依赖。
二、 Hibernate的创始人:
Gavin King
三、 Hibernate做什么:
1、 就是将对象模型(实体类)的东西存入关系模型中,
2、 实体中类对应关系型库中的一个表,
3、 实体类中的一个属性会对应关系型数据库表中的一个列
4、 实体类的一个实例会对应关系型数据库表中的一条记录。
%%将对象数据保存到数据库、将数据库数据读入到对象中%%
OOA---面向对象的分析、面向对象的设计
OOD---设计对象化
OOP---面向对象的开发
阻抗不匹配---例JAVA类中有继承关系,但关系型数据库中不存在这个概念这就是阻抗不匹配。Hibernate可以解决这个问题
四、 Hibernate存在的原因:
1、 解决阻抗不匹配的问题;
2、 目前不存在完整的面向对象的数据库(目前都是关系型数据库);
3、 JDBC操作数据库很繁琐
4、 SQL语句编写并不是面向对象
5、 可以在对象和关系表之间建立关联来简化编程
6、 O/RMapping简化编程
7、 O/RMapping跨越数据库平台
8、 hibernate_0200_OR_Mapping_Simulation
五、 Hibernate的优缺点:
1、 不需要编写的SQL语句(不需要编辑JDBC),只需要操作相应的对象就可以了,就可以能够存储、更新、删除、加载对象,可以提高生产效;
2、 因为使用Hibernate只需要操作对象就可以了,所以我们的开发更对象化了;
3、 使用Hibernate,移植性好(只要使用Hibernate标准开发,更换数据库时,只需要配置相应的配置文件就可以了,不需要做其它任务的操作);
4、 Hibernate实现了透明持久化:当保存一个对象时,这个对象不需要继承Hibernate中的任何类、实现任何接口,只是个纯粹的单纯对象—称为POJO对象(最纯粹的对象—这个对象没有继承第三方框架的任何类和实现它的任何接口)
5、 Hibernate是一个没有侵入性的框架,没有侵入性的框架我们一般称为轻量级框架
6、 Hibernate代码测试方便。
六、 Hibernate使用范围:
1. 针对某一个对象,简单的将它加载、编辑、修改,且修改只是对单个对象(而不是批量的进行修改),这种情况比较适用;
2. 对象之间有着很清晰的关系(例:多个用户属于一个组(多对一)、一个组有多个用户(一对多));
3. 聚集性操作:批量性添加、修改时,不适合使用Hibernate(O/映射框架都不适合使用);
4. 要求使用数据库中特定的功能时不适合使用,因为Hibernate不使用SQL语句;
第9课 Hibernate的重点学习:Hibernate的对象关系映射
一、对象---关系映射模式
l 属性映射;
l 类映射:
l 关联映射:
n 一对一;
n 一对多;
n 多对多。
二、常用的O/R映射框架:
1、 Hibernate
2、 ApacheOJB
3、 JDO(是SUN提出的一套标准—Java数据对象)
4、 Toplink(Orocle公司的)
5、 EJB(2.0X中有CMP;3.0X提出了一套“Java持久化API”---JPA)
6、 IBatis(非常的轻量级,对JDBC做了一个非常非常轻量级的包装,严格说不是O/R映射框架,而是基于SQL的映射(提供了一套配置文件,把SQL语句配置到文件中,再配置一个对象进去,只要访问配置文件时,就可得到对象))
7、 JAP(是SUN公司的一套标准)
a) 意愿统一天下
第10课 模拟Hibernate原理(OR模拟)
我们使用一个项目来完成
功能:有一个配置文件,文件中完成表名与类名对象,字段与类属性对应起来。
测试驱动开发
一、 项目名称
hibernate_0200_OR_Mapping_Simulation
二、 原代码
- Test类:
- public static void main(String[] args) throws Exception{
- Student s = new Student();
- s.setId(10);
- s.setName("s1");
- s.setAge(1);
- Session session = new Session();//此Session是我们自己定义的Session
- session.save(s);
- }
- Session类
- import java.lang.reflect.Method;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.util.HashMap;
- import java.util.Map;
- import com.wjt276.hibernate.model.Student;
- public class Session {
- String tableName = "_Student";
- Map<String,String> cfs = new HashMap<String,String>();
- String[] methodNames;//用于存入实体类中的get方法数组
- public Session(){
- cfs.put("_id", "id");
- cfs.put("_name", "name");
- cfs.put("_age", "age");
- methodNames = new String[cfs.size()];
- }
- public void save(Student s) throws Exception{
- String sql = createSQL();//创建SQL串
- Class.forName("com.mysql.jdbc.Driver");
- Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/hibernate","root","root");
- PreparedStatement ps = conn.prepareStatement(sql);
- //
- for(int i = 0; i < methodNames.length; i++){
- Method m = s.getClass().getMethod(methodNames[i]);//返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法
- Class r = m.getReturnType();//返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型
- if(r.getName().equals("java.lang.String")) {
- //对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。
- //个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换
- String returnValue = (String)m.invoke(s);
- ps.setString(i + 1, returnValue);
- }
- if(r.getName().equals("int")) {
- Integer returnValue = (Integer)m.invoke(s);
- ps.setInt(i + 1, returnValue);
- }
- if(r.getName().equals("java.lang.String")) {
- String returnValue = (String)m.invoke(s);
- ps.setString(i + 1, returnValue);
- }
- System.out.println(m.getName() + "|" + r.getName());
- }
- ps.executeUpdate();
- ps.close();
- conn.close();
- }
- private String createSQL() {
- String str1 = "";
- int index = 0;
- for(String s : cfs.keySet()){
- String v = cfs.get(s);//取出实体类成员属性
- v = Character.toUpperCase(v.charAt(0)) + v.substring(1);//将成员属性第一个字符大写
- methodNames[index] = "get" + v;//拼实体类成员属性的getter方法
- str1 += s + ",";//根据表中字段名拼成字段串
- index ++;
- }
- str1 = str1.substring(0,str1.length() -1);
- String str2 = "";
- //根据表中字段数,拼成?串
- for (int i = 0; i < cfs.size(); i++){ str2 += "?,";}
- str2 = str2.substring(0,str2.length() -1);
- String sql = "insert into " + tableName + "(" + str1 + ")" + " values (" + str2 + ")";
- System.out.println(sql);
- return sql;
- }}
第11课 Hibernate基础配置
一、 提纲
1、 对应项目:hibernate_0300_BasicConfiguration
2、 介绍MYSQL的图形化客户端
3、 Hibernate.cfg.xml:hbm2ddl.auto
a) 先建表还是先建实体类
4、 搭建日志环境并配置显示DDL语句
5、 搭建Junit环境
a) 需要注意Junit的Bug
6、 ehibernate.cfg.xml: show_sql
7、 hibernate.cfg.xml:format_sql
8、 表名和类名不同,对表名进行配置
a) Annotation:@Table
b) Xml:自己查询
9、 字段名和属性相同
a) 默认为@Basic
b) Xml中不用写column
10、 字段名和属性名不同
a) Annotation:@Column
b) Xml:自己查询
11、 不需要psersistence的字段
a) Annotation:@Transient
b) Xml:不写
12、 映射日期与时间类型,指定时间精度
a) Annotation:@Temporal
b) Xml:指定type
13、 映射枚举类型
a) Annotation:@Enumerated
b) Xml:麻烦
14、 字段映射的位置(field或者get方法)
a) Best practice:保持field和get/set方法的一致
15、 @Lob
16、 课外:CLOB BLOB类型的数据存取
17、 课外:Hibernate自定义数据类型
18、 Hibernate类型
二、 介绍MYSQL的图形化客户端
这样的软件网络很多,主要自己动手做
三、 Hibernate.cfg.xml:hbm2ddl.auto
在SessionFactory创建时,自动检查数据库结构,或者将数据库schema的DDL导出到数据库. 使用 create-drop时,在显式关闭SessionFactory时,将drop掉数据库schema.取值validate | update | create | create-drop
四、 搭建日志环境并配置显示DDL语句
我们使用slf接口,然后使用log4j的实现。
1、 首先引入log4j的jar包(log4j-1.2.14.jar),
2、 然后再引入slf4j实现LOG4J和适配器jar包(slf4j-log4j12-1.5.8.jar)
3、 最后创建log4j的配置文件(log4j.properties),并加以修改,只要保留
log4j.logger.org.hibernate.tool.hbm2ddl=debug
五、 搭建Junit环境
1、首先引入Junit 类库 jar包 (junit-4.8.1.jar)
2、在项目名上右键→new→Source Folder→输入名称→finish
3、注意,你对哪个包进行测试,你就在测试下建立和那个包相同的包
4、建立测试类,需要在测试的方法前面加入”@Test”
————————————————————————————————————————————————
- <property name="hbm2ddl.auto">create</property>
- hibernate.hbm.xml 中创建表的语句(在表中自动创建数据库表) <code class="literal">validate</code> | <code class="literal">update</code> | <code class="literal">create</code> | <code class="literal">create-drop</code>
slf4j(接口)下面一些日志实现
http://logging.apache.org/log4j/1.2/index.html log4j使用比slf4j比较流行
不过使用的时候需要一个转换器,即slf4j的slf4j-log4j12-1.5.8.jar 而不是( slf4j-log4j12-1.5.8-sources.jar)
hibernate Libraries 中jar包编辑
在hibernate 上面单击右键 --->Build Path —> Configure Build Path —> Edit 即可进行编辑
D:\javasoft\ssh\hibernate\hibernate-distribution-3.3.2.GA\project\etc\log4j.properties
加入log4j 日志报错,(SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".) 原来是把jar包导入错误应该是slf4j-log4j12-1.5.8.jar
src下面的日志文件 log4j.properties
- ### direct log messages to stdout ###
- log4j.appender.stdout=org.apache.log4j.ConsoleAppender
- log4j.appender.stdout.Target=System.out
- log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
- log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
- ### direct messages to file hibernate.log ###
- #log4j.appender.file=org.apache.log4j.FileAppender
- #log4j.appender.file.File=hibernate.log
- #log4j.appender.file.layout=org.apache.log4j.PatternLayout
- #log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
- ### set log levels - for more verbose logging change 'info' to 'debug' ###
- log4j.rootLogger=warn, stdout
- #log4j.logger.org.hibernate=info
- #log4j.logger.org.hibernate=debug
- ### log HQL query parser activity
- #log4j.logger.org.hibernate.hql.ast.AST=debug
- ### log just the SQL
- #log4j.logger.org.hibernate.SQL=debug
- ### log JDBC bind parameters ###
- #log4j.logger.org.hibernate.type=info
- #log4j.logger.org.hibernate.type=debug
- ### log schema export/update ###
- log4j.logger.org.hibernate.tool.hbm2ddl=debug
- ### log HQL parse trees
- #log4j.logger.org.hibernate.hql=debug
- ### log cache activity ###
- #log4j.logger.org.hibernate.cache=debug
- ### log transaction activity
- #log4j.logger.org.hibernate.transaction=debug
- ### log JDBC resource acquisition
- #log4j.logger.org.hibernate.jdbc=debug
- ### enable the following line if you want to track down connection ###
- ### leakages when using DriverManagerConnectionProvider ###
- #log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace