Hibernate-细细道来

Dao代码,如何编写?

  • 使用Jdbc技术,原始的jdbc操作, Connection/Statement/ResultSet
  • DbUtils组件, 轻量级的dao的组件;
  • Hibernate技术  【hibernate最终执行的也是jdbc代码!】

ORM概念

  • O,  Object  对象
  • R, Realtion 关系  (关系型数据库: MySQL, Oracle…)
  • M,Mapping  映射
  • ORM, 对象关系映射!

ORM, 解决什么问题?

  • 存储:   能否把对象的数据直接保存到数据库?
  • 获取:  能否直接从数据库拿到一个对象?
  • 想做到上面2点,必须要有映射!

总结:

           Hibernate与ORM的关系?

           Hibernate是ORM的实现!

HelloWorld案例

搭建一个Hibernate环境,开发步骤:

1. 下载源码

版本:hibernate-distribution-3.6.0.Final

2. 引入jar文件

           hibernate3.jar核心  +  required 必须引入的(6个) +  jpa 目录  + 数据库驱动包

3. 写对象以及对象的映射

Employee.java            对象

Employee.hbm.xml        对象的映射 (映射文件)

4. src/hibernate.cfg.xml  主配置文件

数据库连接配置

加载所用的映射(*.hbm.xml)

5. App.java  测试

 1 Employee.java     对象
 2 //一、 对象
 3 public class Employee {
 4
 5     private int empId;
 6     private String empName;
 7     private Date workDate;
 8
 9 }
10 Employee.hbm.xml  对象的映射
11 <?xml version="1.0"?>
12 <!DOCTYPE hibernate-mapping PUBLIC
13     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
14     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
15
16 <hibernate-mapping package="cn.itcast.a_hello">
17
18     <class name="Employee" table="employee">
19
20         <!-- 主键 ,映射-->
21         <id name="empId" column="id">
22             <generator class="native"/>
23         </id>
24
25         <!-- 非主键,映射 -->
26         <property name="empName" column="empName"></property>
27         <property name="workDate" column="workDate"></property>
28
29     </class>
30
31 </hibernate-mapping>
32 hibernate.cfg.xml    主配置文件
33 <!DOCTYPE hibernate-configuration PUBLIC
34     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
35     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
36
37 <hibernate-configuration>
38     <session-factory>
39         <!-- 数据库连接配置 -->
40         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
41         <property name="hibernate.connection.url">jdbc:mysql:///hib_demo</property>
42         <property name="hibernate.connection.username">root</property>
43         <property name="hibernate.connection.password">root</property>
44         <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
45
46         <property name="hibernate.show_sql">true</property>
47
48         <!-- 加载所有映射 -->
49         <mapping resource="cn/itcast/a_hello/Employee.hbm.xml"/>
50     </session-factory>
51 </hibernate-configuration>
52 App.java   测试类
53
54 public class App {
55
56     @Test
57     public void testHello() throws Exception {
58         // 对象
59         Employee emp = new Employee();
60         emp.setEmpName("班长");
61         emp.setWorkDate(new Date());
62
63         // 获取加载配置文件的管理类对象
64         Configuration config = new Configuration();
65         config.configure();  // 默认加载src/hibenrate.cfg.xml文件
66         // 创建session的工厂对象
67         SessionFactory sf = config.buildSessionFactory();
68         // 创建session (代表一个会话,与数据库连接的会话)
69         Session session = sf.openSession();
70         // 开启事务
71         Transaction tx = session.beginTransaction();
72         //保存-数据库
73         session.save(emp);
74         // 提交事务
75         tx.commit();
76         // 关闭
77         session.close();
78         sf.close();
79     }
80 }

Hibernate  API

|-- Configuration       配置管理类对象

config.configure();    加载主配置文件的方法(hibernate.cfg.xml), 默认加载src/hibernate.cfg.xml

config.configure(“cn/config/hibernate.cfg.xml”);   加载指定路径下指定名称的主配置文件

config.buildSessionFactory();   创建session的工厂对象

|-- SessionFactory     session的工厂(或者说代表了这个hibernate.cfg.xml配置文件)

sf.openSession();   创建一个sesison对象

sf.getCurrentSession();  创建session或取出session对象

|--Session       session对象维护了一个连接(Connection), 代表了与数据库连接的会话。

Hibernate最重要的对象: 只用使用hibernate与数据库操作,都用到这个对象

session.beginTransaction(); 开启一个事务; hibernate要求所有的与数据库的操作必须有事务的环境,否则报错!

更新:

session.save(obj);   保存一个对象

session.update(emp);  更新一个对象

session.saveOrUpdate(emp);  保存或者更新的方法:

