创建一个数据库bbs,一张表user
持久化类和我们的数据库的表是有对应关系的,故前提是,得有一张数据库的表User二维表(至少1张)和对应的实体类User类,我在vo包(数据对象value Object:页面与页面之间的传递值时保存值的对象)建立:
1 package dashuai.vo; 2 3 /** 4 * User 实体类 5 * 6 * @author Wang Yishuai. 7 * @date 2016/2/2 0002. 8 * @Copyright(c) 2016 Wang Yishuai,USTC,SSE. 9 */ 10 public class User { 11 private int userId; 12 13 private String username; 14 15 private String password; 16 17 public String getPassword() { 18 return password; 19 } 20 21 public void setPassword(String password) { 22 this.password = password; 23 } 24 25 public int getUserId() { 26 return userId; 27 } 28 29 public void setUserId(int userId) { 30 this.userId = userId; 31 } 32 33 public String getUsername() { 34 return username; 35 } 36 37 public void setUsername(String username) { 38 this.username = username; 39 } 40 }
同时它也是一个POJO类——POJO全称是Plain Ordinary Java Object / Plain Old Java Object,中文可以翻译成:普通Java类,具有一部分getter/setter方法的那种类就可以称作POJO类。
创建对象-关系映射的XML文件,必须放在实体类对应的包(我的是vo)下,名字严格对应为:类名.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> <!-- class 里面的属性必须和对应的类名,表名保持一致,实现映射--> <class name="dashuai.vo.User" table="user"> <!-- id代表数据库表的主键, name="userId",对应数据库表里的字段column="userId"--> <id name="userId" column="userId" type="int"/> <!-- 数据库里其他普通字段和实体属性的映射,属性的类型需要小写--> <property name="username" column="username" type="string"/> <property name="password" column="password" type="string"/> </class> </hibernate-mapping>
<class>元素用于指定类和表之间的映射,name属性设定类名(包含路径),table属性设定表名,默认以类名作表名
- name – 对应类的属性名称
- type – 指定属性的类型
- column – 指定表字段的名称
- not-null –指定属性是否允许为空
顺便把Hibernate的主配置文件hibernate.cfg.xml(需放在src根目录下)补充好,千万别忘了把之前对象关系映射配置文件引入到主配置文件内,mapping……
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <!-- 起一个名字 ,我这里叫 MySQL --> <session-factory name="MySQL"> <!-- 关于数据库连接的配置属性--> <!-- 连接MySQL数据库的驱动配置--> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!-- 配置MySQL数据库的连接地址,我的数据库叫bbs,端口一般都是3306 --> <property name="connection.url">jdbc:mysql://localhost:3306/bbs</property> <!-- 配置数据库的用户名和密码--> <property name="connection.username">root</property> <property name="connection.password">123</property> <!-- 配置数据库的方言,设置MySQL5.0版本的方言,MySQL5Dialect类的名称要写完整 --> <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- 方便调试,show_sql = true 设置显示自动生成的SQL脚本--> <property name="show_sql">true</property> <!-- 关键:把对象关系映射配置文件加到hibernate 主配置 文件,否则程序找不到 --> <mapping resource="dashuai/vo/User.hbm.xml"/> </session-factory> </hibernate-configuration>
创建dao包,并通过Hibernate API 编写访问数据库的代码,这里必须要知道hibernate的一些核心的类和接口。如下:
Hibernate 框架的核心类和接口
-
SessionFactory:是一个核心的接口,相当于hibernate和数据库连接的一个大管家,它缓存了Hibernate的配置信息和映射的元数据信息,属于重量级的,故实例化它的实现类只需要实例化一次,且不能轻易的关闭,如果关闭了,和数据库就断开了,此外,连接不同的数据库,需要建立不同的SessionFactory对象,而实例化该类,需要用到一个该接口的实现类——配置类Configuration,用Configuration的对象实例化之后,才能创建Session的实例。
- SessionFactory的创建,configuartion.buildSessionFactory()。
- SessionFactory是线程安全的,可以安全的让多个线程进行共享,一般整个应用只有唯一的一个SessionFactory实例。
- SessionFactory缓存
- 内置缓存,存储Hibernate配置信息和映射元数据信息,物理介质是内存
- 外置缓存,是一个可配置的缓存插件,可以存放大量的数据库数据的拷贝,物理介质可以是内存或者是硬盘
-
Configuration:是SessionFactory接口的实现类。
-
该实现类两个功能
- 负责管理Hibernate的运行的底层配置信息,包括:数据库的URL、数据库用户名和密码、JDBC驱动,数据库Dialect,数据库连接池等。
- 生成SessionFactory的对象,创建的SessionFactory对象能可以创建session
- 使用的两种方法
-
属性文件(hibernate.properties),调用代码:Configuration cfg = new Configuration();
-
xml文件(hibernate.cfg.xml),调用代码:Configuration cfg = new Configuration().configure();
-
-
该实现类两个功能
-
Session:也是一个接口,继承了SessionFactory,Session是Hibernate持久操作的基础核心,可以简单的理解为之前jdbc里的connection对象。
- Session的创建(依靠SessionFactory,sessionFactory对象来自configuartion.buildSessionFactory();,而configuartion这个实例化对象来自new Configuration().configure();),Session session = sessionFactory.openSession();代表了一个数据库的连接,有了该session连接,就可对数据库进行操作(crud),故也叫session为持久化管理器。而对数据库的操作,我们需要封装到事务当中,也就是Hibernate的Transaction
- Session是一个轻量级对象,是非线程安全的,通常和一个数据库事务绑定。
-
Transaction:一个接口,它将应用代码从底层的事务实现中抽象出来,是一个JDBC事务或一个JTA事务,可以在配置文件中指定,默认是JDBC事务。
- 调用代码:Transaction tx = session.beginTransaction();
- 使用Hibernate进行操作时,必须显式的调用Transaction(默认:autoCommit=false)
类图:
再介绍下Query与Criteria接口
Query接口,允许程序员在数据库上执行查询并控制查询如何执行,查询语句使用Hibernate的HQL或本地数据库的SQL,调用代码:Query query = session.createQuery(“from User”);
Criteria接口,是传统SQL的对象化表示,调用代码:Criteria criteria = session.createCriteria(Tuser.class);
结构如图:
代码如下:
整个项目结构
运行结果正确,数据成功插入;Hibernate: insert into user (username, password, userId) values (?, ?, ?)
2016-02-02 23:22:30,202 | INFO | main | dashuai.dao.UserDao.main(UserDao.java:47) | transaction.commit(); ok
2016-02-02 23:22:30,207 | INFO | main | dashuai.dao.UserDao.main(UserDao.java:57) | session.close(); ok
小结:持久化类和关系数据库的映射
说说POJO和JavaBean的区别?
前面简单说了POJO是什么——普通Java类,具有一部分getter/setter方法的那种类就可以称作POJO,理想地讲,一个POJO是一个不受任何限制的Java对象(除了Java语言规范)。例如一个POJO不应该是
- 扩展预定的类
- 实现预定的接口
- 包含预定的标注,如 @javax.ejb.Entity public class Baz{ ...
但是JavaBean则比 POJO复杂很多,JavaBean 是可复用的组件,JavaBean 并没有严格的规范,理论上讲,任何一个 Java 类都可以是一个 Bean 。但通常情况下,由于 JavaBean 是被容器所创建(如 Tomcat) 的,所以 JavaBean 应具有一个无参的构造器,另外,通常 JavaBean 还要实现 Serializable 接口用于实现 Bean 的持久性。JavaBean 是不能被跨进程访问的。
那么为什么需要JavaBean?
因为Java欠缺属性、事件、多重继承功能。所以在Java中实现一些面向对象编程的常见需求,只能手写大量胶水代码。JavaBean正是编写这套胶水代码的惯用模式或约定。对它最简单的理解是数据包,这个数据包里包含了一些信息(属性),比如名称,性别等,包含了可以给这些属性赋值和取值的方法(get和set方法)。通过实例化后的赋值操作,可在别的地方通过get方法把值取出来。这就是javabean,或者叫vo。如果在方法中含有了一些逻辑,比如getName的时候,要给name前面加上公司名称……通常情况下,就叫做bo。而数据库的表对应的持久化类一般叫POJO,这些东西都可以统称为javaBean,核心就是赋值(set)和取值(get)。如果需要用到读写硬盘的缓存,需要网络传输……则需要序列化这个javaBean.实现Serializable接口。
《spring in action》书里详细说到:
JavaBean :是公共Java类,但是为了编辑工具识别,需要满足至少三个条件:
- 有一个public默认构造器(例如无参构造器)
- 属性使用public 的get,set方法访问,也就是说属性设置成private,同时get,set方法与属性名的大小也需要对应。例如属性name,get方法就要写成,public String getName(){},N大写。
- 需要序列化。这个是框架,工具跨平台反映状态必须的
-
重写hashcode和equals方法(可选)……
……
- 在java1996年发布,当年12月即发布了java bean1.00-A,有什么用呢?这样java对象可以重用和统一操作,例如原来说的awt组件(例如一个点point(x,y),IDE可以自动展现它的状态量x,y给你配置,).这就是javaBean的来历,
- 在实际企业开发中,需要实现事务,安全,分布式,javabean就不好用了.sun公司就开始往上面堆功能,堆成了一个加强版的javaBean,这就是EJB的来历;
- EJB功能强大,但是太重了,很多时候都是杀鸡用牛刀!此时编程技术有了一定进展,就是DI(依赖注入),AOP(面向切面),开发者现在可以通过很简单的javaBean也能完成EJB的事情了。
- Spring诞生了.