Hibernate笔记

hibernate配置文件 hibernate配置文件 里面提供了连接数据库 数据库使用的方言 是否打印SQL语句 sql语句的格式 以及对象-关系映射文件的地址等 立即下载

Hibernate

Hibernate 简单应用(单表)
1. 导入hibernate所需要的jar包:
antlr.jar:用来解析 HQL 语句。
cglib.jar:用来修改类。
asm.jar:在运行时候修改类。依赖于
cglib.jar。commons-collections:提供集合功能,比 java 类中的集合提供更强大的功能。commons-logging.jar:记录日志。jta.jar:分布式事务。当有跨数据库访问的时候,需要这个包。dom4j.jar:用来解析 XML 文件。
(记得导入数据库
jar 包)

2. 配置hibernate.cfg.xml文件(放在“src”下)

<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd

">

<hibernate-configuration><session-factory>

<propertyname="hibernate.dialect">

>

</property

org.hibernate.dialect.MySQLDialect

批注 [z1]: 数据库的方言。

批注 [z2]: 数据库驱动的名称。

批注 [z3]: 连接数据库的 URL 地址。批注 [z4]: 用户名。
批注
[z5]: 密码。

批注 [z6]: 每次加载 hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。

批注 [z7]: 显示生成的 SQL 语句。批注 [z8]: 指定映射文件的路径。

<property
name="hibernate.connection.driver_class"> </prope

rty>
<property

name="hibernate.connection.url"> </property>

<property name="hibernate.connection.username"><property name="hibernate.connection.password"><property name="hbm2ddl.auto"> </property>

<property name="show_sql"> </property>

<mapping resource="

</session-factory></hibernate-configuration>

com.mysql.jdbc.Driver

jdbc:mysql:///zhaohan

</property>

root

</property>

123

create

true

com/it315/domain/User.hbm.xml

"/>

Validate:加载 hibernate 时,验证创建数据库表结构。
create:每次加载 hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。

Hbm2ddl.auto 的配置参数:

传智博客—赵涵笔记 1

3. User.java

4. User.hbm.xml

create-drop:加载 hibernate 时创建,退出是删除表结构。update :加载 hibernate 自动更新数据库结构。

package com.it315.domain;import java.util.Date;public class User {

private long id;private String name;private Date birthday;......set,get方法省略

}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping

package=" ">

<class name="User" table="

<id name="id">
<generator class=" "/>

</id>
<property name="name" column="

">

com.it315.domain

批注 [z9]: User.java 所在的包。
批注
[z10]: 与 User.java 映射的表名。

批注 [z11]: 由 hibernate 根据底层数据库自行判断采用identity,hilo,sequence 其中一种作为主键生成方式。

批注 [z12]: Name 属性对应生成表中的 user_name 字段。

UserTable

native

"></property>

user_name

<property name="birthday" column="user_birthday"></property>

</class></hibernate-mapping>

package com.it315.main;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import com.it315.domain.User;

public class Main {
public static void main(String[] args) {

Configuration = new Configuration();

批注 [z13]: Configuration 实例会根据当前的数据库配置信息,构造SessionFactory 实例并返回。

cfg

5. Main.java

传智博客—赵涵笔记 2

批注 [z14]: 如果配置文件的名称不是默认的“hibernat e.cfg .xml”,那么 configure()方法要指定文件名。

批注 [z15]: Session 是持久层操作的基础,相当于 jdbc 中的 connection.

批注 [z16]: 对数据有更改的操作都要开启事务和提交事务。Hibernate默认的事务是关闭的。

SessionFactory sessionfactory =cfg. .buildSessionFactory();

Session = sessionfactory.openSession();

User user = new User();user.setName("zhaohan");user.setBirthday(new Date());
Transaction tc = session. ;

session.save(user);

tc.commit();}

}

configure()

session

beginTransaction()

package com.it315.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;

public final class HibernateUtils {
private static SessionFactory
sessionFactory;static {

Configuration cfg = new Configuration();
sessionFactory = cfg.configure().buildSessionFactory();

}
public static Session
getSession(){

return sessionFactory.openSession();}

}

package com.it315.main;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.Transaction;import com.it315.domain.User;
import com.it315.util.HibernateUtils;

Domain Object的限制:
○1 必须有一个无参数的构造方法。
○2 有无意义的表示符
id.(可选)
○3 非 final 的,对懒加载有影响。(可选)

注意 :初始化的代码是很耗资源的,所以将上面代码修改为:HibernateUtils.java

Main.java

传智博客—赵涵笔记 3

public class Main {
public static void main(String[] args) {

Session session = null;Transaction tc = null;try {

session = HibernateUtils.getSession();

User user = new User();user.setName("zhaohan");user.setBirthday(new Date());

tc = session.beginTransaction();session.save(user);
tc.commit();

} catch (Exception e) {if(tc != null){

tc.rollback();

throw new RuntimeException(e.getMessage(),e);}

} finally {
if(session != null){

session.close();}

}}

}

<id name="id"

<generator class="native"/></id>

unsaved-value="0"

>

批注 [z17]: 设置没有保存的对象的id 值为-1。调用 session 的
saveOr Updat e()方法,如果这个对象的 id 和设置的这个-1 是相等的,那么说明这个对象没有被保存过,就保存。如果不相等,那么就更新。

注意:
Hibernate 中的几个重要方法:

○1 save 和 persist 的区别(在没有开启事务的前提下是有区别的,如果开启了事务,则效果是一样的。)

○1 save 在没有开启事务的前提下,会将数据插入数据库,但是当发现事务没有开启的话,插入的数据就会立刻回滚。

○2 persist 在没有开启事务的前提下,不会产生 insert 语句。○2 saveOrUpdate

○3 get 和 load 的区别
□1 调用 get()方法,会立刻访问数据库。生成 select 语句。
□2 调用
load()方法,返回一个代理对象,只有在取得对象属性的时候才会真正的去访

传智博客—赵涵笔记 4

问数据库。例如:

批注 [z18]: 得到的这个 user 对象,是从 User 类继承来的。

static User getUser(long id){Session session = null;

Transaction tc = null;

try {
session = HibernateUtils.getSession();
User user = (User)session.load(User.class, id);System.out.println( );

System.out.println(user.getName());

return user;
} catch (Exception e) {

if (tc != null) {tc.rollback();

throw new RuntimeException(e.getMessage(), e);}

} finally {
if (session != null) {

session.close();}

}

return null;}

user.getClass()

package com.it315.UserDaoImpl;

Hibernate 中的对象的几种状态:
○1 瞬时:数据库中没有数据与之对应,超过作用域会被
JVM 垃圾回收器回收,一般是 new

出来且与 session 没有关联的对象。
○2 持久:数据库中有数据与之对应,当前与
session 有关联,并且相关联的 session 没

有关闭,事 务没有提 交,持久 对象状态 发生改变 ,在事 务提交时 会影响到 数据库

(hibernate 能检测到)。
○3 托管:数据库中有数据与之相应,但当前没有
session 与之关联。托管对象状态发生改

变,hibernate 不能检测到。

判断对象的状态是根据 session 判断的,看它与 session 是否关联。例如:刚查到的对象,在 session 还没有关闭之前,是持久状态,因为数据库中有数据与它对应,且相关联的 session 没有关闭,这时候修改它的属性,hibernate 能检测到。若在 session关闭之后,虽然数据库中也有数据与它相对应,但没有与 session 关联,所以变为托管状态。

增,删,改,查:UserDaoImpl.java

传智博客—赵涵笔记 5

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;import com.it315.daoI.UserDaoI;import com.it315.domain.User;
import com.it315.util.HibernateUtils;

public class UserDaoImpl implements UserDaoI {Session session = HibernateUtils.getSession();

Transaction tc = null;

@Override
public void
saveUser(User user) {

try {
tc = session.beginTransaction();session.save(user);
tc.commit();

} finally {
if (session != null) {

session.close();}

}}

@Override
public User
findUserById(long id) {

try {
User user = (User) session.get(User.class, id);return user;

} finally {
if (session != null) {

session.close();}

}}

@Override
public User
findUserByName(String name) {

try {
Query q = session

.createQuery("from User as user where user.name =?");q.setString(0, name);

传智博客—赵涵笔记 6

=:

");

/*Query q = session
.createQuery("from User as user where user.name

q.setString("*/

User user = (User) q.uniqueResult();

name

批注 [z19]: name 是随便起的。

批注 [z20]: 和上面批注的 name 保持一致。

name

", name);

return user;} finally {

if (session != null) {session.close();

}}

}

@Override
public void
updateUser(User user) {

try {
tc = session.beginTransaction();session.update(user);tc.commit();

} finally {
if (session != null) {

session.close();}

}}

public void saveOrUpdate(User user){try {

tc = session.beginTransaction();session.saveOrUpdate(user);tc.commit();

} finally {
if (session != null) {

session.close();}

}}

@Override
public void
remove(User user) {

try {
tc = session.beginTransaction();

传智博客—赵涵笔记 7

session.delete(user);

tc.commit();} finally {

if (session != null) {session.close();

}}

}}

