hibernateNote - juedaiyuer/researchNote GitHub Wiki
#Hibernate笔记#
##源代码##
- 所需jar包(如果使用最新jar包,部分方法已经废弃或者不用)
- 测试用例
ORM 对象/关系映射
实际项目中写SQL语句不好吗?
- 不同的数据库使用SQL语法不同,比如PL/SQL与T/SQL
- 同样的功能在不同的数据库中有不同的实现方式.比如分页SQL
- 程序过分依赖SQL对程序的移植及扩展,维护等带来很大的麻烦
使用ORM框架技术
- Hibernate是java领域的一款开源的ORM框架技术
- Hibernate对JDBC进行了非常轻量级的对象封装
其它主流的ORM框架技术
- MyBatis 前身iBatis
- Toplink
- EJB 本身是JAVAEE的规范
插件Hibernate Tools
JBoss推出,简化ORM框架Hibernate,以及JBOSS Seam,EJB3等开发工作
##eclipse下的开发##
查找安装包
Help-Install new software-add
下载到本地,安装...UNTODO
在线安装
Find:Jboss-tool
选择Kepler版本
##第一个Hibernate程序##
###创建Hibernate的配置文件###
hibernate.cfg.xml
创建成功后,查看是否出现代码提示功能;如果没有需要手动导入dtd
<session-factory>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql:///hibernate?useUnicode=true&characterEncoding=UTF-8</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">ture</property>
<property name="hbm2ddl.auto">create</property>
</session-factory>
属性说明
show_sql 是否把运行时的SQL语句输出到控制台,编码阶段便于测试
format_sql 输出到控制台的SQL语句是否进行排版,便于阅读
hbm2ddl.auto 可以帮助由java代码生成数据库脚本,进而生成具体的表结构.create|update|create-drop|validate
default_schema 默认的数据库
dialect 方言,hibernate可针对特殊的数据库进行优化
//ddl生成策略
create 将原有表删除,添加记录
update 保留原有的数据
###创建持久化类###
遵循javabean设计原则
package hibernateDemo;
import java.util.Date;
public class Students {
private int sid;
private String sname;
private String gender;
private Date birthday;
private String address;
public Students() {
}
public Students(int sid, String sname, String gender, Date birthday, String address) {
this.sid = sid;
this.sname = sname;
this.gender = gender;
this.birthday = birthday;
this.address = address;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Students [sid=" + sid + ", sname=" + sname + ", gender=" + gender + ", birthday=" + birthday
+ ", address=" + address + "]";
}
}
###创建对象-关系映射文件###
Hibernate XML Mapping file(hbm.xml)
创建成功后,在cfg.xml中添加如下代码:
<mapping resource="Students.hbm.xml"/>
###Junit测试###
@Test 测试方法
@Before 初始化方法
@After 释放资源
创建源程序
NEW-Source Folder
package hibernateDemo;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
//测试类
public class StudentsTest {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init()
{
//创建配置对象
Configuration config = new Configuration().configure();
//创建服务注册对象
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
//创建会话工厂
sessionFactory = config.buildSessionFactory(serviceRegistry);
//会话对象
session = sessionFactory.openSession();
//开启事务
transaction = session.beginTransaction();
}
@After
public void destroy()
{
transaction.commit(); //先提交事务
session.close();//关闭会话
sessionFactory.close();
}
@Test
public void testSaveStudents()
{
//生成一个学生对象
Students s = new Students(1,"张三丰","男",new Date(),"武当山");
session.save(s);
}
}
##深入##
不建议直接使用JDBC的connection操作数据库,而是通过session操作数据库
session可以理解为操作数据库的对象
session与connection的关系,多对一关系,一个connection可以供多个session使用
调用session的方法,save(),update(),delete(),createQuery()等
transaction
hibernate对数据的操作都是封装到事务中,并且默认是非自动提交方式.所以session保存对象时,如果不开启事务,并且手工提交事务,对象不会真正保存在数据库当中
session详解
如何获得session对象:
openSession
getCurrentSession
如果使用getCurrentSession需要在hibernate.cfg.xml文件中进行配置
本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
- getCurrentSession在事务提交或者回滚之后会自动关闭,而openSession需要手动关闭.如果没有关闭,多次之后会导致连接池溢出
- openSession每次创建新的session对象,getCurrentSession使用现有的session对象
- getCurrentSession类似于单例模式
session对象的doWork()方法
hbm配置文件
<hibernate-mapping
schema="schemaName"
catalog="catalogName"
default-cascade="cascade_style" //级联风格
default-access="field|property|classname" //访问策略
default-lazy="true|false" //记载策略
package="packagename"
/>
<class
name="ClassName"
table="tableName"
batch-size="N"
where="condition"
entity-name="EntityName"
/>
<id
name="propertyName"
type="typename"
colunm="column_name"
length="length"
<generator class="generatorClass">
/id>
主键生成策略
##单表操作##
###单一主键###
assigned 由java应用程序负责生成(手工赋值)
native 由底层数据库自动生成标识符,如果是mysql就是increment;如果是oracle就是sequence...
组件属性
实体类中的某个属性属于用户自定义的类的对象
<component name="address" class="Address">
<property name="postcode" column="POSTCODE"></property>
<property name="phone" column="PHONE"></property>
<property name="address" column="ADDRESS"></property>
</component>
单表CRUD操作
save
update
delete
get/load(查询单个记录)
get与load区别
在不考虑缓存的情况下,get方法会在调用之后立即向数据库发出sql语句,返回持久化对象
load方法会在调用后返回一个代理对象,该代理对象只保存了实体对象的id,直到使用对象的非主键属性时才会发出sql语句
查询数据库中不存在的数据时,get方法返回NULL,load方法抛出异常org.hibernate.ObjectNotFoundException
##测试遇到的问题##
java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
导入jar包
导入hibernate的jar包(文件中lib/required)
导入Mysql的jdbc驱动
导入junit4的jar包
学会使用用户类库
方便自己
window-Preferences-Java-Build Path-User Libraries
- junit4
- hibernate-core
- mysql-jdbc
add libraries
选择上面创建的用户类库