hibernate是orm框架,他的出现使程序员从繁重的orm工作中解放出来,直接操作对象,就可以实现实体对象与数据库之间的增删改查等操作。
hibernate的使用,需要我们提供实体和表对应的映射配置文件即xxx.hbm.xml,另外,我们需要操作连接数据库,还需要数据库配置相关的文件hibernate.cfg.xml,他们两个都可以放在resources目录下,一般情况下xxx.hbm.xml配置文件和实体放在一个目录下。
xxx.hbm.xml配置文件中,我们需要指定实体所在的包,需要指定实体类名对应的数据库的表明,以及实体属性对应数据表字段名。有了这种对应关系,我们操作实体,就好比在操作表。在原始的jdbc中,我们需要编写sql来做增删改查,在hibernate中,我们也可以支持原生的sql,但是大多数情况下,不是很复杂的查询,我们一般使用hibernate提供的类sql,即hql。比如:
String hql="from User";
这句hql对应的就是sql:select * from xx_user。
hibernate.cfg.xml是连接数据库的配置文件,在这里,我们可以配置数据库连接相关的属性:
connection.driver_class
connection.url
connection.username
connection.password
除此之外,我们可以配置
show_sql:是否显示运行的sql语句,在开发阶段我们设置为true,可以很好的帮助我们找到sql异常。
format_sql:是否格式化sql语句。
hbm2ddl.auto:自动创建表结构。
最后,hibernate.cfg.xml配置文件需要将实体类映射文件全部引入进来。
<mapping resource="com/xxx/hibernate4/entity/user.hbm.xml"/>
Java中使用hibernate,hibernate为我们提供了SessionFactory、Session等api,调用session.save(),session.update(),
session.get(),session.delete()等一系列方法就可以实现增删改查操作了,hibernate为我们封装了这些实现,我们只需要调用相关方法就可以实现jdbc时代复杂的statement转换操作了,确实方便了不少。
这里以maven工程为例,使用hibernate-core-4.3.10.Final版本的hibernate:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.10.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
建立实体类:
BaseEntity.java
package com.xxx.hibernate4.entity;
import java.io.Serializable;
import java.util.Date;
public class BaseEntity implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
protected Integer id;
protected Date createDate;
protected Date modifyDate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
User.java
package com.xxx.hibernate4.entity;
public class User extends BaseEntity {
/**
*
*/
private static final long serialVersionUID = 1L;
private String username;
private String password;
private String mobile;
private int age;
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 getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password +
", mobile=" + mobile + ", age=" + age + ", id="
+ id + "]";
}
}
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 package="com.xxx.hibernate4.entity">
<class name="User" table="xx_user">
<id name="id" type="int">
<generator class="increment" />
</id>
<property name="username" column="username"/>
<property name="password" column="password"/>
<property name="age" column="age"/>
<property name="mobile" column="mobile"/>
<property name="createDate" column="createdate"/>
<property name="modifyDate" column="modifydate"/>
</class>
</hibernate-mapping>
这里有必要说明一下的就是hibernate id generator,是用来生成主键的,生成主键的方式这里采用的是increment,自动增长,采用自动增长的方式,需要id类型为long,int,short等类型。另外几种常见的主键生成策略是:
identity:数据库生成主键的方式,也是一种自动增长的策略,由数据库自动增长来实现。
native:由数据库底层决定使用何种策略,适用于多种数据库实例的场景,比如有mysql,oracle,postgres混合使用的。
uuid:适用于string类型的ID生成策略。
sequence:适用于支持序列的数据库,mysql不支持序列,所以不能支持这种策略。
hibernate.cfg.xml
<?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="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql:///hibernate4?useUnicode=true&characterEncoding=UTF-8</property>
<property name="connection.username">hadoop</property>
<property name="connection.password">hadoop</property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQL57InnoDBDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="com/xxx/hibernate4/entity/user.hbm.xml"/>
</session-factory>
</hibernate-configuration>
至此,所有的准备工作已经做完了,我们需要编写测试方法来测试hibernate。
单独使用hibernate,需要手动编码创建SessionFactory ,有了SessionFactory,就有了Session,这样我们就可以方便的进行增删改查了。
package com.xxx.hibernate4;
import java.util.Date;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.xxx.hibernate4.entity.BaseEntity;
import com.xxx.hibernate4.entity.User;
@SuppressWarnings("deprecation")
public class App {
public static SessionFactory sessionFactory;
public static final ThreadLocal<Session> session = new ThreadLocal<>();
static {
try {
Configuration cfg = new Configuration().configure();
sessionFactory = cfg.buildSessionFactory();
} catch (HibernateException e) {
e.printStackTrace();
System.err.println("Initialize SessionFactory fail "+e);
}
}
public static Session getSession() {
Session sess = (Session)session.get();
if(sess==null) {
sess = sessionFactory.openSession();
session.set(sess);
}
return sess;
}
public static void closeSession() {
Session sess = (Session)session.get();
if(sess!=null) {
sess.close();
}
session.set(null);
sessionFactory.close();
}
public static void add(BaseEntity entity) {
Session sess = getSession();
Transaction tx = sess.beginTransaction();
entity.setCreateDate(new Date());
entity.setModifyDate(new Date());
sess.save(entity);
tx.commit();
closeSession();
}
public static void search(String className) {
Session sess = getSession();
Integer id = 1;
Object object = sess.get(className, id);
System.out.println(object);
closeSession();
}
public static void main( String[] args ){
User user = new User();
user.setUsername("superadmin");
user.setPassword("admin");
user.setAge(20);
user.setMobile("13800126330");
add(user);
//search("com.xxx.hibernate4.entity.User");
}
}
运行打印信息:
在数据库中验证数据:
mysql> select * from xx_user;
+----+------------+----------+-----+-------------+----------------------------+----------------------------+
| id | username | password | age | mobile | createdate | modifydate |
+----+------------+----------+-----+-------------+----------------------------+----------------------------+
| 1 | superadmin | admin | 20 | 13800126330 | 2019-03-18 11:52:38.938000 | 2019-03-18 11:52:38.938000 |
+----+------------+----------+-----+-------------+----------------------------+----------------------------+
1 row in set
运行search("com.xxx.hibernate4.entity.User")方法,查询id=1的user:
在运行第一个插入方法的时候, 我们只是在数据库中建立了hiberate4的数据库,并没有建立表结构。
但是,当我们运行了add()方法之后,我们的数据表自动被hibernate帮我们创建了,是因为我们hibernate.cfg.xml配置了hbm2ddl.auto=update,他表示第一次加载hibernate的时候,会自动根据实体模型model来建立表结构,以后加载hibernate会自动更新表结构(如果字段修改或者增加),不会重复创建表结构。