package com.it315.test;import java.util.Date;
import org.junit.BeforeClass;import org.junit.Test;

import com.it315.UserDaoImpl.UserDaoImpl;import com.it315.daoI.UserDaoI;
import com.it315.domain.User;

public class UserDaoImplTest {static UserDaoI dao = null;static User user = null;

@BeforeClass
public static void
setUpBeforeClass() throws Exception {

dao = new UserDaoImpl();
user = new User();user.setName("zhangsan");user.setBirthday(new Date());

}

@Test
public void
testFindUserById() {

User user = dao.findUserById(19);

System.out.println(user.getName());}

@Test
public void
testFindUserByName() {

User user = dao.findUserByName("mali");

System.out.println(user.getBirthday());}

@Test

Test.java

传智博客—赵涵笔记 8

public void testRemove() {user.setId(19);dao.remove(user);

}

@Test
public void
testSaveUser() {

dao.saveUser(user);}

@Test
public void
testUpdateUser() {

user.setId(19);user.setName("maik");dao.updateUser(user);

}}

package com.it315.domain;public class Department {

private int id;private String name;get(),set()方法省略......

}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping

package="com.it315.domain">
<class name="Department" table="Department">

<id name="id">
<generator class="native"/>

</id>

<property name="name" column="department_name"></property></class>

</hibernate-mapping>

关联和集合的映射
1. 多对一(Employee-Department)○1 Department.java

○2 Department.hbm.xml

传智博客—赵涵笔记 9

○3 Employee.java

○4 Employee.hbm.xml

批注 [z21]: 员工与部门之间是多对一的关系。在这里将 Employee.java里的 depart 属性映射为 Employee 表中的 depart_id 字段。

默认是与部门的 id 进行关联,如果想指定关联的字段:<many-to-one name="depart"column= "depa rt_id "

propert y-ref ="nam e"/>

package com.it315.domain;public class Employee {

private int id;
private String name;private int age;
private Department depart;get(),set()方法省略......
}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping

package="com.it315.domain">
<class name="Employee" table="Emlpoyee">

<id name="id">
<generator class="native"/>

</id>
<property name="name" column="employee_name"></property><property name="age" column="employee_age"></property>
< column="depart_id" />

</class></hibernate-mapping>

many-to-one name="depart"

......

<mapping resource="com/it315/domain/Department.hbm.xml"/><mapping resource="com/it315/domain/Employee.hbm.xml"/>......

package com.it315.test;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;import com.it315.domain.Department;import com.it315.domain.Employee;import com.it315.util.HibernateUtils;

○5 hibernate.cfg.xml

○6 Test.java

传智博客—赵涵笔记 10

批注 [z22]: 清除一级缓存。读取数据时默认是先去一级缓存中查询,一级缓存中没有的话才去数据库里查询。

public class Test {
public static void main(String[] args) {

Session session = null;Transaction tc = null;try {

session = HibernateUtils.getSession();tc = session.beginTransaction();

Department depart = new Department();depart.setName("JiShu");

session.save(depart);

Employee emp = new Employee();emp.setAge(20);emp.setName("zhaohan");emp.setDepart(depart);

session.save(emp);

session. ;

System.out.println("----------------------------");

Employee emp1 = (Employee)session.get(Employee.class,emp.getId());

System.out.println(emp1.getName());

tc.commit();

} finally {
if (session != null) {

session.close();}

}}

}

clear()

Hibernate: insert into Department (department_name) values (?)Hibernate: insert into Emlpoyee (employee_name, employee_age, depart_id)values (?, ?, ?)
----------------------------
zhaohan
JiShu

不调用 clear()方法输出的语句是:

传智博客—赵涵笔记 11

掉用 clear()方法输出的语句是:

Hibernate: insert into Department (department_name) values (?)Hibernate: insert into Emlpoyee (employee_name, employee_age, depart_id)values (?, ?, ?)
----------------------------
Hibernate: select employee0_.id as id1_0_, employee0_.employee_name asemployee2_1_0_, employee0_.employee_age as employee3_1_0_,employee0_.depart_id as depart4_1_0_ from Emlpoyee employee0_ whereemployee0_.id=?
zhaohan
Hibernate: select department0_.id as id0_0_,department0_.department_name as department2_0_0_ from Departmentdepartment0_ where department0_.id=?
JiShu