没有设置主键,执行保存;

有设置主键,执行更新操作;

如果设置主键不存在报错!

主键查询:

session.get(Employee.class, 1);    主键查询

session.load(Employee.class, 1);   主键查询 (支持懒加载)

HQL查询:

HQL查询与SQL查询区别:

SQL: (结构化查询语句)查询的是表以及字段;  不区分大小写。

HQL: hibernate  query  language 即hibernate提供的面向对象的查询语言

查询的是对象以及对象的属性。

区分大小写。

Criteria查询:

完全面向对象的查询。

本地SQL查询:

复杂的查询,就要使用原生态的sql查询,也可以,就是本地sql查询的支持!

(缺点: 不能跨数据库平台!)

|-- Transaction    hibernate事务对象

Hibernate.cfg.xml

  主配置文件中主要配置:数据库连接信息、其他参数、映射信息!

  常用配置查看源码: hibernate-distribution-3.6.0.Final\project\etc\hibernate.properties

  数据库连接参数配置

    例如:## MySQL

    #hibernate.dialect org.hibernate.dialect.MySQLDialect

    #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect

    #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect

    #hibernate.connection.driver_class com.mysql.jdbc.Driver

    #hibernate.connection.url jdbc:mysql:///test

    #hibernate.connection.username gavin  

    #hibernate.connection.password

  自动建表 

       #hibernate.hbm2ddl.auto   create-drop        每次在创建sessionFactory时候执行创建表;

当调用sesisonFactory的close方法的时候,删除表!

    #hibernate.hbm2ddl.auto    create         每次都重新建表; 如果表已经存在就先删除再创建

    #hibernate.hbm2ddl.auto    update  如果表不存在就创建; 表存在就不创建;

    #hibernate.hbm2ddl.auto    validate  (生成环境时候) 执行验证: 当映射文件的内容与数据库表结构不一样的时候就报错!

映射配置

  1. 普通字段类型

  2. 主键映射

单列主键映射

多列作为主键映射

    主键生成策略,查看api:   5.1.2.2.1. Various additional generators

  3.  数据库主键:

一个表能否有多个主键?   不能。

为什么要设置主键?

         数据库存储的数据都是有效的,必须保持唯一。

为什么把id作为主键?

因为表中通常找不到合适的列作为唯一列即主键,所以为了方法用id列,因为id是数据库系统维护可以保证唯一,所以就把这列作为主键!

联合/复合主键?

    如果找不到合适的列作为主键,除了用id列以外,我们一般用联合主键,即多列的值作为一个主键,从而确保记录的唯一性。

  4.  映射配置:

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5
 6
 7 <!-- 映射文件: 映射一个实体类对象;  描述一个对象最终实现可以直接保存对象数据到数据库中。  -->
 8 <!--
 9     package: 要映射的对象所在的包(可选,如果不指定,此文件所有的类都要指定全路径)
