[Hibernate 框架学习]一、初步体验
前言
上一周大致扫了一遍马士兵老师的 Struts2 教程,而这一周则开始看 Hibernate 的教程了,教程选择了传智播客上的 2016 年的 Hibernate 视频教程,相对来说也比较新。讲解的是 Hibernate 5.x 版本,而目前最新的版本是 Hibernate 5.2.12。
对于我而言,开始改变自己的学习方法。视频教程是四天的课程,不过因为自己平时还要上班,故这一周大概看了一天半的教程,主要是学习一开始怎么使用,可能之后的教程先不去看。而是开始使用 SSH 框架尝试着去做点东西,遇到什么问题再去看相应的教程,这样子可能会更好些。而这一篇便是入门笔记。
环境介绍
- 系统:MacOS High Sierra 10.13.1
- JDK:1.8.0_112
- 开发工具:Eclipse 4.7.1a
- Tomcat 版本:9.0
- Hibernate 版本:5.2.12(官网地址:http://hibernate.org/orm/releases)
- MySQL 驱动:mysql-connector-java-5.1.41-bin.jar
- MySQL 版本:5.7.17
第一个 Hibernate 项目
在视频中是新建 Java 项目,不过在这里我是直接新建了 Web 项目,其实没什么区别。
导入相关的 jar 包
创建相应的数据库
相关的实体类
Hibernate 配置文件
编写测试类测试
导入相关 jar 包
将官网下载的压缩包解压,拷贝压缩包中 required 文件夹下的 jar 包和 jpa 文件夹下的 jar 包到项目中
以及拷贝 MySQL 驱动的 jar 包
数据库
创建相应的数据库,这里数据库名为:hibernate_day01
编写实体类
创建包,例如 test.entity,然后在包下创建一个 User.class 类,代码如下
package test.entity;
public class User {
private int uid; // 用户 id
private String username; // 用户名
private String password; // 密码
private String address; // 地址
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Hibernat 配置文件
在这里有两种配置文件,一个配置文件是与实体类对应的映射文件,另一个则是核心配置文件。
Hibernate 映射文件配置
主要是让实体类和数据库中的表对应,类与表对应,类中的属性与表字段对应。
一般来说,映射文件和实体类放在同一目录下,命名为:实体类名称.hbm.xml,例如:User.hbm.xml
配置如下:
<?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>
<!--
1. 配置类和表对应
class 标签
name 属性:实体类全路径
table 属性:数据库表名称
-->
<class name="test.entity.User" table="t_user">
<!--
2. 配置实体类 id 和表 id对应
hibernate 要求实体类有一个属性唯一值
hibernate 要求表有字段作为唯一值
-->
<id name="uid" column="uid">
<!--
设置数据库表 id 增长策略
native:生成表 id 值就是主键自动增长
-->
<generator class="native"></generator>
</id>
<!--
配置其他属性和表字段对应
name 属性:实体类属性名称
column 属性:字段名称
-->
<property name="username" column="username" />
<property name="password" column="password" />
<property name="address" column="address" />
</class>
</hibernate-mapping>
Hibernate 核心配置文件
核心配置文件的名称必须为:hibernate.cfg.xml
核心配置文件存放的位置必须是在 src 下
配置如下:
<?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-configuration>
<session-factory>
<!-- 第一部分:配置数据库信息 必须的 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- <property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01?useUnicode=true&characterEncoding=UTF-8</property> -->
<property name="hibernate.connection.url"> <![CDATA[jdbc:mysql:///hibernate_day01?useUnicode=true&characterEncoding=utf8]]></property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- 第二部分:配置 Hibernate 信息 可选的 -->
<!-- 输出底层 sql 语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 输出底层 sql 语句格式 -->
<property name="hibernate.format_sql">true</property>
<!--
hibernate 帮创建表,需要配置之后
update:如果已经有表,更新;如果没有,帮忙创建表
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--
配置数据库方言
在 MySQL 里面实现分页,关键字 limit,只能在 MySQL 里面使用
在 Oracle 数据库,实现分页使用关键字 rownum
让 Hibernate 框架识别不同数据库的自己特有的语句
-->
<!-- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 第三部分:把映射文件放到核心配置中 必须的 -->
<mapping resource="test/entity/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
测试类
新建包 test.test,在包中新建一个 HibernateTest.java 类。
其中代码如下:
package test.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import test.entity.User;
public class HibernateTest {
public static void main(String[] args) {
// 加载 hibernate 核心配置文件
Configuration cfg = new Configuration();
cfg.configure();
// 创建 SessionFactory 对象
SessionFactory sessionFactory = cfg.buildSessionFactory();
// 使用 SessionFactory 创建 session 对象
Session session = sessionFactory.openSession();
// 开启事务
Transaction tx = session.beginTransaction();
// 写具体逻辑 CRUD 操作
User user = new User();
user.setUsername("test");
user.setPassword("123");
user.setAddress("深圳");
session.save(user);
// 提交事务
tx.commit();
// 关闭资源
session.close();
sessionFactory.close();
}
}
然后运行 main 方法,成功后,则会在数据库中创建对应的表,以及插入对应的数据。
注意,数据库需要自己创建,Hibernate 并不能自动帮忙创建数据库。
遇到的问题
配置数据库方言时的问题
该配置根据自己的情况做了修改。首先是数据库方言配置,注释掉的是视频中的配置,如果使用注释掉的那个配置,则无法实现自动创建表的功能,后台输出的 Hibernate 自动生成的 SQL 语句如下:
Hibernate:
create table t_user (
uid integer not null auto_increment,
username varchar(255),
password varchar(255),
address varchar(255),
primary key (uid)
) type=MyISAM
于是乎改成方言:org.hibernate.dialect.MySQL5Dialect 就可以了。Hibernate 自动生成的 SQL 语句如下:
Hibernate:
create table t_user (
uid integer not null auto_increment,
username varchar(255),
password varchar(255),
address varchar(255),
primary key (uid)
) engine=MyISAM
分析:因为我的 MySQL 版本是 5.7。而老版本的 MySQL 使用 type 而不是 engine,而 5.x 版本的 MySQL 默认使用的是 engine,使用 type 可能出现兼容问题。故需要将方言配置为 MySQL5Dialect。1
中文乱码问题
同样是 Hibernate 核心配置文件那里,配置数据库时,需要设置数据库,配置如下:
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01?useUnicode=true&characterEncoding=UTF-8</property>
则在加载配置文件的时候,会将 & 认为 ; 号,导致错误。所以正确的书写如下[^2]:
<property name="hibernate.connection.url"><![CDATA[jdbc:mysql:///hibernate_day01?useUnicode=true&characterEncoding=utf8]]></property>
后记
视频上虽然也是使用了 5.X 的版本,不过与我使用的版本有点区别。看了视频后,始终还是要尝试着自己动手去操作,有些问题,视频中的老师可能没有遇到,而你遇到了,再自己动手去寻找答案,解决问题。于是乎就有了这一篇 Hibernate 初步体验的文档了。
在实践中成长!
编辑:HochenChong
时间:2017-11-15
参考文献
- MySQL5.6.16数据库中type=MyISAM错误的解决办法.http://blog.youkuaiyun.com/bnxf00000/article/details/22573715
[^2]: 解决hibernate向mysql插入中文乱码问题.http://blog.youkuaiyun.com/peditable/article/details/7047573 ↩