Hibernate是一个开放源代码的对象关系映射框架(ORM),它对JDBC进行了非常轻量级的对象封装,简化了java应用程序与数据库交互的开发。简化了数据创建,数据处理和数据访问。
对象关系映射(Object Relational Mapping,简称ORM),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
把对象表示的映射到基于SQL的关系模型数据库结构中去。在具体的操作实体对象的时候,就不需要再去和复杂的 SQ L 语句打交道,只需简单的操作实体对象的属性和方法。ORM 技术是在对象和关系之间提供了一条桥梁,对象型数据和数据库中的关系型的数据通过这个桥梁来相互转。
ORM技术特点:
Hibernate架构包括许多对象持久对象,会话工厂,事务工厂,连接工厂,会话,事务等。hibernate架构中有4层Java应用层,持久层,hibernate映射层和数据库层。
需要引入hibernate的核心包和数据库连接包。只要到maven公库就能找到相应的jar包。我使用的以下版本:
package org.ssh1.entity;
import java.util.Date;
/**
* 用来封装数据的实体类
*
* @author lee
*
*/
public class User {
private int id;
private String name;
private Date birthday;
//默认构造器
public User() {};
public int getId(){
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
映射文件的名称必须和实体类一样,以 .hbm.xml
结尾。例如上面实体类的映射文件则为 User.hbm.xml 。
<hibernate-mapping package="org.ssh1.entity">
<class name="User" table="user">
<id name="id" type="int">
<column name="id" />
<generator class="native" />
id>
<property name="name" type="java.lang.String">
<column name="name" />
property>
<property name="birthday" type="java.util.Date">
<column name="birthday" />
property>
class>
hibernate-mapping>
PS:实体类和映射文件必须在同一个包下面
PSPS : 实体类的成员变量 和 数据库的字段 名称可以不一样。
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driverproperty>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernateproperty>
<property name="hibernate.connection.username">rootproperty>
<property name="hibernate.connection.password">qwertyuioproperty>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialectproperty>
<property name="hibernate.show_sql">trueproperty>
<mapping resource="org/ssh1/entity/User.hbm.xml">mapping>
session-factory>
hibernate-configuration>
到了这里基本配置已经完成了。现在我们尝试使用hibernate来想数据库,保存一个对象到数据库中。
在使用hibernate前,我们先了解相关的API。
package org.ssh1.dao;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import org.ssh1.entity.User;
public class Dao {
@Test
public void dao() {
//创建Configuratiion对象
Configuration config = new Configuration();
//加载配置文件
//(默认加载 src下的 hibernate.cfg.xml文件,也可以传入路径参数,加载其他的配置文件)
config.configure();
//创建一个Session工厂类
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = null;
Transaction trans = null;
try {
//创建一个会话
session = sessionFactory.openSession();
//开启事务
trans = session.beginTransaction();
//创建一个User对象,并添加一些信息
User user = new User();
user.setName("yang");
user.setBirthday(new Date());
//保存对象
//在这里我们可以看到,hibernate封装后的数据库操作,是以对象的形式来操作的
//不需要写任何的sql语句
session.save(user);
//提交事务
trans.commit();
}catch(Exception e) {
//出现异常,事务回滚
trans.rollback();
throw new RuntimeException(e);
}finally {
//关闭会话
session.close();
}
}
}
可以看到正确执行了,保存一个User对象到数据库中。hibernate,使程序脱离了繁琐的 JDBC的操作,以操作对象的形式来操作数据库。
PS:可能出现的异常:
Field ‘id’ doesn’t have a default value
数据库表中的主键没设置自动增长。也可以将主键的配置
改为
。
assigned是指主键是由人工分配的,native则指主键值由库自动给出。
这里主要讲解如何使用 Session的方法来操作数据库。(相关的映射文件、配置文件、实体类、数据库和上面一样。)
package org.ssh1.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* hibernate工具类
*
* @author lee
*
*/
public class HibernateUtils {
public static SessionFactory sessionFactory ;
static {
Configuration config = new Configuration();
config.configure();
sessionFactory = config.buildSessionFactory();
}
public static Session openSession() {
return sessionFactory.openSession();
}
}
package org.ssh1.dao;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import org.ssh1.entity.User;
import org.ssh1.utils.HibernateUtils;
/**
* 相关的hibernate API 使用
*
* @author lee
*
*/
public class Dao {
//1、save 保存对象(数据)方法
@Test
public void testSave(){
Session session = null;
Transaction trans = null;
try {
session = HibernateUtils.openSession();
trans = session.beginTransaction();
//因为id主键为自动增长,因此不需要指定id属性
User user = new User();
user.setName("qing");
user.setBirthday(new Date());
System.out.println("1、将一个对象保存到数据库当中:");
session.save(user);
trans.commit();
}catch(Exception e){
trans.rollback();
throw new RuntimeException(e);
}finally {
session.close();
}
}
//2、update 更新对象(数据)方法
@Test
public void testUpdate(){
Session session = null;
Transaction trans = null;
try {
session = HibernateUtils.openSession();
trans = session.beginTransaction();
//更新必须要有主键,当成员变量为null的时候,也会将对应的字段更新为null
//例如:下面的User对象没有设置 birthday属性,当执行更新操作,可以看到该条数据的birthday字段为null
User user = new User();
user.setId(100);
user.setName("xiao");
System.out.println("2、将指定id值的对象 更新到数据库中:");
session.update(user);
trans.commit();
}catch(Exception e){
trans.rollback();
throw new RuntimeException(e);
}finally {
session.close();
}
}
//3、get 获取对象(数据)方法 (主键查询)
@Test
public void testGet(){
Session session = null;
Transaction trans = null;
try {
session = HibernateUtils.openSession();
trans = session.beginTransaction();
//要查询对象(数据)的 id值
int id = 1;
System.out.println("3、根据 id 值获取指定的对象(数据):");
User user = session.get(User.class, id);
trans.commit();
}catch(Exception e){
trans.rollback();
throw new RuntimeException(e);
}finally {
session.close();
}
}
//4、load 获取对象(数据)方法 (主键查询)(懒加载,就是用到时才会去查询。)
@Test
public void testLoad(){
Session session = null;
Transaction trans = null;
try {
session = HibernateUtils.openSession();
trans = session.beginTransaction();
//要查询对象(数据)的 id值
int id = 1;
System.out.println("4、根据 id 值获取指定的对象(数据):");
User user = session.load(User.class, id);
user.getName();//这时候才会去数据库中查找数据(懒加载)
trans.commit();
}catch(Exception e){
trans.rollback();
throw new RuntimeException(e);
}finally {
session.close();
}
}
//5、saveOrUpdate 保存或更新对象(数据)方法
@Test
public void testSaveOrUpdate(){
Session session = null;
Transaction trans = null;
try {
session = HibernateUtils.openSession();
trans = session.beginTransaction();
//当该 对象的id值对应的数据,在数据库中存在时,则更新对象
//当该 对象没有设置id值 ,或id值对应的数据,在数据库中不存在时,则保存对象
User user = new User();
user.setId(99);
System.out.println("5、保存或更新一个对象(数据):");
session.saveOrUpdate(user);
trans.commit();
}catch(Exception e){
trans.rollback();
throw new RuntimeException(e);
}finally {
session.close();
}
}
//6、delete 删除对象(数据)方法
@Test
public void testSaveOrUpdate(){
Session session = null;
Transaction trans = null;
try {
session = HibernateUtils.openSession();
trans = session.beginTransaction();
//以传入一个id值来删除指定的对象(数据)
int id = 88;
System.out.println("6、删除一个对象(数据):");
session.delete(id);
trans.commit();
}catch(Exception e){
trans.rollback();
throw new RuntimeException(e);
}finally {
session.close();
}
}
}
测试运行一下,可以看到结果:
hibernate的查询方式常见的主要分为三种: HQL查询,QBC(Criteria)查询,以及使用原生SQL查询。
HQL(Hibernate Query Language)是hibernate提供的面向对象的查询语言,在HQL中使用类名,而不是表名。所以是数据库独立的查询语言。
HQL查询提供了更加丰富的和灵活的查询特性,因此Hibernate将HQL查询方式立为官方推荐的标准查询方式,HQL查询在涵盖Criteria查询的所有功能的前提下,提供了类似标准SQL语句的查询方式,同时也提供了更加面向对象的封装。
HQL有很多优点。 它们如下:
HQL查询主要是调用 Query对象的方法来实现。Query的对象可以通过Session接口调用createQuery()方法。常用的方法有:
//获取一个Query对象
Query query = session.creaeteQuery("HQL语句");
//将获取的结果作为列表返回
public List list()
//指定从哪里检索数据
public Query setFirstResult(int rowno)
//指定从表中检索数据的行数
public Query setMaxResult(int rowno)
//设置占位符的值
public Query setParameter(int position, Object value)
//设置占位符的值
public Query setParameter(String name, Object value)
这里,我们介绍下一些常用的查询。
(查询所有、条件查询)(单个字段查询、单列查询、多列查询)(统计查询、分页查询)
package org.ssh1.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.Query;
import org.junit.Test;
import org.ssh1.entity.User;
import org.ssh1.utils.HibernateUtils;
/**
* 常用的HQL查询
*
* @author lee
*
*/
public class Dao {
//1、查询所有
@Test
public void getAll() {
Session session = null;
Transaction trans = null;
try {
session = HibernateUtils.openSession();
trans = session.beginTransaction();
/*
* 类似于SQL语句,但是通过操作对象来实现的。
* 例如,"from User" 中,"User" 不是数据表的名称,而是实体类的名称。
* 相对于sql语句 (select * from user) 来,还可以略写 "select * "
*
*/
//HQL语句 ,获取所有的 User对象
String HQL = "from User";
//创建一个Query类
@SuppressWarnings("unchecked")
Query query = session.createQuery(HQL);
//将获取的结果作为列表返回
List users = query.list();
//输出从数据库获得的结果
System.out.println(users);
trans.commit();
}catch(Exception e) {
trans.rollback();
throw new RuntimeException(e);
}finally {
session.close();
}
}
//2、条件查询
@Test
public void getPart() {
Session session = null;
Transaction trans = null;
try {
session = HibernateUtils.openSession();
trans = session.beginTransaction();
/**
* 这里还有很多的条件查询,这里只是作为一个举例
*
*/
//HQL语句 ,获取字段 name为指定的值的 User对象
String HQL = "from User where name = ?";
//创建一个Query类
@SuppressWarnings("unchecked")
Query query = session.createQuery(HQL);
//设置第 1 个占位符的值(从0开始)
query.setParameter(0, "lee");
//query.setParameter("name","lee")//这种形式也是允许的
//获取 单一的一个 查询到的数据
User user = query.uniqueResult();
//输出从数据库获得的结果
System.out.println(user);
trans.commit();
}catch(Exception e) {
trans.rollback();
throw new RuntimeException(e);
}finally {
session.close();
}
}
//3、单个字段查询
@Test
public void getSingleProperty() {
Session session = null;
Transaction trans = null;
try {
session = HibernateUtils.openSession();
trans = session.beginTransaction();
/**
* 这里还有很多的单个字段查询,这里只是作为一个举例
*
*/
//HQL语句 ,获取指定 id值的对象的 name字段
String HQL = "select u.name from User u where id = ?";
//创建一个Query类
@SuppressWarnings("unchecked")
Query query = session.createQuery(HQL);
//设置第 1 个占位符的值(从0开始)
query.setParameter(0, 1);
//获取 单一的一个 查询到的数据
String name = query.uniqueResult();
//输出从数据库获得的结果
System.out.println(name);
trans.commit();
}catch(Exception e) {
trans.rollback();
throw new RuntimeException(e);
}finally {
session.close();
}
}
//4、单列查询
@Test
public void getSingleColumn() {
Session session = null;
Transaction trans = null;
try {
session = HibernateUtils.openSession();
trans = session.beginTransaction();
/**
* 这里还有很多的单列查询,这里只是作为一个举例
*
*/
//HQL语句 ,获取所有User对象的 name 字段
String HQL = "select u.name from User u ";
//创建一个Query类
@SuppressWarnings("unchecked")
Query query = session.createQuery(HQL);
//获取 多个查询到list集合
List names = query.list();
//输出从数据库获得的结果
System.out.println(names);
trans.commit();
}catch(Exception e) {
trans.rollback();
throw new RuntimeException(e);
}finally {
session.close();
}
}
//5、多列查询
@Test
public void getColumns() {
Session session = null;
Transaction trans = null;
try {
session = HibernateUtils.openSession();
trans = session.beginTransaction();
/**
* 这里还有很多的多列查询,这里只是作为一个举例
*
*/
//HQL语句 ,获取所有User对象的 name 、id字段
String HQL = "select u.name,u.id from User u ";
//创建一个Query类
@SuppressWarnings("unchecked")
Query