Hibernate
Hibernate 是一个高性能的对象关系型持久化存储和查询的服务,其遵循开源的 GNU Lesser General Public License (LGPL) 而且可以免费下载。
J2EE三层架构
- 表示层(WEB):
代表框架:Struts - 业务逻辑层(service)
代表框架:spring - 持久化层(Dao)
代表框架:hibernate或者Mybatis
我们所用的hibernate框架就处于持久化层,相比Mybatis我更喜欢hibernate,原因有如下几条:
- hibernate是全自动,而mybatis是半自动
- hibernate数据库移植性远大于mybatis
- hibernate拥有完整的日志系统,mybatis则欠缺一些
- 缓存机制上,hibernate要比mybatis更好一些
- hibernate比Mybatis封装度更高
本文使用的开发环境是eclipse
注意:本文开发平台为Linux!!!,
首先肯定是下载eclipse,国外下载地址下载非常慢,所以提供个一个国内镜像下载地址,是清华源的
清华源eclipse下载地址
下载速度快到飞起!!!
下载eclipse的同时我们开始下载hibernate所用的jar包
官网最新版下载地址:
Hibernate官网
但是速度非常慢,所以我把自己下载好的hibernate jar包上传到了我的github上:
github
我这里的版本是5.4.14
在eclipse里安装好JBoss Tools的hibernate插件,安装好后新建项目时会看到
一个hibernate项目,那就安装成功了
现在就可以开始写代码了,我这里的示例是JAVA WEB项目
首先先将刚刚下载的hibernate jar包导入我们的项目目录
需要导入的jar包在hibernate解压目录下的lib目录中,在此目录中我们需要将required目录与jpa-metamodel-generator目录下的所有jar包导入项目,然后还要将mysql(也可以是其他数据库)官方提供的用于连接数据库的jar包也导入进来,hibernate本身没有的,所以需要我们单独在去下载,然后导入到我的WEB项目中的WEB_INF/lib目录下
然后要记得吧这些jar包要include进去,光是复制进来是没用的
然后我在mysql数据库中新建一个表此表位于CppFastSolution库中,插入内容
现在开始写一个类,因为在hibernate中会对数据库表进行映射,他会将一个表对应到一个持久化类上,所以我们还需要写一个类,我这里吧这个类写到src目录下
代码:
package cn.CFS.sql;
public class CUserInfo {
private long userId;
private String Passwd;
private String userName;
private String email;
private int sex;
private String birthday;
private String regtime;
private String userURL;
private String work;
private String home;
private int jingyan;
private int level;
private int Money;
private String jihuoStatus;
public void setUserId(long userId) {
this.userId = userId;
}
public void setPasswd(String passwd) {
this.Passwd = passwd;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void setEmail(String email) {
this.email = email;
}
public void setSex(int sex) {
this.sex = sex;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public void setRegtime(String regtime) {
this.regtime = regtime;
}
public void setUserURL(String userURL) {
this.userURL = userURL;
}
public void setWork(String work) {
this.work = work;
}
public void setHome(String home) {
this.home = home;
}
public void setJingyan(int jingyan) {
this.jingyan = jingyan;
}
public void setLevel(int level) {
this.level = level;
}
public void setMoney(int money) {
this.Money = money;
}
public void setJihuoStatus(String jihuoStatus) {
this.jihuoStatus = jihuoStatus;
}
public long getUserId() {
return userId;
}
public String getPasswd() {
return Passwd;
}
public String getUserName() {
return userName;
}
public String getEmail() {
return email;
}
public int getSex() {
return sex;
}
public String getBirthday() {
return birthday;
}
public String getRegtime() {
return regtime;
}
public String getUserURL() {
return userURL;
}
public String getWork() {
return work;
}
public String getHome() {
return home;
}
public int getJingyan() {
return jingyan;
}
public int getLevel() {
return level;
}
public int getMoney() {
return Money;
}
public String getJihuoStatus() {
return jihuoStatus;
}
}
我这里类的一个属性与表中的一个字段对应,且名称我设置的也完全一样,类名也与表名一致,其实不一样也可以,他主要是在xml文件中设置对表的映射,所以等会的xml配置文件中对应关系没错就可以了,设置完类属性后要分别设置属性的set,get方法以便我们获取或设置字段值
现在来设置映射xml文件,此文件的保存位置与名称没有限制,因为他并不会直接加载,而是通过一个hibernate的核心配置类加载的,但是按照官方的标准要求,这个映射文件的名称应该为:“文件名.hbm.xml”
我选择在刚才的持久化类所在的包下新建一个xml文件,现在要设置映射文件的dtd约束
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
这样约束就设置好了,现在开始编写映射文件的主体部分,
步骤大概是:
- 首先根标签是
<hibernate-mapping></hibernate-mappin>
- 然后是
<class></class>
标签,在此标签内设置对表与持久化类的对应关系 - 其次是主键的设置
<id></id>
此标签内设置主键唯一性约束,以及字段与持久化类属性的对应关系等,主键唯一性约束此使用<generator></generator>
标签完成 - 然后是普通字段设置,使用
<property/>
标签完成,此标签内同样要设置字段与持久化类属性的对应关系
下面分开细说下每个标签中要用到的属性值:
<hibernate-mapping>
此标签内有一个package属性她的值可以是持久化类所在的包
<class>
此标签内有name与table属性,name属性设置为持久化类完整类名,也就是"包名+类名"的完整类名,切记一定是完整类名,table属性设置持久化类所对应的表
<id>
此标签内有name与column属性,name为持久化类中与与主键所对应的类属性名,column为主键字段名
<generator>
此标签内有一个class属性,此属性可以有许多值,详情可自行百度查看,通常吧此属性设置为native
<property>
此标签内有name与column两个属性,也是用于设置表内字段与持久化类对应关系的
完整映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.CFS.sql">
<!-- 建立类与表的对应关系 -->
<class name="cn.CFS.sql.CUserInfo" table="CUserInfo">
<!-- 主键字段 -->
<id name="userId" column="userId">
<generator class="native"/>
</id>
<!-- 常规字段 -->
<property name="Passwd" column="Passwd"/>
<property name="userName" column="userName"/>
<property name="email" column="email"/>
<property name="sex" column="sex"/>
<property name="birthday" column="birthday"/>
<property name="regtime" column="regtime"/>
<property name="userURL" column="userURL"/>
<property name="work" column="work"/>
<property name="home" column="home"/>
<property name="jingyan" column="jingyan"/>
<property name="level" column="level"/>
<property name="Money" column="Money"/>
<property name="jihuoStatus" column="jihuoStatus"/>
</class>
</hibernate-mapping>
然后开始编写hibernate核心配置文件,此文件的位置固定为src文件夹下,名称固定为hibernate.cfg.xml不能有不同
此文件内分别设置:数据库的登录信息,其他可选的配置信息,映射文件设置
首先登录信息必须设置必不可少,里面包括登录地址,用户名与密码
<!--设置数据库驱动-->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!--设置数据库链接地址-->
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/CppFastSolution
</property>
<!--设置数据库登录用户名与密码-->
<property name="hibernate.connection.username">用户名</property>
<property name="hibernate.connection.password">密码</property>
此处要说明的是<property>
标签的name属性值是固定的,不同的数据库她的值可能略有不同,具体内容可找到hibernate解压目录下的hibernate.properties文件,找到自己所用的数据库,那里面有需要设置的值,在我github里上传的压缩包中,我直接将hibernate.properties文件放到了doc目录中,可直接查看不需要在搜索查找
然后是可选的其他设置,在这块可设置是否在表不存在的情况下自动创建表(是的hibernate就是这么强!),也可以设置数据库方言等其他信息,不过这块的设置是可选的,不设置也可以
<!-- 配置数据库方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
自动创建表的设置值也可以在hibernate.properties文件中找到,就是被我选中的这块
本篇先不细说自动创建表的操作
然后就是最重要的,设置映射文件
<!-- 加载映射文件 -->
<mapping resource="cn/CFS/sql/sqlrun.hbm.xml"/>
要注意的是resource属性中要设置的是映射文件的路径而不是以点隔开的包名
最后要说明的是以上配置要全部放进<session-factory>
标签中,而<session-factory>
标签要放进<hibernate-configuration>
,另外核心配置文件的dtd约束设置也与刚刚的映射文件略有不同
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
完整代码
<?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核心配置文件 -->
<hibernate-configuration>
<session-factory>
<!-- 数据库信息配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/CppFastSolution
</property>
<property name="hibernate.connection.username">用户名</property>
<property name="hibernate.connection.password">密码</property>
<!-- 配置其他信息 -->
<!-- 配置数据库方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 加载映射文件 -->
<mapping resource="cn/CFS/sql/sqlrun.hbm.xml"/>
</session-factory>
</hibernate-configuration>
下面简单的写一个测试JSP页面看看能不能拿到我刚刚创建好的表CUserInfo的内容,此处的步骤可分为:
- 获取Configuration对象
- 获取SessionFactory对象
- 获取Session,打开事务
- 用面向对象的方式操作数据库
- 关闭事务关闭Session
<%@page import="org.hibernate.Transaction"%>
<%@page import="org.hibernate.Session"%>
<%@page import="cn.CFS.sql.CUserInfo"%>
<%@page import="org.hibernate.SessionFactory"%>
<%@page import="org.hibernate.cfg.Configuration"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<!-- html前端显示部分 -->
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- JSP后端处理部分 -->
<%
//配置对象
Configuration cfg=new Configuration().configure();
//事物对象
Transaction tx=null;
//持久化对象
CUserInfo ci=null;
//session工厂
SessionFactory sessionFactory=null;
//session对象
Session databaseSession=null;
try{
sessionFactory=cfg.buildSessionFactory();
databaseSession=sessionFactory.openSession();
tx=databaseSession.beginTransaction();
ci=(CUserInfo)databaseSession.get(CUserInfo.class, 1000L);
//提交事物
tx.commit();
}catch(Exception e){
%>
<%="Error:" %>
<h1><%= e.getMessage() %></h1>
<%
}
//如果查询不到数据则持久化对象为空
if(ci!=null){
String name=ci.getUserName();
%>
<%=ci.getUserName() %>
<%
}
else{
%>
<%="无数据" %>
<%
}
//关闭session
databaseSession.close();
%>
</body>
</html>
此处因为我已经往表里插入了数据,故此篇不演示插入操作,只简单的演示一下读取操作,此处只简单的获取指定userId中userName字段的值,我们看看结果
与数据库表中一致