CREATE TABLE `department` (
`id` int(11) NOT NULL auto_increment,`department_name` varchar(255) default NULL,PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=gbk;

CREATE TABLE `emlpoyee` (
`id` int(11) NOT NULL auto_increment,
`employee_name` varchar(255) default NULL,
`employee_age` int(11) default NULL,
`depart_id` int(11) default NULL,
PRIMARY KEY (`id`),
KEY `FK44624656163671D3` (`depart_id`),
CONSTRAINT `FK44624656163671D3` FOREIGN KEY (`depart_id`) REFERENCES

`department` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;

package com.it315.domain;import java.util.Set;

public class Department {
private int
id;
private String name;
private Set<Employee> employee;get(),set()方法省略......

表的定义语句为:

2. 一对多(Department-Employee)○1 Department.java

传智博客—赵涵笔记 12

}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.it315.domain">

<class name="Department" table="Department"><id name="id">

<generator class="native" /></id>

<property name="name" column="department_name"></property><set name=" ">

<key column="

<one-to-many class="Employee" /></set>

</class></hibernate-mapping>

employee

批注 [z23]: 映射 Department 的employee 属性,它的类型是 set 类型。

批注 [z24]: 生成外键的字段名。(注意这个字段名要和 Employee 表中定义的外键字段名相同。)

depart_id

" />

package com.it315.domain;public class Employee {

private int id;
private String name;private int age;
private Department depart;get(),set()方法省略......

}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping

package="com.it315.domain">
<class name="Employee" table="Emlpoyee">

<id name="id">
<generator class="native"/>

</id>
<property name="name" column="employee_name" /><property name="age" column="employee_age" /><many-to-one name="depart" column=" "/>

批注 [z25]: 这个字段名要和Department.hbm.xml 里 set 集合映射的 key 的字段名相同。

depart_id

○2 Department.hbm.xml

○3 Employee.java

○4 Employee.hbm.xml

传智博客—赵涵笔记 13

</class></hibernate-mapping>

package com.it315.test;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;import com.it315.domain.Department;import com.it315.domain.Employee;import com.it315.util.HibernateUtils;

public class Test {
public static void main(String[] args) {

save();

test();

}
static void
save() {

Session session = null;Transaction tc = null;try {

session = HibernateUtils.getSession();tc = session.beginTransaction();

Department depart = new Department();depart.setName("jishu");session.save(depart);

Set<Employee> set = new HashSet<Employee>();

Employee emp = new Employee();emp.setAge(20);emp.setName("lisa");emp.setDepart(depart);session.save(emp);set.add(emp);

Employee emp1 = new Employee();emp1.setAge(21);emp1.setName("zhangsan");emp1.setDepart(depart);session.save(emp1);set.add(emp1);

○5 Test.java

传智博客—赵涵笔记 14

System.out.println("-------------------");depart.setEmployee(set);
tc.commit();

} finally {
if (session != null) {

session.close();}

}}

static void test() {Session session = null;try {

session = HibernateUtils.getSession();

Department depart =(Department)session.get(Department.class, 1);

Set<Employee> set = depart.getEmployee();for(Employee emp : set){

System.out.println(emp.getName());}

} finally {
if(session != null){

session.close();}

}}

}

Hibernate: insert into Department (department_name) values (?)Hibernate: insert into Emlpoyee (employee_name, employee_age, depart_id)values (?, ?, ?)
Hibernate: insert into Emlpoyee (employee_name, employee_age, depart_id)values (?, ?, ?)
-------------------
Hibernate: update Emlpoyee set depart_id=? where id=?
Hibernate: update Emlpoyee set depart_id=? where id=?
Hibernate: select department0_.id as id0_0_,

○6 运行结果:

传智博客—赵涵笔记 15

department0_.department_name as department2_0_0_ from Departmentdepartment0_ where department0_.id=?
Hibernate: select employee0_.depart_id as depart4_1_, employee0_.id asid1_, employee0_.id as id1_0_, employee0_.employee_name asemployee2_1_0_, employee0_.employee_age as employee3_1_0_,employee0_.depart_id as depart4_1_0_ from Emlpoyee employee0_ whereemployee0_.depart_id=?

zhangsanlisa

CREATE TABLE `department` (
`id` int(11) NOT NULL auto_increment,`department_name` varchar(255) default NULL,PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `emlpoyee` (
`id` int(11) NOT NULL auto_increment,
`employee_name` varchar(255) default NULL,
`employee_age` int(11) default NULL,
`depart_id` int(11) default NULL,
PRIMARY KEY (`id`),
KEY `FK44624656163671D3` (`depart_id`),
CONSTRAINT `FK44624656163671D3` FOREIGN KEY (`depart_id`) REFERENCES

`department` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

package com.it315.domain;

public class Room {private int id;private int floor;private Door door;get(),set()方法省略......}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

表的定义语句为:

3. 一对一(Room-Door)○1 Room.java

○2 Room.hbm.xml

传智博客—赵涵笔记 16

批注 [z26]: 通过外键生成主键。

批注 [z27]: 告诉当前表主键上存在一个约束。

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.it315.domain">

<class name="Room" table="room"><id name="id">

<generator class="native" /></id>

<property name="floor" /><one-to-one name="door" />

</class></hibernate-mapping>

package com.it315.domain;

public class Door {private int id;private int number;private Room room;get(),set()方法省略......}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.it315.domain">

<class name="Door" table="door"><id name="id">

<generator class=" ">

<param name="property">room</param></generator>

</id>
<property name="number" />
<one-to-one name="room" />

</class></hibernate-mapping>

foreign

constrained="true"

package com.it315.test;
import org.hibernate.Session;import org.hibernate.Transaction;import com.it315.domain.Door;import com.it315.domain.Room;

○3 Door.java

○4 Door.hbm.xml

○5 Test.java

传智博客—赵涵笔记 17

import com.it315.util.HibernateUtils;

public class Test {
public static void main(String[] args) {

add();

select();

}

public static void add() {Session session = null;Transaction tc = null;try {

session = HibernateUtils.getSession();tc = session.beginTransaction();

Room r = new Room();r.setFloor(1);

Door d = new Door();d.setNumber(2);d.setRoom(r);

session.save(r);session.save(d);

tc.commit();} finally {

if (session != null) {session.close();

}}

}

public static void select() {Session session = null;try {

session = HibernateUtils.getSession();
Room r = (Room) session.get(Room.class, 1);System.out.println(r.getDoor().getNumber());

} finally {
if (session != null) {

session.close();}

}

传智博客—赵涵笔记 18

}}

Hibernate: insert into room (floor) values (?)
Hibernate: insert into door (number, id) values (?, ?)
Hibernate: select room0_.id as id1_1_, room0_.floor as floor1_1_,door1_.id as id0_0_, door1_.number as number0_0_ from room room0_ leftouter join door door1_ on room0_.id=door1_.id where room0_.id=?
2

CREATE TABLE `room` (
`id` int(11) NOT NULL auto_increment,`floor` int(11) default NULL,
PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `door` (
`id` int(11) NOT NULL,
`number` int(11) default NULL,
PRIMARY KEY (`id`),
KEY `FK2F23AE66854F71` (`id`),
CONSTRAINT `FK2F23AE66854F71` FOREIGN KEY (`id`) REFERENCES `room`

(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.it315.domain">

<class name="Door" table="door"><id name="id">

<generator class="native" /></id>

<property name="number" />

<many-to-one name="room" column="room_id" unique="true"/></class>

</hibernate-mapping>

结果:

表的定义语句为:

两张表共用一个主键,所以只执行了一条查询语句。一对一的另一种方法:

Door.hbm.xml

传智博客—赵涵笔记 19

表的定义语句为:

CREATE TABLE `room` (
`id` int(11) NOT NULL auto_increment,`floor` int(11) default NULL,
PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `door` (
`id` int(11) NOT NULL auto_increment,
`number` int(11) default NULL,
`room_id` int(11) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `room_id` (`room_id`),
KEY `FK2F23AEB8C4C155` (`room_id`),
CONSTRAINT `FK2F23AEB8C4C155` FOREIGN KEY (`room_id`) REFERENCES `room`

(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

package com.it315.domain;import java.util.Set;

public class Teacher {
private int
id;
private String name;
private Set<Student> students;get(),set()方法省略......

public String toString() {
return "id=" + this.id + "name=" + this.name + "students="

+ this.getStudents();

}}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.it315.domain">

<class name="Teacher" table="Teacher">

这种写法其实是多对一加了一个限制,外键只允许有一个,所以才有一对一的效果。4. 多对多(teacher-student)

○1 Teacher.java

○2 Teacher.hbm.xml

传智博客—赵涵笔记 20

批注 [z28]: 生成表的名字。生成表中有两个字段,一个是 teacher 的 id,一个是 student 的 id.

<id name="id">
<generator class="native" />

</id>
<property name="name" column="teacher_name" />
<set name="students" table=" ">

<key column="teacher_id"/>

<many-to-many class="Student" column="student_id"/></set>

</class></hibernate-mapping>

teacher_student

package com.it315.domain;import java.util.Set;

public class Student {
private int
id;
private String name;
private Set<Teacher> teachers;get(),set()方法省略......

public String toString() {
return "id=" + this.id + "name=" + this.name;

}}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.it315.domain">

<class name="Student" table="Student"><id name="id">

<generator class="native" /></id>

<property name="name" column="student_name"></property><set name="teachers" table="teacher_student">

<key column="student_id" />

<many-to-many class="Teacher" column="teacher_id" /></set>

</class></hibernate-mapping>

○3 Student.java

○4 Student.hbm.xml

○5 Test.java
传智博客—赵涵笔记 21

package com.it315.test;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;import com.it315.domain.Student;import com.it315.domain.Teacher;import com.it315.util.HibernateUtils;

public class Test {
public static void main(String[] args) {

add();

select();}

static void add(){
Session session = null;Transaction ts = null;try{

session = HibernateUtils.getSession();ts = session.beginTransaction();

Set<Teacher> set1 = new HashSet<Teacher>();

Teacher teacher1 = new Teacher();teacher1.setName("t1");set1.add(teacher1);

Teacher teacher2 = new Teacher();teacher2.setName("t2");set1.add(teacher2);

Set<Student> set2 = new HashSet<Student>();

Student student1 = new Student();student1.setName("s1");set2.add(student1);

Student student2 = new Student();student2.setName("s2");set2.add(student2);

teacher1.setStudents(set2);teacher2.setStudents(set2);

传智博客—赵涵笔记 22

session.save(teacher1);session.save(teacher2);session.save(student1);session.save(student2);

ts.commit();

}finally{
if(session != null){

session.close();}

}}

static void select(){Session session = null;Transaction ts = null;try{

session = HibernateUtils.getSession();
ts = session.beginTransaction();
Teacher teacher = (Teacher)session.get(Teacher.class, 1);

System.out.println(teacher.getStudents());

}finally{
if(session != null){

session.close();}

}}

}

Hibernate: insert into Teacher (teacher_name) values (?)
Hibernate: insert into Teacher (teacher_name) values (?)
Hibernate: insert into Student (student_name) values (?)
Hibernate: insert into Student (student_name) values (?)
Hibernate: insert into teacher_student (teacher_id, student_id) values(?, ?)

Hibernate: insert into teacher_student (teacher_id, student_id) values(?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values(?, ?)

Hibernate: insert into teacher_student (teacher_id, student_id) values

○6 运行结果:

传智博客—赵涵笔记 23

(?, ?)
Hibernate: select teacher0_.id as id0_0_, teacher0_.teacher_name asteacher2_0_0_ from Teacher teacher0_ where teacher0_.id=?
Hibernate: select students0_.teacher_id as teacher1_1_,students0_.student_id as student2_1_, student1_.id as id2_0_,student1_.student_name as student2_2_0_ from teacher_student students0_left outer join Student student1_ on students0_.student_id=student1_.idwhere students0_.teacher_id=?
[id=1name=s1, id=2name=s2]

CREATE TABLE `teacher` (
`id` int(11) NOT NULL auto_increment,`teacher_name` varchar(255) default NULL,PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=gbk;

CREATE TABLE `student` (
`id` int(11) NOT NULL auto_increment,`student_name` varchar(255) default NULL,PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=gbk;

CREATE TABLE `teacher_student` (
`teacher_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
PRIMARY KEY (`student_id`,`teacher_id`),
KEY `FK2E2EF2DE7E54D71F` (`teacher_id`),
KEY `FK2E2EF2DE6DB98C7F` (`student_id`),
CONSTRAINT `FK2E2EF2DE6DB98C7F` FOREIGN KEY (`student_id`) REFERENCES

`student` (`id`),
CONSTRAINT `FK2E2EF2DE7E54D71F` FOREIGN KEY (`teacher_id`) REFERENCES

`teacher` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;

package com.it315.domain;

public class Name {
private String firstName;private String lastName;get(),set()方法省略......

}

○7 表的定义语句:

5. 组件映射(user-name)○1 Name.java

传智博客—赵涵笔记 24

○2 User.java

○3 User.hbm.xml

批注 [z29]: 说明 name 属性是由firstName 和 lastName 两个属性组成。

package com.it315.domain;

public class User {private int id;private Name name;private int age;get(),set()方法省略......

}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.it315.domain">

<class name="User" table="User"><id name="id">

<generator class="native" /></id>

<component name="name">

</component>

<property name="age" column="user_age"></property></class>

</hibernate-mapping>

<property name="firstName" column="first_name" />

<property name="lastName" column="last_name" />

package com.it315.test;
import org.hibernate.Session;
import org.hibernate.Transaction;import com.it315.domain.Name;
import com.it315.domain.User;
import com.it315.util.HibernateUtils;

public class Test {
public static void
main(String[] args) {

User user = new User();user.setAge(20);

Name name = new Name();name.setFirstName("zhang");name.setLastName("san");

○4 Test.java

传智博客—赵涵笔记 25

批注 [z30]: 表中会多加一个字段,用来记录保存数据的顺序,读取的时候就会按照这个字段上的值的顺序读取。

user.setName(name);

Session session = null;Transaction tc = null;try{

session = HibernateUtils.getSession();tc = session.beginTransaction();

session.save(user);

tc.commit();}finally{

if(session != null){session.close();

}}

}}

CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,`first_name` varchar(255) default NULL,`last_name` varchar(255) default NULL,`user_age` int(11) default NULL,PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=gbk;

......
<list name = “employee”>

<key column = “depart_id” />

<one-to-many class = “Employee” /></list>

......

<list-index column = “order_col” />

○5 表的定义语句

讨论映射集合为什么用 set?......
private list employees;......

如果改用 list 的话,读取的时候就会按照保存的顺序读取,例如:

因为我们读取数据时候对读取的顺序并没有要求,所以不必要耗费系统资源用 list 读取。如果想用 list,但又不需要顺序的话,可以这样:

传智博客—赵涵笔记 26

批注 [z31]: Bag 的底层借助 List 实现,但却屏蔽了 List 的有序性。Bag集合为无序集,且允许出现重复元素,是 Hibernate 自定义的集合类型。

批注 [z32]: 表示放弃维护关系,默认是 false.

......
< name = “employee”>

<key column = “depart_id” />

<one-to-many class = “Employee” /></bag>

......

bag

......

......

teacher1.setStudents(set2);teacher2.setStudents(set2);student1.setTeachers(set1);student2.setTeachers(set1);

......
<set name="teachers" table="teacher_student" >

<key column="student_id" />

<many-to-many class="Teacher" column="teacher_id" /></set>

......

inverse="true"

static void save() {
Session session = null;

Transaction tc = null;try {

session = HibernateUtils.getSession();tc = session.beginTransaction();

Department depart = new Department();depart.setName("jishu");session.save(depart);

Set<Employee> set = new HashSet<Employee>();

Inverse和cascade(Employee-Department)○1 在上面“多对多”的例子中,如果:

这样会报 错,发 生主键 冲突。
这时候可 以放弃 学生的 维护关 系,这 样在保 存学生 的时候 就不 会在中 间表中 产生数 据。

One-to-many 维护关联关系就是更新外键;many-to-many 维护关联关系就是在中间表增减记 录。

注意:配置 one-to-one 的对象不维护关联关系。
如果使用
List 的话,为了保持顺序,不能放弃对关系的维护。

○2 在上面“一对多”的例子中,将 Test.java 中的 save()方法改为:

传智博客—赵涵笔记 27

批注 [z33]: 设置级联保存和更新。当保存部门的时候,连同与它有关的其他对象信息一并保存。

Employee emp = new Employee();emp.setAge(20);emp.setName("lisa");emp.setDepart(depart);//session.save(emp);set.add(emp);

Employee emp1 = new Employee();emp1.setAge(21);emp1.setName("zhangsan");emp1.setDepart(depart);//session.save(emp1);set.add(emp1);

System.out.println("-------------------");depart.setEmployee(set);
tc.commit();

} finally {
if (session != null) {

session.close();}

}

<set name="employee" inverse="true"

<key column="depart_id"></key><one-to-many class="Employee" />

</set>

cascade="save-update"

>

package com.it315.domain;

public class Skiller extends Employee {private String skill;get(),set()方法省略......

}

然后在 Department.hbm.xml 文件中:

一般对 many-to-one 和 many-to-many 不设置级联,在 one-to-one 和one-to-many 中设置级联。

继承的映射○1 Skiller.java

传智博客—赵涵笔记 28

○2 Sales.java

○3 Employee.java

批注 [z34]: 普通员工的值是 0.

批注 [z35]: 定义了一个鉴别器,类型为 int 型,列名是 type.

批注 [z36]: 技术员工的值是 1,也可以都不赋值,如果不赋值的话,默认在表的字段中用包名+类名区分。

package com.it315.domain;

public class Sales extends Employee {private int sell;get(),set()方法省略......

}

package com.it315.domain;

public class Employee {private int id;private String name;private int age;

public String toString() {
return "id=" + this.id + "name=" + this.name;

}}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping

package="com.it315.domain">
<class name="Employee" table="Emlpoyee"

<id name="id">
<generator class="native"/>

</id>

<property name="name" column="employee_name" /><property name="age" column="employee_age" /><subclass name="Skiller"

<property name="skill" /></subclass>

<subclass name="Sales" discriminator-value="2"><property name="sell" />

</subclass>

</class></hibernate-mapping>

>

>

discriminator-value="0"

<discriminator type="int" column="type"/>

discriminator-value="1"

○4 Employee.hbm.xml

传智博客—赵涵笔记 29

○5 Test.java

package com.it315.test;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;import com.it315.domain.Employee;import com.it315.domain.Sales;
import com.it315.domain.Skiller;import com.it315.util.HibernateUtils;

public class Test {
public static void
main(String[] args) {

add();

select();}

static void add() {
Session session = null;Transaction tc = null;try {

session = HibernateUtils.getSession();tc = session.beginTransaction();

Employee em1 = new Employee();em1.setAge(20);em1.setName("el1");

Skiller em2 = new Skiller();em2.setAge(30);em2.setName("e2");em2.setSkill("skill");

Sales em3 = new Sales();em3.setAge(40);em3.setName("e3");em3.setSell(15);

session.save(em1);session.save(em2);session.save(em3);

tc.commit();} finally {

if (session != null) {

传智博客—赵涵笔记 30

session.close();}

}}

static void select() {Session session = null;try {

session = HibernateUtils.getSession();String hql = "from Employee";
Query q = session.createQuery(hql);System.out.println(q.list());

} finally {
if (session != null) {

session.close();}

}}

}

Hibernate: insert into Emlpoyee (employee_name, employee_age, type)values (?, ?, 0)
Hibernate: insert into Emlpoyee (employee_name, employee_age, skill,type) values (?, ?, ?, 1)

Hibernate: insert into Emlpoyee (employee_name, employee_age, sell, type)values (?, ?, ?, 2)
Hibernate: select employee0_.id as id0_, employee0_.employee_name asemployee3_0_, employee0_.employee_age as employee4_0_, employee0_.skillas skill0_, employee0_.sell as sell0_, employee0_.type as type0_ fromEmlpoyee employee0_

[id=1name=el1, id=2name=e2, id=3name=e3]

CREATE TABLE `emlpoyee` (
`id` int(11) NOT NULL auto_increment,`type` int(11) NOT NULL,
`employee_name` varchar(255) default NULL,`employee_age` int(11) default NULL,`skill` varchar(255) default NULL,
`sell` int(11) default NULL,
PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

○6 运行结果:

○7 生成表的定义语句:

传智博客—赵涵笔记 31

因为在技 术和销 售两个 类里可 能会有 多个字 段,所 以放在 一张表 里会对 系统的 优化造 成影响。所以 要将每 个子类 建立一 张表。
Employee.hbm.xml

批注 [z37]: 生成的表名:skiller.

批注 [z38]: 查询有关 skiller 的信息,会根据这个 emp-id 外键字段去查找。

<class name="Employee" table="Emlpoyee"><id name="id">

<generator class="native"/></id>

<property name="name" column="employee_name" /><property name="age" column="employee_age" /><joined-subclass name="Skiller" table=" ">

<key column="

<property name="skill" /></joined-subclass>
<joined-subclass name="Sales" table="sales">

<key column="emp_id" />

<property name="sell" /></joined-subclass>

</class>

skiller

emp_id

Hibernate: insert into Emlpoyee (employee_name, employee_age) values(?, ?)
Hibernate: insert into Emlpoyee (employee_name, employee_age) values(?, ?)

Hibernate: insert into skiller (skill, emp_id) values (?, ?)Hibernate: insert into Emlpoyee (employee_name, employee_age) values(?, ?)
Hibernate: insert into sales (sell, emp_id) values (?, ?)
Hibernate: select employee0_.id as id0_, employee0_.employee_name asemployee2_0_, employee0_.employee_age as employee3_0_,employee0_1_.skill as skill1_, employee0_2_.sell as sell2_, case whenemployee0_1_.emp_id is not null then 1 when employee0_2_.emp_id is notnull then 2 when employee0_.id is not null then 0 end as clazz_ from Emlpoyeeemployee0_ left outer join skiller employee0_1_ onemployee0_.id=employee0_1_.emp_id left outer join sales employee0_2_ onemployee0_.id=employee0_2_.emp_id
[id=1name=el1, id=2name=e2, id=3name=e3]

CREATE TABLE `emlpoyee` (
`id` int(11) NOT NULL auto_increment,`employee_name` varchar(255) default NULL,`employee_age` int(11) default NULL,

" />

运行结果:

这种映射 在效率 上不是 很理想 。生成表的 定义语 句:

传智博客—赵涵笔记

32

PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `sales` (
`emp_id` int(11) NOT NULL,
`sell` int(11) default NULL,
PRIMARY KEY (`emp_id`),
KEY `FK682490C46FD469B` (`emp_id`),
CONSTRAINT `FK682490C46FD469B` FOREIGN KEY (`emp_id`) REFERENCES

`emlpoyee` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `skiller` (
`emp_id` int(11) NOT NULL,
`skill` varchar(255) default NULL,
PRIMARY KEY (`emp_id`),
KEY `FK7FFD86BE46FD469B` (`emp_id`),
CONSTRAINT `FK7FFD86BE46FD469B` FOREIGN KEY (`emp_id`) REFERENCES

`emlpoyee` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

<class name="Employee" table="Employee"><id name="id">

<generator class="native" /></id>

<property name="name" column="employee_name"/><property name="age" column="employee_age" /><discriminator column="type" />
<subclass name="Skiller">

<property name="skill" /></subclass>

<subclass name="Sales"><join table="sales">

<key column="employee_id" />

<property name="sell" /></join>

</subclass>

</class>

如果销售 类中有 很多字 段,而 技术类 中只有 很少字 段,那 么需要 混合使 用“一 个类继 承体系 一张表”和“ 每个子 类一张 表”。

懒加载
利用上面 “组件 映射” 那个例 子:
传智博客—赵涵笔记
33

Lazy.java

批注 [z39]: 这里调用了 user 的getAge()方法,那么会去访问数据库,但此时 session 已经关闭,所以这里会抛出代理没有初始化的异常。

package com.it315.test;
import org.hibernate.Session;
import org.hibernate.Transaction;import com.it315.domain.Name;
import com.it315.domain.User;
import com.it315.util.HibernateUtils;

public class lazy {
public static void
main(String[] args) {

add();
User user = select();System.out.println( );

}

static void add() {
User user = new User();user.setAge(20);

Name name = new Name();name.setFirstName("zhang");name.setLastName("san");

user.setName(name);

Session session = null;Transaction tc = null;try {

session = HibernateUtils.getSession();tc = session.beginTransaction();

session.save(user);

tc.commit();} finally {

if (session != null) {session.close();

}}

}

static User select() {Session session = null;User user = null;
try {

session = HibernateUtils.getSession();

user.getAge()

传智博客—赵涵笔记 34

批注 [z40]: 调用 load()方法返回的是一个代理对象,里面没有值,只有第一次去调用它的方法的时候才会去数据库里查询。

批注 [z41]: 初始化代理对象,传的参数必须是代 理对象 。

} finally {
if (session != null) {

session.close();}

}

return user;}

}

user

= (User)session.load(User.class, 1);

static User select() {
Session session = null;

User user = null;try {

session = HibernateUtils.getSession();user = (User)session.load(User.class, 1);

;

} finally {
if (session != null) {

session.close();}

}

return user;}

}

Hibernate.initialize(user)

......
<class name="Door" table="door">

<id name="id">
<generator class="foreign">

<param name="property">room</param>

用 load()实现懒加载必须保证 session 没有关闭。Hibernate 提供了一种代理对象初始化的方法:

这时候再 运行上 面那段 程序, 就不会 出现异 常了。

○1 一对一懒加载
必须同时 满足下 面三个 条件, 才能实 现懒加 载。
Lazy != false
Constrained = true
Fetch = select

因为查找 room 的时候一般需要一同把 door 的信息列出来,而查找 door 的时候却不一定要把房间的信息列出来,所以在次我将 room 设为懒加载。

Door.hbm.xml

传智博客—赵涵笔记 35

批注 [z42]: 默认设置。使用代理的方式懒加载。

批注 [z43]: Fetch 是设置通过 door 获取 room 的信息时的抓取方式。Join是一条 select 语句全部查询出来,这样无法实现懒加载,所以用 select。必须通过第二条 select 语句才能查询处 room 的信息。(select 是默认配置)

批注 [z44]: Door 不是代理对象,我们设置的 Room 是代理对象,所以我们将 Room 作为参数传进去。

</generator></id>

<property name="number" />
<one-to-one name="room"
constrained="true"

/>

</class>......

lazy="proxy"

fetch="select"

package com.it315.test;
import org.hibernate.Hibernate;import org.hibernate.Session;
import com.it315.domain.Door;
import com.it315.util.HibernateUtils;

public class Lazy {
public static void
main(String[] args) {

Test.add();
Door door =
select();System.out.println(door.getRoom());

}

static Door select() {Session session = null;Door door = null;
try {

session = HibernateUtils.getSession();door = (Door) session.get(Door.class, 1);

;

} finally {
if (session != null) {

session.close();}

}

return door;}

}

Hibernate.initialize(door.getRoom())

Lazy.java

○2 一对多懒加载必须满足 以下两 个条件 :Lazy != falseFetch = select

因为默认的配置就是 lazy =传智博客—赵涵笔记

proxy,fetch =

select,所以配置文件不需要修改。

36

Lazy.java

批注 [z45]: 当确定只有一个结果的时候用 uniqueResult()方法,否则用list().

package com.it315.test;
import org.hibernate.Hibernate;import org.hibernate.Session;
import com.it315.domain.Department;import com.it315.util.HibernateUtils;

public class Lazy {
public static void main(String[] args) {

Test.save();
Department depart =
select();System.out.println(depart.getEmployee());

}
static Department
select(){

Session session = null;Department depart = null;try{

session = HibernateUtils.getSession();
depart = (Department)session.get(Department.class, 1);
Hibernate.initialize(depart.getEmployee());

}finally{
if(session != null){

session.close();}

}

return depart;}

}

static void select(){
Session session = null;

List list = null;try{

session = HibernateUtils.getSession();
String hql = "from Department as depart where depart.name=:n";Query q = session.createQuery(hql);q.setString("n","jishu");
Department depart = (Department) ;

/*

q.uniqueResult()

若不想使用懒加载,只需要在配置文件中将 lazy 的值改为 false,或者将 fetch 的值改为 join.

HQL和Criteria一.最简单 HQL 的查询:

传智博客—赵涵笔记 37

批注 [z46]: 其实索引。
批注
[z47]: 获取最大记录数。

list = q.list();
for(Iterator iter = list.iterator();iter.hasNext();){

Department depart = (Department)iter.next();

System.out.println(depart.getName());}

*/

}finally{
if(session != null){

session.close();}

}}

Query q = session.createQuery(hql);
List list = q.list();
for(Iterator iter = list.iterator();iter.hasNext();){

Object[] rs = (Object[])iter.next();Department d1 = (Department)rs[0];Employee e1 = (Employee)rs[1];

}

setFirstResult(begin)

setMaxResults(count)

;

Criteria crit = session.createCriteria(Department.class);list = crit.list();
for(Iterator iter = list.iterator();iter.hasNext();){

Department depart = (Department)iter.next();

System.out.println(depart.getName());}

Criteria crit = session.createCriteria(Department.class);

○1 如果查询语句是这样:
String hql = “select depart,emp from Department depart,Employee asemp ”+”where depart.id=emp.depart.id and depart.id=:id”;
应当这样 遍历:

查询几个 对象, 数组长 度就是 几。

○2 如果查询语句是这样:
String hql = “from java.lang.Object”;这样的 hql 语句会将所有的对象都查一遍。

○3 分页
q. ;

q.

二 . Criteria○1

○2

传智博客—赵涵笔记 38

crit.add(

crit.add(

crit.addOrder(

list = crit.list();

Restrictions.eq("name","jishu")

);

批注 [z48]: 属性 name 的值必须是jishu.

批注 [z49]: Id 必须在 1 和 10 之间。批注 [z50]: 按照 id 的倒序排列。

Restrictions.between("id", 1, 10)

);

Order.desc("id")

);

crit.setFirstResult(1);crit.setMaxResults(10);

static void test() {
Session session = null;

try {
session = HibernateUtils.getSession();Department depart =

(Department)session.get(Department.class, 1);System.out.println(depart.getEmployee());

System.out.println("----------");

Department depart1 =(Department)session.get(Department.class, 1);

System.out.println(depart1.getEmployee());} finally {

if(session != null){session.close();

}}

}

相当于这样的 SQl 语句:
Select * from Department where name=”jishu” and id between 1 and 10 orderby id desc

○3 分 页

缓存一.一级缓存

○

1

两次查询的都是 id 为 1 的 Department 对象,因为有一级缓存,所以在第一次查询到了以后,将查询到的对象以及 id 值一同保存在 Map 集合中,在第二次执行相同操作的时候,就不会从数据 库里查 询,直接 去一级 缓存中 读取数 据。这也 就是为 什么只 执行了 一个查 询语句 的原因 。

如果在System.out.println("----------");这一句后面添加:session.clear();
这样就把 一级缓 存清除 了,在第 二次查 询具有 相同id的 对象的 时候,一 级缓存 中没有 数据 ,

所以会去 数据库 中查询 ,这样 就出现 了第二 条查询 语句。
如果一级 缓存中 的对象 特别多 ,只想 清空某 一个对 象的缓 存, 可以调 用evict方法 ,传参

数是对象 类型:
传智博客—赵涵笔记
39

session.evict(depart);

注意:save,update,saveOrUpdate,load,get,list,iterate,lock这些方法都将会对象 放在一 级缓存 中,一 级缓存 不能控 制缓存 的数量 ,所以 要注意 大批量 的操作 数据时 可能造成内存 溢出。

○2

static void test() {
Session session = null;

Transaction tc = null;try {

session = HibernateUtils.getSession();tc = session.beginTransaction();Department depart =

(Department)session.get(Department.class, 1);System.out.println(depart.getName());

depart.setName("sell");

tc.commit();} finally {

if(session != null){session.close();

}}

}

......<hibernate-configuration>

<session-factory>
<property name="hibernate.dialect">

org.hibernate.dialect.MySQLDialect</property>

<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver

</property>

此时对象为持久状态,所以它的值可以修改,并且生成了updaet语句。

如果在depart.setName(“sell”);这句下面清除一级缓存,那么将不会生成update语句,并且表中的字段也不会修改。因为它的更新是根据一级缓存来和数据库进行同步的。调用setName()方法的时候是不会更新数据的,它的属性值全在一级缓存里,只有在提交事务的时候才会更新数据库。这时候如果将一级缓存清掉,hibernate将无法检测到这种属性变化。

一级缓存的作用范围是很小的,当session关闭,那么一级缓存中的数据也不在了。

二.二级缓存

Update,saveorUpdate,list,iterator,get,load,一级Query,Criteria都会填充二 级缓存 。Save这 个 方法 不适合 native生成 方式的 主键 。
○1
hibernate.cfg.xml

传智博客—赵涵笔记 40

<property name="hibernate.connection.url">jdbc:mysql:///zhaohan

</property>
<property name="hibernate.connection.username">root</property><property name="hibernate.connection.password">123</property><property name="hbm2ddl.auto">create</property>
<property name="show_sql">true</property>

<property name="cache.use_second_level_cache"> </property>

<property name="cache.provider_class">

</property>
<mapping resource="com/it315/domain/Department.hbm.xml" /><mapping resource="com/it315/domain/Employee.hbm.xml" />

<class-cache usage=" "

</session-factory></hibernate-configuration>

true

批注 [z51]: True 为默认值,打开二级缓存。(Hiberna te.pr oper ties文件中第 479 行。)

批注 [z52]: 表示用HashtableCacheProvider 这个缓存实现。(Hibernate.properties 文件中第 494 行提供了多种缓存实现。)

批注 [z53]: 说明缓存中的数据是只读的,不能更改,这样就不需要手工清除缓存;
usage=" read- write "说明放入缓存中的数据是可读可写的。

批注 [z54]: 表示对哪个对象实现二级缓存。

org.hibernate.cache.HashtableCacheProvider

read-write

/>

class="com.it315.domain.Department"

static void cache(){
Session session = HibernateUtils.getSession();
Department depart = (Department)session.get(Department.class,

1);

1);

System.out.println(depart.getName());session.close();

System.out.println("---------------");
Session session1 = HibernateUtils.getSession();

Department depart1 = (Department)session1.get(Department.class,

System.out.println(depart1.getName());

session1.close();}

Hibernate: select department0_.id as id0_0_,department0_.department_name as department2_0_0_ from Departmentdepartment0_ where department0_.id=?
jishu
---------------
jishu

Test.java

运行结果:

传智博客—赵涵笔记 41

两次查询 都是查 询同一id 的同一 对象, 第二次 查询默 认会 去一级 缓存中 查找, 这时候 发现session已经关闭,一级缓存中没有数据,然后会去二级缓存中查找。(二级缓存中没有才会去数据 库中查 找)发 现二级 缓存中 有这个 对象, 所以只 出现 了一条select 语句。

○2HibernateUtils.java

批注 [z55]: 打开统计信息,默认为true.

package com.it315.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;

public final class HibernateUtils {
private static SessionFactory sessionFactory;static {

Configuration cfg = new Configuration();
sessionFactory = cfg.configure().buildSessionFactory();

}
public static SessionFactory
getSessionFactory(){

return sessionFactory;}

public static Session getSession(){return sessionFactory.openSession();

}}

......

<property name="cache.use_second_level_cache">true</property><property name="cache.provider_class">

org.hibernate.cache.HashtableCacheProvider</property>

<property name="generate_statistics"> </property>

<class-cache usage="read-write"class="com.it315.domain.Employee" />

<class-cache usage="read-only"class="com.it315.domain.Department" />

......

true

public class Test {
public static void main(String[] args) {

save();cache();

Hibernate.cfg.xml

Test.java

传智博客—赵涵笔记 42

批注 [z56]: 得到统计信息。(只统计二级缓存,不统计一级缓存)

Statistics s =

System.out.println("往二级缓存中放了"+s.getSecondLevelCachePutCount()+"次");

;

System.out.println("命中了"+s.getSecondLevelCacheHitCount()+" 次

");

System.out.println(s.getSecondLevelCacheMissCount()+"次在缓存中没有找到");

}

static void save() {
Session session = null;

Transaction tc = null;try {

session = HibernateUtils.getSession();tc = session.beginTransaction();

Department depart = new Department();depart.setName("jishu");session.save(depart);

Set<Employee> set = new HashSet<Employee>();

Employee emp = new Employee();emp.setAge(20);emp.setName("lisa");emp.setDepart(depart);set.add(emp);

Employee emp1 = new Employee();emp1.setAge(21);emp1.setName("zhangsan");emp1.setDepart(depart);set.add(emp1);

depart.setEmployee(set);

tc.commit();

} finally {
if (session != null) {

session.close();}

}

HibernateUtils.getSessionFactory().getStatistics()

传智博客—赵涵笔记 43

}

static void cache(){
Session session = HibernateUtils.getSession();
Department depart = (Department)session.get(Department.class,

1);

1);

}

System.out.println(depart.getName());
session.close();
System.out.println("---------------");
Session session1 = HibernateUtils.getSession();
Department depart1 = (Department)session1.get(Department.class,

System.out.println(depart1.getName());session1.close();

Hibernate: insert into Department (department_name) values (?)Hibernate: insert into Emlpoyee (employee_name, employee_age, depart_id)values (?, ?, ?)
Hibernate: insert into Emlpoyee (employee_name, employee_age, depart_id)values (?, ?, ?)
Hibernate:
select department0_.id as id0_0_,department0_.department_name as department2_0_0_ from Departmentdepartment0_ where department0_.id=?
jishu
---------------
jishu

往二级缓 存中放 了1次

批注 [z57]: 这一次是第一回查询Department 对象的时候,将查询到的department 放进缓存中。

批注 [z58]: 第二次查找 Department对象的时候是从二级缓存中查找到的。

批注 [z59]: 第一次查询 Department对象的时候会去缓存中查找,没有查找到,所以去数据库中查找的。

批注 [z60]: 保存一个部门和两个员工信息的时候放进二级缓存,共放了三次。

批注 [z61]: 两次查找部门信息都是从二级缓存中读取,所以命中两次,没有生成 select 语句。

命中了1次

1次在缓存 中没有 找到

jishu---------------jishu

往二级缓 存中放 了3次

命中了2次

运行结果是:

查看命中次数 有助于 对程序 的优化,如果二 级缓存 中保存 的对象 有很多 ,而命 中率却 很少的话,那 就浪费 了资源 。

执行save操作的时候,是会把保存的对象放进二级缓存中的,因为save方法是否将对象放进二级缓存是和主键生成策略有关的,如果是native的话,就不会把对象放进二级缓存。上例中Department和Employee两个主键生成方式都是native,所以在保存两个对象的时候不会放进二级缓存中。

如果将两 个对象 的主键 生成方 式都改 成hilo,那 么执行 的结 果为:

传智博客—赵涵笔记 44

批注 [z62]: 在缓存中查找数据都查找到了,所以没有 miss.

0次在缓存 中没有 找到

static void cache(){
Session session = HibernateUtils.getSession();
Department depart = (Department)session.get(Department.class,

1);

1);

System.out.println(depart.getName());session.close();

System.out.println("---------------");
Session session1 = HibernateUtils.getSession();

Department depart1 = (Department)session1.get(Department.class,

System.out.println(depart1.getName());session1.close();

Session session2 = HibernateUtils.getSession();

String hql = "from Employee emp where emp.id = 32768";Query q = session2.createQuery(hql);
Employee em = (Employee)q.uniqueResult();System.out.println(em.getAge());

session2.close();}

jishu
---------------
jishu
Hibernate:
select employee0_.id as id1_, employee0_.employee_name asemployee2_1_, employee0_.employee_age as employee3_1_,employee0_.depart_id as depart4_1_ from Emlpoyee employee0_ whereemployee0_.id=32768
20
往二级缓 存中放 了3次
命中了2次

有三个方法会从二级缓存中读取数据:iterator,get,load。Iterator方法指的是Query的 iterator方法 。例如:

Iterator iter = query.iterate();Iter.next();

使用下面 例子进 行说明 :

○1 HQL查询

运行结果:

传智博客—赵涵笔记 45

批注 [z63]: 这个信息是从缓存中查询的。

0次在缓存 中没有 找到

static void cache(){
Session session = HibernateUtils.getSession();String hql = "from Employee";
Query q = session.createQuery(hql);
Iterator iter = q.iterate();while(iter.hasNext()){

Employee em = (Employee)iter.next();

System.out.println(em.getName());}

session.close();System.out.println("----------------");

Session session1 = HibernateUtils.getSession();
Employee em = (Employee)session1.get(Employee.class, 32768);System.out.println(em.getAge());

session1.close();}

Hibernate: select employee0_.id as col_0_0_ from Emlpoyee employee0_Hibernate: select employee0_.id as id1_0_, employee0_.employee_name asemployee2_1_0_, employee0_.employee_age as employee3_1_0_,employee0_.depart_id as depart4_1_0_ from Emlpoyee employee0_ whereemployee0_.id=?

lisa
Hibernate:
select employee0_.id as id1_0_, employee0_.employee_name asemployee2_1_0_, employee0_.employee_age as employee3_1_0_,employee0_.depart_id as depart4_1_0_ from Emlpoyee employee0_ whereemployee0_.id=?
zhangsan
----------------

往二级缓 存中放 了2次命中了1次
2次在缓存 中没有 找到

20

HQL查询会生成select语句从数据库中查找,不会去二级缓存中去查找。所以建议在根据id查找数 据的时 候要用get 方法。

○2 iterator方法

运行结果:

这样如果 有N个对 象,那 么就会 出现N+1条 查询语 句。如 果缓 存中没 有对象 但遍历 的对象 又很多的情 况下,用iterator 方法的 话并不 是很好,但若是 第二次 查询的 话,会把 系统优 化很多 。

查询缓存:

传智博客—赵涵笔记 46

上面例一中,HQL查询不会去缓存中查找,我们可以通过配置使Query和Criteria都从缓存中查 找,但是因 为命 中率较 低,所以默 认配置 是关闭 的。(hibernate.properties 文件中第484行)

通过Query或Criteria 查找数 据库得 到的结 果集,hibernate 会把 查询语 句当作key,把返回结 果的id做 为value存到 缓存里 去。那 么第二 次执 行相 同 查询语 句 的时候,发现缓 存里有相关信 息,那么 就会拿 到缓存 中所有id 的集合,然后再 根据id去 一级缓 存和二 级缓存 中去找 ,找不到就 去数据 库中查 找。

将cache.use_query_cache配置为true打开查询缓存,并且调用query.setCacheable(true)或criteria.setCacheable(true)。

注意:查 询缓存 不是一 级缓存 ,也不 是二级 缓存。 如果没 有十 足把握 ,不要 打开查 询缓存,这样 会对性 能有严 重影响 。

清除二级缓存:

批注 [z64]: 将缓存中的所有Department 对象全部清除。如果只想清除 id 为 1 的 Department 对象,只需要:
evict(D epart ment. clas s,1)

static void cache(){
Session session = HibernateUtils.getSession();
Department depart = (Department)session.get(Department.class,

1);

1);

}

System.out.println(depart.getName());session.close();

System.out.println("---------------");

Session session1 = HibernateUtils.getSession();
Department depart1 = (Department)session1.get(Department.class,

System.out.println(depart1.getName());session1.close();

HibernateUtils.getSessionFactory().evict(Department.class);

jishu
---------------
Hibernate:
select department0_.id as id0_0_,department0_.department_name as department2_0_0_ from Departmentdepartment0_ where department0_.id=?
jishu
往二级缓 存中放 了4次
命中了1次
1次在缓存 中没有 找到

.......

运行结果:

换OSCacheProvider缓存实现:

传智博客—赵涵笔记 47

批注 [z65]: “sql”参数为配置文件中的命名查询名称。

<property name="cache.provider_class">

org.hibernate.cache.OSCacheProvider

</property>

......

......

<class name="Department" table="Department"><id name="id">

<generator class="hilo" /></id>

<property name="name" column="department_name"></property><set name="employee" inverse="true" cascade="save-update">

<key column="depart_id"></key>

<one-to-many class="Employee" /></set>

</class>

<query name="sql">
from Department depart where depart.id = 1

</query>......

static void cache(){
Session session = HibernateUtils.getSession();Query q = session. ;

Department depart = (Department)q.uniqueResult();System.out.println(depart.getName());session.close();

}

getNamedQuery("sql")

for(int i=0;i<1000000;i++){

只需要将原来的缓存实现换成OSCacheProvider,并且把OSCacheProvider包oscache-2.1.jar导入。

使用缓存的条件:

1. 读取大于修改
2. 数据量不能超过内存容量3. 对数据要有独享的控制4. 可以容忍出现无效数据

将查询语句写在配置文件中

注意大批量操作的问题
大批量的 操作数 据时可 能造成 内存溢 出,解 决办法 如下:

1. 清除session中的数据

传智博客—赵涵笔记 48

批注 [z66]: 只能出现在字段上,不能出现在方法上.

批注 [z67]: 默认设置是 CLASS,但设置成 RUNTIME 才能获取到这个Annotation.

Session.save(obj);if(i%50==0){

session.flush();

session.clear();}

}

package com.it315.jpa;
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;

@Retention(RetentionPolicy.public @interface HelloWorld {}

@Target(ElementType.FIELD)

RUNTIME

)

package com.it315.jpa;public class TestBean {

@HelloWorld
private String name;private int age;get(),set()方法省略......

}

package com.it315.jpa;
import java.lang.annotation.Annotation;import java.lang.reflect.Field;

public class Test {
public static void main(String[] args)
throws SecurityException,

每当有50条数据的 时候, 就和数 据库同 步一次 ,然 后清除 一级缓 存中的 对象。

2. 用StatelessSession接口,它没有一级缓存,也不和二级缓存,查询缓存交互,通过该接口的操作会立即发送给数据库,与JDBC的功能一样。
StatelessSession s = sessionFactory.openStatelessSession();该接口的方法和session类似。

Annotation
○1 HolloWorld.java

@Target({ElementType.METHOD,ElementType.FIELD})既可以出现在字段上,也可以出 现在方 法上。 里面是 一个数 组,要 中花括 号括起 来。

○2 Bean.java

○3 Test.java

传智博客—赵涵笔记 49

NoSuchFieldException {

test();}

static void test() throws SecurityException, NoSuchFieldException {Class = TestBean.class;

Field

Boolean b = field.
if (b) {
Annotation annotation = field. ;

System.out.println(annotation.getClass());} else {

System.out.println("没有这个Annota tion");}

}}

clazz

批注 [z68]: 得到的Class就是Bean类在硬盘上的描述信息,连同他上面的注解一同可以得到。

批注 [z69]: Name字段的信息全部封装在Field对象里去了,包括字段上的注解。

批注 [z70]: 看 name 字段上是否有helloWorld 这个 Annotation.

批注 [z71]: 得到 HelloWorld 这个Annotation.

field

= clazz.getDeclaredField("name");

isAnnotationPresent(HelloWorld.class)

;

getAnnotation(HelloWorld.class)

package com.it315.jpa;
import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)public @interface Notnull {
}

package com.it315.jpa;

public class TestBean {@Notnull

private String name;private int age;get(),set()方法省略......

}

package com.it315.jpa;
import java.lang.annotation.Annotation;import java.lang.reflect.Field;

public class Test {
public static void
main(String[] args) throws SecurityException,

例:不允许name字段为空○1 Notnull.java

○2 Bean.java

○3 Test.java

传智博客—赵涵笔记 50

NoSuchFieldException {

Bean tb = new Bean();checkNull(tb);

}

static void checkNull(TestBean tb) throws SecurityException,NoSuchFieldException {

Class clazz = TestBean.class;
Field field = clazz.getDeclaredField("name");if(field.isAnnotationPresent(Notnull.class)){

String name = tb.getName();if(name == null){

throw new RuntimeException("名字不得为空!");}

}}

}

Exception in thread "main" java.lang.RuntimeException: 名字不得为空!at com.it315.jpa.Test.checkNull(Test.java:34)
at com.it315.jpa.Test.main(Test.java:13)

○4 运行结果(name并为赋值):

传智博客—赵涵笔记 51

hibernate配置 介绍了hibernate的两种方法,所用myeclipse版本为8.6,数据库为mysql,按步骤即可完成hibernate配置 立即下载

相关推荐

hibernate基本配置

学过hibernate自己做得简单总结

Hibernate 配置文件(hibernate.cfg.xml、hbm.xml)

hibernate.xml 配置 Hibernate 的全局环境。

weixin_57558097的博客 3877

Hibernate配置

NULL 博文链接:https://hi-beijing.iteye.com/blog/1174299

Hibernate 配置

使用注解:这是最常见的方式,实体类使用 JPA 注解来定义映射关系。使用 XML 文件:可以在实体类之外定义一个 XML 文件来定义映射关系。混合使用:可以结合使用注解和 XML 文件。

qq_33240556的博客 1499

仿真每日一练 | Workbench下薄板疲劳分析

今天给大家介绍Workbench下薄板疲劳分析,采用稳态分析模块进行评估。完成求解后,插入疲劳工具,同时插入对应的寿命进行查看,如图7和图8所示。采用稳态分析模块,导入几何模型,效果如图1。添加固定约束与扭矩,同时添加转速如图4所示。主要包括7要素,对应的类型见图2。求解完成后查看应力,如图6所示。1-1-3、有限元系统模型构建。1-2-1、加载条件/边界条件。1-1-1、几何模型构建。1-1-2、材料定义。1-2-2、求解设置。1-3-1、查看结果。1-3-2、评估结果。1-3-3、修正结果。

ansysxuexizhe的博客 1071

【python】epub的电子书繁体字与简体字转换

中文繁体与简体转换

xiexianyou666的博客 3088

Hibernate框架介绍以及入门 【二】Hibernate的常见配置

在面试前我整理归纳了一些面试学习资料,文中结合我的朋友同学面试美团滴滴这类大厂的资料及案例由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!大家看完有什么不懂的可以在下方留言讨论也可以关注。[外链图片转存中…(img-nFWKHbXK-1712075636824)][外链图片转存中…(img-LendfM22-1712075636825)]

2301_79058515的博客 1127

GPU基准测试全攻略:从驱动验证到深度学习环境部署

GPU基准测试是评估显卡性能与稳定性的核心方法,其原理在于通过标准化负载程序,对GPU的计算单元、显存和散热系统进行压力测试。这项技术的价值在于,它能科学量化硬件性能,确保软件环境配置正确,为深度学习、科学计算等重负载任务提供稳定基础。在实际应用场景中,无论是新卡验机、排查深度学习环境问题(如“warning: no usable gpu found”报错),还是验证“PyTorch GPU版本安装”后的实际算力,系统的基准测试都是不可或缺的工程实践环节。通过结合通用计算测试与深度学习框架验证,用户可以提前

weixin_30080745的博客 342

Hibernate执行流程分析及配置文详解

1)Session是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心,所有持久化对象必须在 session 的管理下才可以进行持久化操作。Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久层操作的数据都缓存在 session 对象处。SessionFactory 对象一旦构造完毕,即被赋予特定的配置信息(SessionFactory 对象中保存了当前的数据库配置信息和所有映射关系以及预定义的SQL语句。

棉花糖老丫 1443

Cadence Sigrity

目录 一、PowerSI 1、PowerSI仿真前设置 2、PowerSI提取S参数 (1)检查叠层 (2)选择需要提取的走线和GND (3)设置端口 (4)设置提取频率和提取方式 (5)运行仿真 一、PowerSI PowerSI是一个交流分析工具,适用于频域仿真。 S参数提取 电源阻抗提取 全波参数提取 阻抗、耦合检查 谐振分析 1、PowerSI仿真前设置 打开PCB文件: 打开后如图: 设置为单色后: 仿真前的设置:

fang_yang_wa的博客 3万+

【信息科学与工程学】【物理/化学科学和工程技术】第八篇 光学07

对于光源-探测器距离 ρ, 稳态漫反射率 R(ρ) ≈ (1/(4π)) [ z₀ (μ_eff + 1/r₁) exp(-μ_eff r₁)/r₁² + (z₀ + 2z_b) (μ_eff + 1/r₂) exp(-μ_eff r₂)/r₂² ], 其中 μ_eff = √(3μ_a(μ_a+μ_s’)), z₀=1/μ_s’, z_b 与边界条件有关。通过测量光纤各点的布里渊频移 ν_B(z) 来得到应变/温度分布:Δν_B(z) = C_ν,ε Δε(z) + C_ν,T ΔT(z)。

weixin_49199313的博客 325

Hibernate 配置使用

Hibernate核心配置与使用指南: Hibernate主要通过hibernate.cfg.xml配置数据库连接和映射关系,支持注解和XML两种实体类映射方式。使用流程包括创建SessionFactory、打开Session进行CRUD操作,最后关闭资源。配置文件包含关键参数如方言、SQL显示、自动建表策略等。

onlymscn的博客 870

OAI-5G开源通信平台实践(一)-安装 部署及RFsimulator基本测试

OAI (Open Air Interface) 是目前开源5G/4G项目中最完善、最成熟的一个,并且仍然在持续更新。其包含基站、终端及核心网网元的代码,可基于x86\arm+射频卡搭建实际硬件平台,也可在x86平台上对rf\phy等层进行模拟,做各网元协议栈的单独测试验证。本文总结了x86平台下,oai的安装及运行方式。包括NTN分支和主分支的rf simulator、nos1、端到端部署等场景的验证流程,同时总结了验证过程中遇到的问题及解决方法。

十年通信老兵的技术修炼之路——从3G到5G,从地面基站到卫星通信。 2963

hibernate学习笔记

hibernate学习笔记

congine_mcfeng的专栏 158

rk3576 适配摄像头 (mipi 双摄)

RK3576 自带两个 4-Lane DPHY 和一个 DCPHY CSI 接口,可以连接 4lane 的双摄像头,最直接的方式就是充分利用其两个 D-PHY 接口。次选方案是 DCPHY + DPHY方案,更次之方案是单DPHY,设置成分离模式,连接两颗摄像头。

weixin_35723192的博客 387

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Rhyme/Hibernate 完整学习笔记

hibernate学习笔记有道云笔记

RhymeChiang 436

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Hibernate学习笔记

目录 目录 1. 学习网址 2. 简介 2.1. ORM 2.2. 创始人 2.3. 用途 2.4. 优缺点 3. 对象关系映射 3.1. 对象-关系映射模式 3.2. 常用的O/R映射框架 4. 基础配置 4.1. 依赖包配置(Maven) 4.2. 日志环境 4.3. JUnit环境 5. Annotation 5.1. 实体类-表 映射 5.2. 属性-字段 映...

Bazinga的博客 2661

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Hibernate马士兵学习笔记

Hibernate马士兵学习笔记

lishuanglearn的博客 324

Hibernate学习笔记(hibernate详解)

很不错的笔记,无论是开发还是面试都可以参考,祥见附件:

天高任你飞 97

Hibernate Annotation学习笔记

学习笔记

baobeituping的专栏 130
上一篇: spring笔记
下一篇: Hibernate笔记2
focusjava
博客等级 码龄14年 127粉丝 528原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值