10     auto-import 默认为true, 在写hql的时候自动导入包名
11                 如果指定为false, 再写hql的时候必须要写上类的全名;
12                   如:session.createQuery("from cn.itcast.c_hbm_config.Employee").list();
13  -->
14 <hibernate-mapping package="cn.itcast.c_hbm_config" auto-import="true">
15
16     <!--
17         class 映射某一个对象的(一般情况,一个对象写一个映射文件,即一个class节点)
18             name 指定要映射的对象的类型
19             table 指定对象对应的表;
20                   如果没有指定表名,默认与对象名称一样
21      -->
22     <class name="Employee" table="employee">
23
24         <!-- 主键 ,映射-->
25         <id name="empId" column="id">
26             <!--
27                 主键的生成策略
28                     identity  自增长(mysql,db2)
29                     sequence  自增长(序列), oracle中自增长是以序列方法实现
30                     native  自增长【会根据底层数据库自增长的方式选择identity或sequence】
31                             如果是mysql数据库, 采用的自增长方式是identity
32                             如果是oracle数据库, 使用sequence序列的方式实现自增长
33
34                     increment  自增长(会有并发访问的问题,一般在服务器集群环境使用会存在问题。)
35
36                     assigned  指定主键生成策略为手动指定主键的值
37                     uuid      指定uuid随机生成的唯一的值
38                     foreign   (外键的方式, one-to-one讲)
39              -->
40             <generator class="uuid"/>
41         </id>
42
43         <!--
44             普通字段映射
45             property
46                 name  指定对象的属性名称
47                 column 指定对象属性对应的表的字段名称,如果不写默认与对象属性一致。
48                 length 指定字符的长度, 默认为255
49                 type   指定映射表的字段的类型,如果不指定会匹配属性的类型
50                     java类型:     必须写全名
51                     hibernate类型:  直接写类型,都是小写
52         -->
53         <property name="empName" column="empName" type="java.lang.String" length="20"></property>
54         <property name="workDate" type="java.util.Date"></property>
55         <!-- 如果列名称为数据库关键字,需要用反引号或改列名。 -->
56         <property name="desc" column="`desc`" type="java.lang.String"></property>
57
58     </class>
59
60
61 </hibernate-mapping>

  5.复合主键映射

 1 // 复合主键类
 2 public class CompositeKeys implements Serializable{
 3     private String userName;
 4     private String address;
 5    // .. get/set
 6 }
 7 public class User {
 8
 9     // 名字跟地址,不会重复
10     private CompositeKeys keys;
11     private int age;
12 }
13 User.hbm.xml
14 <?xml version="1.0"?>
15 <!DOCTYPE hibernate-mapping PUBLIC
16     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
17     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
18
19 <hibernate-mapping package="cn.itcast.d_compositeKey" auto-import="true">
20
21     <class name="User">
22
23         <!-- 复合主键映射 -->
24         <composite-id name="keys">
25             <key-property name="userName" type="string"></key-property>
26             <key-property name="address" type="string"></key-property>
27         </composite-id>
28
29         <property name="age" type="int"></property>
30
31     </class>
32
33
34 </hibernate-mapping>
35
36 App.java
37
38 public class App2 {
39
40     private static SessionFactory sf;
41     static  {
42         // 创建sf对象
43         sf = new Configuration()
44             .configure()
45             .addClass(User.class)  //(测试) 会自动加载映射文件:Employee.hbm.xml
46             .buildSessionFactory();
47     }
48
49     //1. 保存对象
50     @Test
51     public void testSave() throws Exception {
52         Session session = sf.openSession();
53         Transaction tx = session.beginTransaction();
54
55         // 对象
56         CompositeKeys keys = new CompositeKeys();
57         keys.setAddress("广州棠东");
58         keys.setUserName("Jack");
59         User user = new User();
60         user.setAge(20);
61         user.setKeys(keys);
62
63         // 保存
64         session.save(user);
65
66
67         tx.commit();
68         session.close();
69     }
70
71     @Test
72     public void testGet() throws Exception {
73         Session session = sf.openSession();
74         Transaction tx = session.beginTransaction();
75
76         //构建主键再查询
77         CompositeKeys keys = new CompositeKeys();
78         keys.setAddress("广州棠东");
79         keys.setUserName("Jack");
80
81         // 主键查询
82         User user = (User) session.get(User.class, keys);
83         // 测试输出
84         if (user != null){
85             System.out.println(user.getKeys().getUserName());
86             System.out.println(user.getKeys().getAddress());
87             System.out.println(user.getAge());
88         }
89
90
91         tx.commit();
92         session.close();
93     }
94 }
时间: 2024-11-03 21:53:03

Hibernate-细细道来的相关文章

ios多线程使用之细细细~解

