hibernate是一个开源,轻量级的orm(对象关系映射)工具。hibernate框架简化了java应用程序与数据库交互的开发。
orm工具简化了数据创建,数据处理和数据访问。它是将对象映射到数据库中存储的数据(表)的编程技术。
注:为什么会有这篇教程文章?答:只是想写一篇最nb的hibernate教程入门文章。nb代表人见人爱,花见花开,车见爆胎,飞鸟落地…,最后,需要注意的是:这篇文章包教不包会!除非你从头到尾认真看完并运行所有示例代码。
本教程文章基于以下工具(软件):
hibernate.x ~ hibernate.5 更新功能:
从hibernate 5.0开始hibernate spatial是hibernate项目的一部分,因此我们也可以处理gis数据了。
域模型映射支持java 8日期和时间类型。 标准sql日期/时间类型以及支持的java 8 date
/ time
类类型之间的映射,如下所示:
java.time.localdate
java.time.localtime
, java.time.offsettime
java.time.instant
, java.time.localdatetime
,java.time.offsetdatetime
和 java.time.zoneddatetime
字节码增强机制从头重新设计,hibernate可支持maven和gradle插件。可以通过字节码仪器来增强三个主要方面:
lazy
,只有在第一次被访问时,它们才被提取。hibernate的原生api(session等)已更新为使用泛型类型化。无需在获取实体时转换。
hibernate 5.0
将其扩展到更广泛的类型(例如uuid
)。hibernate是一个库,为了处理所有类型的数据库,它不依赖于应用程序选择的任何类型的数据库,如果java是“一次写入到处运行”的语言,hibernate则是“写一次就可运行在所有类型的数据库“中的框架。
在这篇文章中,使用的是mysql数据(你可使用其它的数据库,如:oracle,mysql或sql server),并创建一个简单的数据库:mydb
,完整的数据库创建语句如下所示:
创建数据:
create database if not exists mydb default charset utf8 collate utf8_general_ci;
需要创建以下几张表,它们的关系图如下所示 -
创建表语句:
create table department (
dept_id integer not null,
dept_name varchar(255) not null,
dept_no varchar(20) not null,
location varchar(255),
primary key (dept_id),
unique (dept_no)
);
create table employee (
emp_id bigint not null,
emp_name varchar(50) not null,
emp_no varchar(20) not null,
hire_date date not null,
image longblob,
job varchar(30) not null,
salary float not null,
dept_id integer not null,
mng_id bigint,
primary key (emp_id),
unique (emp_no)
);
create table salary_grade (
grade integer not null,
high_salary float not null,
low_salary float not null,
primary key (grade)
);
create table timekeeper (
timekeeper_id varchar(36) not null,
date_time datetime not null,
in_out char(1) not null,
emp_id bigint not null,
primary key (timekeeper_id)
);
alter table employee
add index fk75c8d6ae269a3c9 (dept_id),
add constraint fk75c8d6ae269a3c9
foreign key (dept_id)
references department (dept_id);
alter table employee
add index fk75c8d6ae6106a42 (emp_id),
add constraint fk75c8d6ae6106a42
foreign key (emp_id)
references employee (emp_id);
alter table employee
add index fk75c8d6ae13c12f64 (mng_id),
add constraint fk75c8d6ae13c12f64
foreign key (mng_id)
references employee (emp_id);
alter table timekeeper
add index fk744d9bff6106a42 (emp_id),
add constraint fk744d9bff6106a42
foreign key (emp_id)
references employee (emp_id);
向上面创建的表中,分别插入一些测试数据,如下所示 -
insert into department (dept_id, dept_name, dept_no, location)
values (10, 'accounting', 'd10', 'new york');
insert into department (dept_id, dept_name, dept_no, location)
values (20, 'research', 'd20', 'dallas');
insert into department (dept_id, dept_name, dept_no, location)
values (30, 'sales', 'd30', 'chicago');
insert into department (dept_id, dept_name, dept_no, location)
values (40, 'operations', 'd40', 'boston');
-------------------------------------------------------------------------------------------------
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7839, 'king', 'e7839', str_to_date('17-11-1981', '%d-%m-%y'), 'president', 5000, 10, null);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7566, 'jones', 'e7566', str_to_date('02-04-1981', '%d-%m-%y'), 'manager', 2975, 20, 7839);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7902, 'ford', 'e7902', str_to_date('03-12-1981', '%d-%m-%y'), 'analyst', 3000, 20, 7566);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7369, 'smith', 'e7369', str_to_date('17-12-1980', '%d-%m-%y'), 'clerk', 800, 20, 7902);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7698, 'blake', 'e7698', str_to_date('01-05-1981', '%d-%m-%y'), 'manager', 2850, 30, 7839);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7499, 'allen', 'e7499', str_to_date('20-02-1981', '%d-%m-%y'), 'salesman', 1600, 30, 7698);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7521, 'ward', 'e7521', str_to_date('22-02-1981', '%d-%m-%y'), 'salesman', 1250, 30, 7698);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7654, 'martin', 'e7654', str_to_date('28-09-1981', '%d-%m-%y'), 'salesman', 1250, 30, 7698);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7782, 'clark', 'e7782', str_to_date('09-06-1981', '%d-%m-%y'), 'manager', 2450, 30, 7839);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7788, 'scott', 'e7788', str_to_date('19-04-1987', '%d-%m-%y'), 'analyst', 3000, 20, 7566);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7844, 'turner', 'e7844', str_to_date('08-09-1981', '%d-%m-%y'), 'salesman', 1500, 30, 7698);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7876, 'adams', 'e7876', str_to_date('23-05-1987', '%d-%m-%y'), 'clerk', 1100, 20, 7698);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7900, 'adams', 'e7900', str_to_date('03-12-1981', '%d-%m-%y'), 'clerk', 950, 30, 7698);
insert into employee (emp_id, emp_name, emp_no, hire_date, job, salary, dept_id, mng_id)
values (7934, 'miller', 'e7934', str_to_date('23-01-1982', '%d-%m-%y'), 'clerk', 1300, 10, 7698);
-------------------------------------------------------------------------------------------------
insert into salary_grade (grade, high_salary, low_salary)
values (1, 9999, 3001);
在这里,创建一个maven项目并在pom.xml
中声明使用的hibernate
库。打开 eclipse,选择菜单 file -> new -> other…,在弹出框中选择 maven,如下所示 -
下一步选择工作目录,如下图所示 -
下一步,选择模板类型,如下图所示 -
下一步,写入工程名称:hibernatequickstart,以及输入包信息:com.h3
等信息。
项目(hibernatequickstart)创建完成后,如下图所示 -
在pom.xml
中,需要声明使用hibernate 5
库,以及用于各种数据库类型(如oracle,mysql和sql server)的jdbc库,这里使用 mysql jdbc。
完整的 pom.xml 配置/声明如下所示 -
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0</modelversion>
<groupid>com.h3</groupid>
<artifactid>hibernatequickstart</artifactid>
<version>0.0.1-snapshot</version>
<packaging>jar</packaging>
<name>hibernatequickstart</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceencoding>utf-8</project.build.sourceencoding>
</properties>
<dependencies>
<dependency>
<groupid>junit</groupid>
<artifactid>junit</artifactid>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- hibernate core -->
<!-- http://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupid>org.hibernate</groupid>
<artifactid>hibernate-core</artifactid>
<version>5.2.2.final</version>
</dependency>
<!-- mysql jdbc driver -->
<!-- http://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupid>mysql</groupid>
<artifactid>mysql-connector-java</artifactid>
<version>5.1.34</version>
</dependency>
<!-- sqlserver jdbc driver (jtds) -->
<!-- http://mvnrepository.com/artifact/net.sourceforge.jtds/jtds -->
<dependency>
<groupid>net.sourceforge.jtds</groupid>
<artifactid>jtds</artifactid>
<version>1.3.1</version>
</dependency>
</dependencies>
</project>
在这一步中,我们来创建实体类。每个实体描述一个数据库中的表。这里先不说明每个类是做什么用的。一共要创建如下几个实体类(对应上面创建的四张表),如下 -
所有创建的类如下图所示 -
这几个类的代码,分别如下所示 -
department.java 类代码 -
package com.h3.entities;
import java.util.hashset;
import java.util.set;
import javax.persistence.column;
import javax.persistence.entity;
import javax.persistence.fetchtype;
import javax.persistence.id;
import javax.persistence.onetomany;
import javax.persistence.table;
import javax.persistence.uniqueconstraint;
@entity
@table(name = "department", uniqueconstraints = { @uniqueconstraint(columnnames = { "dept_no" }) })
public class department {
private integer deptid;
private string deptno;
private string deptname;
private string location;
private set<employee> employees = new hashset<employee>(0);
public department() {
}
public department(integer deptid, string deptname, string location) {
this.deptid = deptid;
this.deptno = "d" + this.deptid;
this.deptname = deptname;
this.location = location;
}
@id
@column(name = "dept_id")
public integer getdeptid() {
return deptid;
}
public void setdeptid(integer deptid) {
this.deptid = deptid;
}
@column(name = "dept_no", length = 20, nullable = false)
public string getdeptno() {
return deptno;
}
public void setdeptno(string deptno) {
this.deptno = deptno;
}
@column(name = "dept_name", nullable = false)
public string getdeptname() {
return deptname;
}
public void setdeptname(string deptname) {
this.deptname = deptname;
}
@column(name = "location")
public string getlocation() {
return location;
}
public void setlocation(string location) {
this.location = location;
}
@onetomany(fetch = fetchtype.lazy, mappedby = "department")
public set<employee> getemployees() {
return employees;
}
public void setemployees(set<employee> employees) {
this.employees = employees;
}
}
employee.java 类代码 -
package com.h3.entities;
import java.util.date;
import java.util.hashset;
import java.util.set;
import javax.persistence.column;
import javax.persistence.entity;
import javax.persistence.fetchtype;
import javax.persistence.id;
import javax.persistence.joincolumn;
import javax.persistence.lob;
import javax.persistence.manytoone;
import javax.persistence.onetomany;
import javax.persistence.table;
import javax.persistence.temporal;
import javax.persistence.temporaltype;
import javax.persistence.uniqueconstraint;
@entity
@table(name = "employee", uniqueconstraints = { @uniqueconstraint(columnnames = { "emp_no" }) })
public class employee {
private long empid;
private string empno;
private string empname;
private string job;
private employee manager;
private date hidedate;
private float salary;
private byte[] image;
private department department;
private set<employee> employees = new hashset<employee>(0);
public employee() {
}
public employee(long empid, string empname, string job, employee manager, date hidedate, float salary, float comm,
department department) {
this.empid = empid;
this.empno = "e" + this.empid;
this.empname = empname;
this.job = job;
this.manager = manager;
this.hidedate = hidedate;
this.salary = salary;
this.department = department;
}
@id
@column(name = "emp_id")
public long getempid() {
return empid;
}
public void setempid(long empid) {
this.empid = empid;
}
@column(name = "emp_no", length = 20, nullable = false)
public string getempno() {
return empno;
}
public void setempno(string empno) {
this.empno = empno;
}
@column(name = "emp_name", length = 50, nullable = false)
public string getempname() {
return empname;
}
public void setempname(string empname) {
this.empname = empname;
}
@column(name = "job", length = 30, nullable = false)
public string getjob() {
return job;
}
public void setjob(string job) {
this.job = job;
}
@manytoone(fetch = fetchtype.lazy)
@joincolumn(name = "mng_id")
public employee getmanager() {
return manager;
}
public void setmanager(employee manager) {
this.manager = manager;
}
@column(name = "hire_date", nullable = false)
@temporal(temporaltype.date)
public date gethidedate() {
return hidedate;
}
public void sethidedate(date hidedate) {
this.hidedate = hidedate;
}
@column(name = "salary", nullable = false)
public float getsalary() {
return salary;
}
public void setsalary(float salary) {
this.salary = salary;
}
@column(name = "image", length = 1111111, nullable = true)
@lob
public byte[] getimage() {
return image;
}
public void setimage(byte[] image) {
this.image = image;
}
@manytoone(fetch = fetchtype.lazy)
@joincolumn(name = "dept_id", nullable = false)
public department getdepartment() {
return department;
}
public void setdepartment(department department) {
this.department = department;
}
@onetomany(fetch = fetchtype.lazy, mappedby = "empid")
public set<employee> getemployees() {
return employees;
}
public void setemployees(set<employee> employees) {
this.employees = employees;
}
}
salarygrade.java 类代码 -
package com.h3.entities;
import javax.persistence.column;
import javax.persistence.entity;
import javax.persistence.id;
import javax.persistence.table;
@entity
@table(name = "salary_grade")
public class salarygrade {
private integer grade;
private float lowsalary;
private float highsalary;
public salarygrade() {
}
public salarygrade(integer grade, float lowsalary, float highsalary) {
this.grade = grade;
this.lowsalary = lowsalary;
this.highsalary = highsalary;
}
@id
@column(name = "grade")
public integer getgrade() {
return grade;
}
public void setgrade(integer grade) {
this.grade = grade;
}
@column(name = "low_salary", nullable = false)
public float getlowsalary() {
return lowsalary;
}
public void setlowsalary(float lowsalary) {
this.lowsalary = lowsalary;
}
@column(name = "high_salary", nullable = false)
public float gethighsalary() {
return highsalary;
}
public void sethighsalary(float highsalary) {
this.highsalary = highsalary;
}
}
timekeeper.java 类代码 -
package com.h3.entities;
import java.util.date;
import javax.persistence.column;
import javax.persistence.entity;
import javax.persistence.fetchtype;
import javax.persistence.generatedvalue;
import javax.persistence.id;
import javax.persistence.joincolumn;
import javax.persistence.manytoone;
import javax.persistence.table;
import javax.persistence.temporal;
import javax.persistence.temporaltype;
import org.hibernate.annotations.genericgenerator;
@entity
@table(name = "timekeeper")
public class timekeeper {
public static final char in = 'i';
public static final char out = 'o';
private string timekeeperid;
private date datetime;
private employee employee;
// 'i' or 'o'
private char inout;
@id
@generatedvalue(generator = "uuid")
@genericgenerator(name = "uuid", strategy = "uuid2")
@column(name = "timekeeper_id", length = 36)
public string gettimekeeperid() {
return timekeeperid;
}
public void settimekeeperid(string timekeeperid) {
this.timekeeperid = timekeeperid;
}
@column(name = "date_time", nullable = false)
@temporal(temporaltype.timestamp)
public date getdatetime() {
return datetime;
}
public void setdatetime(date datetime) {
this.datetime = datetime;
}
@manytoone(fetch = fetchtype.lazy)
@joincolumn(name = "emp_id", nullable = false)
public employee getemployee() {
return employee;
}
public void setemployee(employee employee) {
this.employee = employee;
}
@column(name = "in_out", nullable = false, length = 1)
public char getinout() {
return inout;
}
public void setinout(char inout) {
this.inout = inout;
}
}
配置hibernate目的是让hibernate可以连接数据库并与数据库交互,并声明在前面的步骤中创建的实体列表。
在src/main/java中创建一个名称为:hibernate.cfg.xml 的配置文件,当前项目结构如下图所示 -
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>
<!-- database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/mydb?servertimezone=utc</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<!-- jdbc connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- sql dialect -->
<property name="dialect">org.hibernate.dialect.mysqldialect</property>
<!-- enable hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.nocacheprovider</property>
<!-- echo all executed sql to stdout -->
<property name="show_sql">true</property>
<mapping class="com.h3.entities.department" />
<mapping class="com.h3.entities.employee" />
<mapping class="com.h3.entities.salarygrade" />
<mapping class="com.h3.entities.timekeeper" />
</session-factory>
</hibernate-configuration>
每种数据库都有一个单独的方言, 例如:
oracle方言:
sql server方言:
mysql方言
dialect
是一个使用hibernate的方式将数据库的数据类型转换为java的数据类型,反之亦然。此外,它用于定义将hsql(hibernate sql)的函数转换为数据中的函数的方式,如下列出的一部分 -
java sql类型 | oracle | mysql | sql server |
---|---|---|---|
types.bit | number(1,0) | bit | bit |
types.bigint | number(19,0) | bigin | bigint |
types.date | date | date | date |
……. | … | … | … |
types.clob | clob | longtext | varchar(max) |
types.blob | blob | longblob | varbinary(max) |
创建一个文件: hibernateutils.java , 其代码如下 -
hibernate使用hibernate查询语言(hql)查询数据。 hql与我们所了解的数据库sql语句有点不同。
sql:
hql:
参考比较以下用法 -
-- sql
-- this is a sql query in table department.
select d.dept_no, d.dept_name from department d;
-- hql
-- this is a hql query in entity department.
select d.deptno, d.deptname from department d;
-- query object
select d from department d;
hibernate的操作规则:
应用程序编写的hql在操作过程中,hibernate本身就意识到它使用的数据库类型(如:mysql),它会自动将hql转换为等价的数据库类型的sql形式。 事实上,各种类型的数据库之间的sql语法有一些差异,比如:返回记录的行数的限制就不同(mysql中使用 limit
子句)。
可以参考hql语法: http://docs.jboss.org/hibernate/orm/3.6/reference/en-us/html/queryhql.html
在hibernate中有很多方法可以用来查询数据。在这部分中,将介绍一些查询数据的典型方法。
查询对象示例-1
第一个例子,使用hql查询对象(entity),创建一个java类文件:queryobjectdemo.java,其代码如下 -
package com.h3;
import java.util.list;
import org.hibernate.query.query;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.hibernateutils;
import com.h3.entities.employee;
public class queryobjectdemo {
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
try {
// all the action with db via hibernate
// must be located in one transaction.
// start transaction.
session.gettransaction().begin();
// create an hql statement, query the object.
// equivalent to the sql statement:
// select e.* from employee e order by e.emp_name, e.emp_no
string sql = "select e from " + employee.class.getname() + " e "
+ " order by e.empname, e.empno ";
// create query object.
query<employee> query = session.createquery(sql);
// execute query.
list<employee> employees = query.getresultlist();
for (employee emp : employees) {
system.out.println("emp: " + emp.getempno() + " : "
+ emp.getempname());
}
// commit data.
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
// rollback in case of an error occurred.
session.gettransaction().rollback();
}
}
}
运行上面代码,得到以下结果 -
查询对象示例-2
创建一个java类文件:queryobjectdemo2.java,其代码如下 -
package com.h3;
import java.util.list;
import org.hibernate.query.query;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.hibernateutils;
import com.h3.entities.employee;
public class queryobjectdemo2 {
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
try {
// all the action with db via hibernate
// must be located in one transaction
// start transaction.
session.gettransaction().begin();
// create an hql statement, query the object.
// hql with parameters.
// equivalent to the sql statement:
// select e.* from employee e cross join department d
// where e.dept_id = d.dept_id and d.dept_no = :deptno;
string sql = "select e from " + employee.class.getname() + " e " + " where e.department.deptno=:deptno ";
// create query object.
query<employee> query = session.createquery(sql);
query.setparameter("deptno", "d10");
// execute query.
list<employee> employees = query.getresultlist();
for (employee emp : employees) {
system.out.println("emp: " + emp.getempno() + " : " + emp.getempname());
}
// commit data
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
// rollback in case of an error occurred.
session.gettransaction().rollback();
}
}
}
运行上面代码,得到以下结果 -
......
org.hibernate.hql.internal.querytranslatorfactoryinitiator initiateservice
info: hhh000397: using astquerytranslatorfactory
hibernate: select employee0_.emp_id ..._no=?
emp: e7839 : king
emp: e7934 : miller
`
创建一个java类文件:querysomecolumndemo.java,其代码如下 -
package com.h3;
import java.util.list;
import org.hibernate.query.query;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.hibernateutils;
import com.h3.entities.employee;
public class querysomecolumndemo {
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
try {
session.gettransaction().begin();
// query some columns.
string sql = "select e.empid, e.empno, e.empname from "
+ employee.class.getname() + " e ";
query<object[]> query = session.createquery(sql);
// execute query.
// get the array of object
list<object[]> datas = query.getresultlist();
for (object[] emp : datas) {
system.out.println("emp id: " + emp[0]);
system.out.println(" emp no: " + emp[1]);
system.out.println(" emp name: " + emp[2]);
}
// commit data.
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
// rollback in case of an error occurred.
session.gettransaction().rollback();
}
}
}
运行上面代码,得到以下结果 -
hibernate: select employee0_.emp_id..._0_ from employee employee0_
emp id: 7369
emp no: e7369
emp name: smith
emp id: 7499
emp no: e7499
emp name: allen
emp id: 7521
emp no: e7521
emp name: ward
emp id: 7566
emp no: e7566
emp name: jones
emp id: 7654
emp no: e7654
emp name: martin
emp id: 7698
emp no: e7698
emp name: blake
emp id: 7782
emp no: e7782
emp name: clark
emp id: 7788
emp no: e7788
emp name: scott
emp id: 7839
emp no: e7839
emp name: king
emp id: 7844
emp no: e7844
emp name: turner
emp id: 7876
emp no: e7876
emp name: adams
emp id: 7900
emp no: e7900
emp name: adams
emp id: 7902
emp no: e7902
emp name: ford
emp id: 7934
emp no: e7934
emp name: miller
`
在这种情况下,如果需要在某些表中提取某些列的数据,最好的方法是使用java bean。使用java bean的构造函数来为不同的字段设置值。在此构造函数加入hql查询。
创建一个java类文件:shortempinfo.java,其代码如下 -
package com.h3;
public class shortempinfo {
private long empid;
private string empno;
private string empname;
//
// constructor have 3 parameters, will be used in the hibernate query.
//
public shortempinfo(long empid, string empno, string empname) {
this.empid = empid;
this.empno = empno;
this.empname = empname;
}
public long getempid() {
return empid;
}
public void setempid(long empid) {
this.empid = empid;
}
public string getempno() {
return empno;
}
public void setempno(string empno) {
this.empno = empno;
}
public string getempname() {
return empname;
}
public void setempname(string empname) {
this.empname = empname;
}
}
创建一个java类文件:shortempinfoquerydemo.java,其代码如下 -
package com.h3;
import java.util.list;
import org.hibernate.query.query;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.hibernateutils;
import com.h3.entities.employee;
public class shortempinfoquerydemo {
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
try {
session.gettransaction().begin();
// using constructor of shortempinfo
string sql = "select new " + shortempinfo.class.getname()
+ "(e.empid, e.empno, e.empname)" + " from "
+ employee.class.getname() + " e ";
query<shortempinfo> query = session.createquery(sql);
// execute query.
// get a list of shortempinfo
list<shortempinfo> employees = query.getresultlist();
for (shortempinfo emp : employees) {
system.out.println("emp: " + emp.getempno() + " : "
+ emp.getempname());
}
// commit data.
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
// rollback in case of an error occurred.
session.gettransaction().rollback();
}
}
}
运行上面代码,得到以下结果 -
创建一个java类文件:uniqueresultdemo.java,其代码如下 -
package com.h3;
import java.util.set;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import org.hibernate.query.query;
import com.h3.entities.department;
import com.h3.entities.employee;
public class uniqueresultdemo {
public static department getdepartment(session session, string deptno) {
string sql = "select d from " + department.class.getname() + " d "//
+ " where d.deptno= :deptno ";
query<department> query = session.createquery(sql);
query.setparameter("deptno", deptno);
return (department) query.getsingleresult();
}
public static employee getemployee(session session, long empid) {
string sql = "select e from " + employee.class.getname() + " e "//
+ " where e.empid= :empid ";
query<employee> query = session.createquery(sql);
query.setparameter("empid", empid);
return (employee) query.getsingleresult();
}
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
try {
session.gettransaction().begin();
department dept = getdepartment(session, "d10");
set<employee> emps = dept.getemployees();
system.out.println("dept name: " + dept.getdeptname());
for (employee emp : emps) {
system.out.println(" emp name: " + emp.getempname());
}
employee emp = getemployee(session, 7839l);
system.out.println("emp name: " + emp.getempname());
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session.gettransaction().rollback();
}
}
}
运行上面代码,得到以下结果 -
在这部分中,使用session.persist(object)
将瞬态对象插入数据库的简单示例。本例中将介绍对象瞬态(transitent),持久(persistent)和分离(detached)的概念。
创建一个java类文件:datautils.java,其代码如下 -
package com.h3;
import org.hibernate.session;
import org.hibernate.query.query;
import com.h3.entities.department;
import com.h3.entities.employee;
public class datautils {
public static department finddepartment(session session, string deptno) {
string sql = "select d from " + department.class.getname() + " d "//
+ " where d.deptno = :deptno";
query<department> query = session.createquery(sql);
query.setparameter("deptno", deptno);
return query.getsingleresult();
}
public static long getmaxempid(session session) {
string sql = "select max(e.empid) from " + employee.class.getname() + " e ";
query<number> query = session.createquery(sql);
number value = query.getsingleresult();
if (value == null) {
return 0l;
}
return value.longvalue();
}
public static employee findemployee(session session, string empno) {
string sql = "select e from " + employee.class.getname() + " e "//
+ " where e.empno = :empno";
query<employee> query = session.createquery(sql);
query.setparameter("empno", empno);
return query.getsingleresult();
}
}
创建一个java类文件:persistdemo.java,其代码如下 -
package com.h3;
import java.util.date;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.entities.department;
import com.h3.entities.employee;
public class persistdemo {
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
department department = null;
employee emp = null;
try {
session.gettransaction().begin();
long maxempid = datautils.getmaxempid(session);
long empid = maxempid + 1;
// get persistent object.
department = datautils.finddepartment(session, "d10");
// create transient object
emp = new employee();
emp.setempid(empid);
emp.setempno("e" + empid);
emp.setempname("name " + empid);
emp.setjob("coder");
emp.setsalary(1000f);
emp.setmanager(null);
emp.sethidedate(new date());
emp.setdepartment(department);
// using persist(..)
// now 'emp' is managed by hibernate.
// it has persistent status.
// no action at this time with db.
session.persist(emp);
// at this step the data is pushed to the db.
// execute insert statement.
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session.gettransaction().rollback();
}
// after the session is closed (commit, rollback, close)
// objects 'emp', 'dept' became the detached objects.
// it is no longer in the control of the session.
system.out.println("emp no: " + emp.getempno());
}
}
运行上面代码,得到以下结果 -
hibernate的session类的有一些/几组的重要方法,如下图所示:
hibernate中的一个对象存在于以下四个状态之中的一种:
以上几个状态在下面图中解释:
下面来看这几个状态的流转说明 -
当从一个实体创建一个新的java对象时,该对象处于“短暂”状态。 hibernate不知道它的存在,因为它独立于hibernate的管理。
如果使用方法:get
,load
或find
获取实体对象,则将获得一个等同于数据库中的1
条记录的对象。 此对象处于persistent状态。 它由hibernate管理。
会话调用方法:save
,saveorupdate
和persist
。 合并将短暂(transient)对象置于hibernate的管理之下,此对象转为持久化(persistent)状态。 在使用的具体情况下,它向数据库插入或更新数据。
session
调用evict(..)
或clear()
,以便从处于hibernate管理状态的对象处于关闭状态,并且这些对象处于分离(detached
)的状态。
使用update(..)
,saveorupdate(..)
,merge(..)
将有助于重新连接分离对象。 在具体情况下,它会向数据库中创建更新或插入数据。 对象转回持久化(persistent)状态。
session
调用方法:remove(..)
,delete(..)
删除除记录并持久化对象。
当一个对像使用 session
的get()
,load()
,find()
方法获取关联数据时,它处于持久化(persistent)状态。
创建一个java类文件:persistentdemo.java,用于演示对象的持久化(persistent)状态。
package com.h3;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.entities.department;
import com.h3.entities.employee;
public class persistentdemo {
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
department department = null;
try {
session.gettransaction().begin();
system.out.println("- finding department deptno = d10...");
// persistent object.
department = datautils.finddepartment(session, "d10");
system.out.println("- first change location");
// changing something on persistent object.
department.setlocation("chicago " + system.currenttimemillis());
system.out.println("- location = " + department.getlocation());
system.out.println("- calling flush...");
// use session.flush () to actively push the changes to the db.
// it works for all changed persistent objects.
session.flush();
system.out.println("- flush ok");
system.out.println("- second change location");
// change something on persistent object
department.setlocation("chicago " + system.currenttimemillis());
// print out location
system.out.println("- location = " + department.getlocation());
system.out.println("- calling commit...");
// commit
session.gettransaction().commit();
system.out.println("- commit ok");
} catch (exception e) {
e.printstacktrace();
session.gettransaction().rollback();
}
// create the session after it had been closed earlier
// (cause by commit or update)
session = factory.getcurrentsession();
try {
session.gettransaction().begin();
system.out.println("- finding department deptno = d10...");
// query lại department d10.
department = datautils.finddepartment(session, "d10");
// print out location
system.out.println("- d10 location = " + department.getlocation());
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session.gettransaction().rollback();
}
}
}
执行上面代码,得到以下结果 -
创建一个java类文件:persisttransientdemo.java,用于演示对象的持久化(persistent)状态。
package com.h3;
import java.text.dateformat;
import java.text.simpledateformat;
import java.util.date;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.datautils;
import com.h3.hibernateutils;
import com.h3.entities.employee;
import com.h3.entities.timekeeper;
public class persisttransientdemo {
private static dateformat df = new simpledateformat("dd-mm-yyyy hh:mm:ss");
private static timekeeper persist_transient(session session, employee emp) {
// note:
// configuring of timekeeperid
// @generatedvalue(generator = "uuid")
// @genericgenerator(name = "uuid", strategy = "uuid2")
timekeeper tk1 = new timekeeper();
tk1.setemployee(emp);
tk1.setinout(timekeeper.in);
tk1.setdatetime(new date());
// now, 'tk1' is transient object
system.out.println("- tk1 persistent? " + session.contains(tk1));
system.out.println("====== call persist(tk).... ===========");
// hibernate assign value to id of 'tk1'
// no action to db.
session.persist(tk1);
system.out
.println("- tk1.gettimekeeperid() = " + tk1.gettimekeeperid());
// now 'tk1' is persistent object.
// but no action with db.
// ==> true
system.out.println("- tk1 persistent? " + session.contains(tk1));
system.out.println("- call flush..");
// flush data to db.
// hibernate execute insert statement.
session.flush();
string timekeeperid = tk1.gettimekeeperid();
system.out.println("- timekeeperid = " + timekeeperid);
system.out.println("- inout = " + tk1.getinout());
system.out.println("- datetime = " + df.format(tk1.getdatetime()));
system.out.println();
return tk1;
}
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
employee emp = null;
try {
session.gettransaction().begin();
emp = datautils.findemployee(session, "e7499");
persist_transient(session, emp);
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session.gettransaction().rollback();
}
}
}
执行上面代码,得到以下结果 -
创建一个java类文件:savetransientdemo.java,用于演示对象的持久化(persistent)状态。
package com.h3;
import java.io.serializable;
import java.text.dateformat;
import java.text.simpledateformat;
import java.util.date;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.datautils;
import com.h3.hibernateutils;
import com.h3.entities.employee;
import com.h3.entities.timekeeper;
public class savetransientdemo {
private static dateformat df = new simpledateformat("dd-mm-yyyy hh:mm:ss");
private static timekeeper persist_transient(session session, employee emp) {
// see configuration of timekeeperid:
// @generatedvalue(generator = "uuid")
// @genericgenerator(name = "uuid", strategy = "uuid2")
// create an object, transitent state.
timekeeper tk2 = new timekeeper();
tk2.setemployee(emp);
tk2.setinout(timekeeper.in);
tk2.setdatetime(new date());
// now 'tk3' are state transient.
system.out.println("- tk2 persistent? " + session.contains(tk2));
system.out.println("====== call save(tk).... ===========");
// save() very similar to persist()
// save() return id, persist() return void.
// hibernate assign id value to 'tk2', no action with db
// and return id of 'tk2'.
serializable id = session.save(tk2);
system.out.println("- id = " + id);
//
system.out
.println("- tk2.gettimekeeperid() = " + tk2.gettimekeeperid());
// now, 'tk2' has persistent state
// it has been managed in session.
// ==> true
system.out.println("- tk2 persistent? " + session.contains(tk2));
system.out.println("- call flush..");
// to push data into the db, call flush().
// if not call flush() data will be pushed to the db when calling commit().
// will execute insert statement.
session.flush();
string timekeeperid = tk2.gettimekeeperid();
system.out.println("- timekeeperid = " + timekeeperid);
system.out.println("- inout = " + tk2.getinout());
system.out.println("- datetime = " + df.format(tk2.getdatetime()));
system.out.println();
return tk2;
}
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
employee emp = null;
try {
session.gettransaction().begin();
emp = datautils.findemployee(session, "e7499");
persist_transient(session, emp);
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session.gettransaction().rollback();
}
}
}
执行上面代码,得到以下结果 -
创建一个java类文件:saveorupdatetransientdemo.java,用于演示对象的持久化(persistent)状态。
package com.h3;
import java.text.dateformat;
import java.text.simpledateformat;
import java.util.date;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.datautils;
import com.h3.hibernateutils;
import com.h3.entities.employee;
import com.h3.entities.timekeeper;
public class saveorupdatetransientdemo {
private static dateformat df = new simpledateformat("dd-mm-yyyy hh:mm:ss");
private static timekeeper saveorupdate_transient(session session,
employee emp) {
// see configuration of timekeeperid:
// @generatedvalue(generator = "uuid")
// @genericgenerator(name = "uuid", strategy = "uuid2")
// create an object, transitent state.
timekeeper tk3 = new timekeeper();
tk3.setemployee(emp);
tk3.setinout(timekeeper.in);
tk3.setdatetime(new date());
// now 'tk3' are state transient.
system.out.println("- tk3 persistent? " + session.contains(tk3));
system.out.println("====== call saveorupdate(tk).... ===========");
// here hibernate checks, 'tk3' have id or not (timekeeperid)
// if no, it will be assigned automatically
session.saveorupdate(tk3);
system.out
.println("- tk3.gettimekeeperid() = " + tk3.gettimekeeperid());
// now 'tk3' has persistent state
// it has been managed in session.
// but no action insert, or update to db.
// ==> true
system.out.println("- tk3 persistent? " + session.contains(tk3));
system.out.println("- call flush..");
// to push data into the db, call flush().
// if not call flush() data will be pushed to the db when calling commit().
// now possible to insert or update db. (!!!)
// depending on the id of 'tk3' exists in the db or not
session.flush();
string timekeeperid = tk3.gettimekeeperid();
system.out.println("- timekeeperid = " + timekeeperid);
system.out.println("- inout = " + tk3.getinout());
system.out.println("- datetime = " + df.format(tk3.getdatetime()));
system.out.println();
return tk3;
}
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
employee emp = null;
try {
session.gettransaction().begin();
emp = datautils.findemployee(session, "e7499");
saveorupdate_transient(session, emp);
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session.gettransaction().rollback();
}
}
}
执行上面代码,得到以下结果 -
创建一个java类文件:mergetransientdemo.java,用于演示对象的持久化(persistent)状态。
package com.h3;
import java.text.dateformat;
import java.text.simpledateformat;
import java.util.date;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.datautils;
import com.h3.hibernateutils;
import com.h3.entities.employee;
import com.h3.entities.timekeeper;
public class mergetransientdemo {
private static dateformat df = new simpledateformat("dd-mm-yyyy hh:mm:ss");
private static timekeeper saveorupdate_transient(session session,
employee emp) {
// note:
// configuring of timekeeperid
// @generatedvalue(generator = "uuid")
// @genericgenerator(name = "uuid", strategy = "uuid2")
timekeeper tk4 = new timekeeper();
tk4.setemployee(emp);
tk4.setinout(timekeeper.in);
tk4.setdatetime(new date());
// now 'tk4' transient status.
system.out.println("- tk4 persistent? " + session.contains(tk4));
system.out.println("====== call merge(tk).... ===========");
// hibernate2 has method saveorupdatecopy
// hibernate3 change saveorupdatecopy to merge
// so there will be similarities between the two methods merge and copyorupdate
// here hibernate check tk4 has id or not
// if not, hibernate assign value to id of tk4
// return copy of tk4.
timekeeper tk4copy = (timekeeper) session.merge(tk4);
system.out
.println("- tk4.gettimekeeperid() = " + tk4.gettimekeeperid());
// now 'tk4' still transient state.
// and 'tk4copy' has persistent status
// no action with db (insert or update).
system.out.println("- tk4 persistent? " + session.contains(tk4));
// 'tk4copy' has persistent status
// ==> true
system.out
.println("- tk4copy persistent? " + session.contains(tk4copy));
system.out.println("- call flush..");
// this time have insert or update to db. (!!!)
session.flush();
// 'tk4' still transitent, after flush().
// merge(..) safer than saveorupdate().
system.out.println("- tk4 persistent? " + session.contains(tk4));
//
string timekeeperid = tk4.gettimekeeperid();
system.out.println("- timekeeperid = " + timekeeperid);
system.out.println("- inout = " + tk4.getinout());
system.out.println("- datetime = " + df.format(tk4.getdatetime()));
system.out.println();
return tk4;
}
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
employee emp = null;
try {
session.gettransaction().begin();
emp = datautils.findemployee(session, "e7499");
saveorupdate_transient(session, emp);
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session.gettransaction().rollback();
}
}
}
执行上面代码,得到以下结果 -
由hibernate管理的持久化(persistent)条件中的一个对象可以通过以下两个session
的方法转换为detached
(独立于hibernate的管理)状态:
evict (object)
- 从hibernate管理中删除一个对象
clear()
- 从hibernate管理的对象中删除所有对象。
当然,当session
调用顺序为:commit()
,close()
或rollback()
时,当前会话已经完成。 此会话的所有persistence
对象将从新打开的会话中分离。
创建一个java类文件:evictdemo.java,用于演示对象持久化转变为分离状态。
package com.h3;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.datautils;
import com.h3.hibernateutils;
import com.h3.entities.employee;
public class evictdemo {
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
employee emp = null;
try {
session.gettransaction().begin();
// this is object has persistent status
emp = datautils.findemployee(session, "e7499");
// ==> true
system.out.println("- emp persistent? " + session.contains(emp));
// using evict() to evicts a single object from the session
session.evict(emp);
// now 'emp' has detached status
// ==> false
system.out.println("- emp persistent? " + session.contains(emp));
// all change on the 'emp' will not update
// if not reatach 'emp' to session
emp.setempno("new");
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session.gettransaction().rollback();
}
}
}
执行上面代码,得到以下结果 -
创建一个java类文件:cleardemo.java,用于演示将所有对象持久化转变为分离状态。
package com.h3;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.datautils;
import com.h3.hibernateutils;
import com.h3.entities.department;
import com.h3.entities.employee;
public class cleardemo {
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session = factory.getcurrentsession();
employee emp = null;
department dept = null;
try {
session.gettransaction().begin();
// it is an object has persistent status.
emp = datautils.findemployee(session, "e7499");
dept = datautils.finddepartment(session, "d10");
// clear() evicts all the objects in the session.
session.clear();
// now 'emp' & 'dept' has detached status
// ==> false
system.out.println("- emp persistent? " + session.contains(emp));
system.out.println("- dept persistent? " + session.contains(dept));
// all change on the 'emp' will not update
// if not reatach 'emp' to session
emp.setempno("new");
dept = datautils.finddepartment(session, "d20");
system.out.println("dept name = "+ dept.getdeptname());
session.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session.gettransaction().rollback();
}
}
}
执行上面代码,得到以下结果 -
hibernate管理分离的对象可以通过以下session
的一些方法重新附加:
可以在以下示例中看到这些方法的区别:
创建一个java类文件:updatedetacheddemo.java,用于演示将对象分离转变为持久性状态。
package com.h3;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.datautils;
import com.h3.hibernateutils;
import com.h3.entities.department;
import com.h3.entities.employee;
public class updatedetacheddemo {
public static void main(string[] args) {
sessionfactory factory = hibernateutils.getsessionfactory();
session session1 = factory.getcurrentsession();
employee emp = null;
try {
session1.gettransaction().begin();
// this is a persistent object.
emp = datautils.findemployee(session1, "e7499");
// session1 was closed after a commit is called.
session1.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session1.gettransaction().rollback();
}
// open other session
session session2 = factory.getcurrentsession();
try {
session2.gettransaction().begin();
// check state of 'emp'
// ==> false
system.out.println("- emp persistent? " + session2.contains(emp));
system.out.println("emp salary: " + emp.getsalary());
emp.setsalary(emp.getsalary() + 100);
// update (..) is only used for detached object.
// (not for transient object).
// use the update (emp) to bring back emp persistent state.
session2.update(emp);
// call flush
// update statement will be called.
session2.flush();
system.out.println("emp salary after update: " + emp.getsalary());
// session2 was closed after a commit is called.
session2.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session2.gettransaction().rollback();
}
}
}
执行上面代码,得到以下结果 -
创建一个java类文件:saveorupdatedetacheddemo.java,用于演示将对象分离转变为持久性状态。
package com.h3;
import java.util.random;
import org.hibernate.query;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.datautils;
import com.h3.hibernateutils;
import com.h3.entities.employee;
public class saveorupdatedetacheddemo {
public static void main(string[] args) {
// an object detached state.
employee emp = getemployee_detached();
system.out.println(" - get emp " + emp.getempid());
// random delete or not delete employee
boolean delete = deleteornotdelete(emp.getempid());
system.out.println(" - delete? " + delete);
// call saveorupdate for detached object.
saveorupdate_test(emp);
// after call saveorupdate()
system.out.println(" - emp id " + emp.getempid());
}
// return employee object has detached state
private static employee getemployee_detached() {
sessionfactory factory = hibernateutils.getsessionfactory();
session session1 = factory.getcurrentsession();
employee emp = null;
try {
session1.gettransaction().begin();
long maxempid = datautils.getmaxempid(session1);
system.out.println(" - max emp id " + maxempid);
employee emp2 = datautils.findemployee(session1, "e7839");
long empid = maxempid + 1;
emp = new employee();
emp.setempid(empid);
emp.setempno("e" + empid);
emp.setdepartment(emp2.getdepartment());
emp.setempname(emp2.getempname());
emp.sethidedate(emp2.gethidedate());
emp.setjob("test");
emp.setsalary(1000f);
// emp has been managed by hibernate
session1.persist(emp);
// session1 was closed after a commit is called.
// an employee record are insert into db.
session1.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session1.gettransaction().rollback();
}
// session1 closed 'emp' switch to detached state.
return emp;
}
// random: delete or not delete.
private static boolean deleteornotdelete(long empid) {
// a random number 0-9
int random = new random().nextint(10);
if (random < 5) {
return false;
}
sessionfactory factory = hibernateutils.getsessionfactory();
session session2 = factory.getcurrentsession();
try {
session2.gettransaction().begin();
string sql = "delete " + employee.class.getname() + " e "
+ " where e.empid =:empid ";
query query = session2.createquery(sql);
query.setparameter("empid", empid);
query.executeupdate();
session2.gettransaction().commit();
return true;
} catch (exception e) {
e.printstacktrace();
session2.gettransaction().rollback();
return false;
}
}
private static void saveorupdate_test(employee emp) {
sessionfactory factory = hibernateutils.getsessionfactory();
// open other session
session session3 = factory.getcurrentsession();
try {
session3.gettransaction().begin();
// check state of emp
// ==> false
system.out.println(" - emp persistent? " + session3.contains(emp));
system.out.println(" - emp salary before update: "
+ emp.getsalary());
// set new salary for detached emp object.
emp.setsalary(emp.getsalary() + 100);
// using saveorupdate(emp) to switch emp to persistent state
// note: if exists object same id in session, this method raise exception
//
// now, no action with db.
session3.saveorupdate(emp);
// by pushing data into the db.
// it will call a insert or update statement.
// if the record is deleted before ==> insert
// else ==> update.
session3.flush();
system.out
.println(" - emp salary after update: " + emp.getsalary());
// session3 was closed after a commit is called.
session3.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session3.gettransaction().rollback();
}
}
}
执行上面代码,多几次运行示例错码,可以看到两种情况,saveorupdate()
方法调用在数据上插入或更新。得到以下结果 -
hibernate 2
版本有saveorupdatecopy(object)
方法。从hibernate 3
起,它被重命名为merge(object)
。 因此与saveorupdate()
相比,merge()
方法有一些相似性和差异。
merge(object)
不会将对象置于hibernate的管理下,而是创建一个对象的副本,而不是管理该对象。
如果调用saveorupdate(aobject)
则aobject
由hibernate管理,并且与aobject
具有相同的id将会抛出异常,但是使用merge(aobject)
时不会得到此异常。
创建一个java类文件:mergedetacheddemo.java,用于演示将对象分离转变为持久性状态。
package com.h3;
import java.util.random;
import org.hibernate.query;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.datautils;
import com.h3.hibernateutils;
import com.h3.entities.employee;
public class mergedetacheddemo {
public static void main(string[] args) {
// an object has detached status
employee emp = getemployee_detached();
system.out.println(" - get emp " + emp.getempid());
// random: delete or not delete the employee by id.
boolean delete = deleteornotdelete(emp.getempid());
system.out.println(" - delete? " + delete);
// call saveorupdate detached object
saveorupdate_test(emp);
// after call saveorupdate
// ...
system.out.println(" - emp id " + emp.getempid());
}
// method return employee object
// and has detached status.
private static employee getemployee_detached() {
sessionfactory factory = hibernateutils.getsessionfactory();
session session1 = factory.getcurrentsession();
employee emp = null;
try {
session1.gettransaction().begin();
long maxempid = datautils.getmaxempid(session1);
system.out.println(" - max emp id " + maxempid);
employee emp2 = datautils.findemployee(session1, "e7839");
long empid = maxempid + 1;
emp = new employee();
emp.setempid(empid);
emp.setempno("e" + empid);
emp.setdepartment(emp2.getdepartment());
emp.setempname(emp2.getempname());
emp.sethidedate(emp2.gethidedate());
emp.setjob("test");
emp.setsalary(1000f);
// 'emp' has persistant state
session1.persist(emp);
// session1 was closed after a commit is called.
// an employee record are insert into db.
session1.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session1.gettransaction().rollback();
}
// session1 closed, 'emp' switched detached state.
return emp;
}
// delete employee by id
// random: delete or not delete
private static boolean deleteornotdelete(long empid) {
// a random number 0-9
int random = new random().nextint(10);
if (random < 5) {
return false;
}
sessionfactory factory = hibernateutils.getsessionfactory();
session session2 = factory.getcurrentsession();
try {
session2.gettransaction().begin();
string sql = "delete " + employee.class.getname() + " e "
+ " where e.empid =:empid ";
query query = session2.createquery(sql);
query.setparameter("empid", empid);
query.executeupdate();
session2.gettransaction().commit();
return true;
} catch (exception e) {
e.printstacktrace();
session2.gettransaction().rollback();
return false;
}
}
private static void saveorupdate_test(employee emp) {
sessionfactory factory = hibernateutils.getsessionfactory();
// open other session
session session3 = factory.getcurrentsession();
try {
session3.gettransaction().begin();
// the fact, 'emp' has detached state
// it is not managed by hibernate.
// check the status of emp:
// ==> false
system.out.println(" - emp persistent? " + session3.contains(emp));
system.out.println(" - emp salary before update: "
+ emp.getsalary());
// set new salary for detached object 'emp'
emp.setsalary(emp.getsalary() + 100);
// merge(emp) return empmerge, a copy of 'emp',
// empmerge managed by hibernate
// 'emp' still in detached state
//
// at this time there is no action regarding db.
employee empmerge = (employee) session3.merge(emp);
// ==> false
system.out.println(" - emp persistent? " + session3.contains(emp));
// ==> true
system.out.println(" - empmerge persistent? "
+ session3.contains(empmerge));
// push data into the db.
// here it is possible to create the insert or update on db.
// if the corresponding record has been deleted by someone, it insert
// else it update
session3.flush();
system.out
.println(" - emp salary after update: " + emp.getsalary());
// session3 closed after a commit is called.
session3.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session3.gettransaction().rollback();
}
}
}
执行上面代码,多几次运行示例错码,可以看到两种情况,得到以下结果 -
创建一个java类文件:refreshdetacheddemo.java,用于演示将对象分离转变为持久性状态。
package com.h3;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import com.h3.datautils;
import com.h3.hibernateutils;
import com.h3.entities.employee;
public class refreshdetacheddemo {
public static void main(string[] args) {
// an object with detached status
employee emp = getemployee_detached();
system.out.println(" - get emp " + emp.getempid());
// refresh object
refresh_test(emp);
}
// return employee object has detached state
private static employee getemployee_detached() {
sessionfactory factory = hibernateutils.getsessionfactory();
session session1 = factory.getcurrentsession();
employee emp = null;
try {
session1.gettransaction().begin();
emp = datautils.findemployee(session1, "e7839");
// session1 was closed after a commit is called.
// an employee record are insert into db.
session1.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session1.gettransaction().rollback();
}
// session1 closed 'emp' switch to detached state.
return emp;
}
private static void refresh_test(employee emp) {
sessionfactory factory = hibernateutils.getsessionfactory();
// open other session
session session2 = factory.getcurrentsession();
try {
session2.gettransaction().begin();
// check the status of 'emp' (detached)
// ==> false
system.out.println(" - emp persistent? " + session2.contains(emp));
system.out.println(" - emp salary before update: "
+ emp.getsalary());
// set new salary for 'emp'.
emp.setsalary(emp.getsalary() + 100);
// refresh: make a query statement
// and switch 'emp' to persistent state
// the changes are ignored
session2.refresh(emp);
// ==> true
system.out.println(" - emp persistent? " + session2.contains(emp));
system.out.println(" - emp salary after refresh: "
+ emp.getsalary());
session2.gettransaction().commit();
} catch (exception e) {
e.printstacktrace();
session2.gettransaction().rollback();
}
}
}
执行上面代码,多几次运行示例错码,可以看到两种情况,得到以下结果 -
hibernateutils.java类,无代码显示以下为乱码,凑够字数...线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。多线程能满足程序员编写高效率的程序来达到充分利用 cpu 的目的 提交时间:2019-09-04