在开发中经常会用到多线程来处理一些比较耗时的任务,比如下载的时候存储数据.当进入一个新页面的时候将网络请求放在后台,数据下来之后再到主线程来将数据展示出来等操作,以此来满足用户大老爷的体验,让他们开开心心的用我们开发出来的应用而不是用的时候一脸懵逼的等待响应T T.平常在开发的过程中,我们只需将耗时应用放在后台的子线程.任务结束之后回到主线程来刷新页面就好了.基本下面的几行代码是我们最常用到的: dispatch_async(dispatch_get_global_queue(0, 0), ^{

JAVA 相关资料

在技术方面无论我们怎么学习,总感觉需要提升自已不知道自己处于什么水平了.但如果有清晰的指示图供参考还是非常不错的,这样我们清楚的知道我们大概处于那个阶段和水平. Java程序员 高级特性 反射.泛型.注释符.自动装箱和拆箱.枚举类.可变 参数.可变返回类型.增强循环.静态导入 核心编程 IO.多线程.实体类. 集合类.正则表达式. XML和属性文件 图形编程 AWT(Java2D/JavaSound/JMF).Swing.SWT.JFace 网路编程 Applet.Socket/TCP/UDP.

从程序员到CTO的Java技术路线图(我爱分享)

在技术方面无论我们怎么学习,总感觉需要提升自已不知道自己处于什么水平了.但如果有清晰的指示图供参考还是非常不错的,这样我们清楚的知道我们大概处于那个阶段和水平. Java程序员 高级特性 反射.泛型.注释符.自动装箱和拆箱.枚举类.可变 参数.可变返回类型.增强循环.静态导入 核心编程 IO.多线程.实体类. 集合类.正则表达式. XML和属性文件 图形编程 AWT(Java2D/JavaSound/JMF).Swing.SWT.JFace 网路编程 Applet.Socket/TCP/UDP.

从程序员到CTO的Java技术路线图

http://zz563143188.iteye.com/blog/1877266在技术方面无论我们怎么学习,总感觉需要提升自已不知道自己处于什么水平了.但如果有清晰的指示图供参考还是非常不错的,这样我们清楚的知道我们大概处于那个阶段和水平. Java程序员 高级特性 反射.泛型.注释符.自动装箱和拆箱.枚举类.可变 参数.可变返回类型.增强循环.静态导入 核心编程 IO.多线程.实体类. 集合类.正则表达式. XML和属性文件 图形编程 AWT(Java2D/JavaSound/JMF).Sw

全局变量的危害

今日饱受一个全局变量的危害,导致多个项目出现问题,揪其根本原因是,全局变量的危害导致的.这里转载一篇关于全局变量危害的代码:工作也有些年头了,从一位技术新人成长到现在自诩小牛级别的人物,少不了要自己寻找资料阅读.论坛上.书店里.杂志上......要嘛是些菜鸟浅薄的自炫处女贴,要嘛是高屋建瓴云里来雾里去的概念文,好不容易遇到个实践型高手写的文章,却在渐入佳境之际嘎然而止.本是隔靴搔痒,看完后心中更是郁结不已.也罢,今日且强装回大牛,献丑谈一谈嵌入式C编程中全局变量问题.嵌入式特别是单片机os-le

tinyhttpd源码详解

tinyhttpd是一轻量级的web 服务器,最近几天终于抽出时间来研究研究了.其源码百度即可下载,500多行,确实是学习linux编程的好材料.很多网友都写了关于tinyhttpd的博文,但是我还是觉得不够深入,严格说是写得不够深入,往往就是把500多行代码一扔,分析下主要过程,画个流程图就完事了.我怎么觉得还有很多东西可以挖一挖呢,也许还可再调整一下代码,虽然目前也不清楚可调整多少,待我细细道来. 我分析的过程就按主要路线走,也就是这样一个主干道流程:服务器创建socket并监听某一端口->

C语言::输出九九乘法口诀表

题目要求 编写C语言程序.输出九九乘法口诀表.(如下所示) 1x1=1 1x2=2  2x2=4 1x3=3  2x3=6  3x3=9 ..... 1x9=9  2x9=18 3x9=27 4x9=... 算法分析 首先容我先装一逼,依老夫多年的编程经验,本题一定需要循环! 如果你目前还不知道为什么用循环,也没有关系,只要记住就好,日后经验丰富后,必然也能像我这样! 话入正题,我是怎么看出来这道题用循环的? 首先我们得考虑这份乘法口诀表具有什么特征,稍加分析,我们发现... 乘法口诀表特征如下

7.9笔记

TCP/IP协议不是TCP和IP这两个协议的合称,而是指因特网整个TCP/IP协议族. 从协议分层模型方面来讲,TCP/IP由四个层次组成:网络接口层.网络层.传输层.应用层. TCP协议:即传输控制协议,它提供的是一种可靠的数据流服务.当传送受差错干扰的数据,或举出网络故障,或网络负荷太重而使网际基本传输系统不能正常工作时,就需要通过其他的协议来保证通信的可靠.TCP就是这样的协议.TCP采用"带重传的肯定确认"技术来实现传输的可靠性.并使用"滑动窗口"的流量控制

深入研究 Java Synchronize 和 Lock 的区别与用法

在分布式开发中,锁是线程控制的重要途径.Java为此也提供了2种锁机制,synchronized和lock.做为Java爱好者,自然少不了对比一下这2种机制,也能从中学到些分布式开发需要注意的地方. 我们先从最简单的入手,逐步分析这2种的区别. 一.synchronized和lock的用法区别 synchronized:在需要同步的对象中加入此控制,synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要锁的对象. lock:需要显示指定起始位置和终止位置.一般使用Reen

Linux 爱好者该向闭源软件敞开怀抱了

微软和苹果都已经为开源产品得到接受奠定了基础,甚至苹果公司有开发了一个开源网页显示了它在2015年已经开放的所有产品:微软更是公开表示,“开源 Windows 绝对有可能”.如果你考虑一下企业计算界的状态,就会清楚地发现,不开源的产品处境正岌岌可危. 不祥之兆已经出现在眼前……开源已获胜,运行着世界上一些最强大的网络和系统.如果各大软件厂商想在这个市场分得一杯羹,就得玩开放这个游戏. 此外,微软和苹果都无法再从操作系统赚得大把大把的钱.两家公司甚至免费派送主要版本的升级版.以平台来获利的商业模式