23.Hibernate-基础.md


目录

1. ORM和Hibernare

  • O:object ; R: realtion; M:Mapping。Hibernate是其中一种实现。
  • 解决问题:对象直接保存到数据库<——>直接从数据库拿到一个对象

2. 基本开发

2.1 lib

对于版本hibernate-distribution-3.6.0.Final而言,需要jar包

  • 核心包:hibernate3.jar

  • lib\required下

    23.Hibernate-基础.md

  • lib\jpa下hibernate-jpa-2.0-api-1.0.0.Final.jar

  • 数据库驱动包:


2.2 写对象和引入对象映射

2.2.1 写对象类文件

  • 和表对应的类
package per.liyue.code.hibernatehello;
/*
* 数据库表映射类
* 类的名称和成员变量的名称属性必须和数据库一致
*/
import java.util.Date; public class Employee {
private int empId;
private String empName;
private Date workDate;
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Date getWorkDate() {
return workDate;
}
public void setWorkDate(Date workDate) {
this.workDate = workDate;
}
}

2.3 配置文件

2.3.1 配置加载映射文件

按照格式类名称.hbm.xml格式来创建,源文件可以从库文件中拷贝

配置时候注意对应关系:

  • 类与表对应
  • 类名和表名对已
  • 属性对应
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Nov 9, 2006 6:27:53 PM by Hibernate Tools 3.2.0.beta7 -->
<!-- package:类对象所在的包
auto-import:表面是自动导入包,如果设定为false,则需要在执行hql语句时候将包名写清楚:
Demo:在true时候可以写为session.createQuery("from Employee").list();
在false时候必须写为session.createQuery("from per.liyue.code.hibernatehello.Employee").list();
-->
<hibernate-mapping package="per.liyue.code.hibernatehello" auto-import="true">
<!-- 类与表的对应
name:类名称
table:表名称 -->
<class name="Employee" table="employee">
<!-- 主键 注意和类成员和表列名称的一致对应 -->
<id name="empId" column="EmpId" >
<!-- 主键的生成策略:
1.identity 自增长(mysql,db2)
2.sequence 自增长(序列), oracle中自增长是以序列方法实现
3.native 自增长【会根据底层数据库自增长的方式选择identity或sequence】
如果是mysql数据库, 采用的自增长方式是identity
如果是oracle数据库, 使用sequence序列的方式实现自增长 4.increment 自增长(会有并发访问的问题,一般在服务器集群环境使用会存在问题。) 5.assigned 指定主键生成策略为手动指定主键的值
6.uuid 指定uuid随机生成的唯一的值
7.foreign (外键的方式, one-to-one讲)
-->
<generator class="native" /> </id>
<!-- 非主键,同样一一映射
name:类的属性名称
column:表的字段名称
length:设定字段的长度,默认为255
type:设定映射表的类型,如果不写匹配类对应属性的类型
java类型:必须带完整包名:java.lang.String
hibernate类型:全部都是小写 -->
<property name="empName" column="EmpName"></property>
<property name="workDate" column="WorkDate"></property>
</class>
</hibernate-mapping>

2.3.2 配置数据库连接文件

配置文件hibernate.cfg.xml

<!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 name="foo">
<!-- 数据库连接配置 -->
<!-- 连接类 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 连接数据库 -->
<property name="hibernate.connection.url">jdbc:mysql:///hi</property>
<!-- 连接用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 连接密码 -->
<property name="hibernate.connection.password">root</property>
<!-- 数据库方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- 加载所有的映射 -->
<mapping resource="per/liyue/code/hibernatehello/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>

2.4 实现保存对象插入数据

package per.liyue.code.hibernatehello;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class App {
@Test
public void Fun(){
/*
* 创建一个对象,以便验证提交数据库
*/
Employee em = new Employee();
em.setEmpId(1);
em.setEmpName("张神马");
em.setWorkDate(new Date()); /*
* 通过Hibernate操作提交数据
*/
//获取加载配置文件
Configuration config = new Configuration();
config.configure();//默认加载src下的hibernate.cfg.xml文件
//创建session工程
SessionFactory sf = config.buildSessionFactory();
//创建一个会话,表示和数据库的一个连接
Session session = sf.openSession();
//开启事务
Transaction tx = session.beginTransaction();
//保存数据库
session.save(em);
//提交事务
tx.commit();
//关闭资源
session.close();
sf.close();
}
}

3. 常见错误

3.1 重复匹配

Exception : org.hibernate.MappingException: Repeated column in mapping for entity

检查配置文件.hbm.xml中的属性标签是否多个标签匹配了同一个数据库列

3.2表属性设置

org.hibernate.exception.GenericJDBCException: could not insert: [per.liyue.code.hibernatehello.Employee] at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140) at org.hibernate.exception.SQLStateConverter.co

对应的表主键是自增长才能匹配配置文件中的

3.3程序执行成功且hibernate生成sql语句,但是数据库中没有数据

没有开启或者提交事务!

4. API详解

4.1 Configuration 配置管理类对象

  • config.configure(); 加载主配置文件的方法(hibernate.cfg.xml); 默认加载src/hibernate.cfg.xml

  • config.configure(“cn/config/hibernate.cfg.xml”); 加载指定路径下指定名称的主配置文件

  • config.buildSessionFactory(); 创建session的工厂对象

4.2 SessionFactory session的工厂(或者说代表了这个hibernate.cfg.xml配置文件)

  • sf.openSession(); 创建一个sesison对象
  • sf.getCurrentSession(); 创建session或取出session对象

4.3 Sessionsession对象维护了一个连接(Connection), 代表了与数据库连接的会话。

  • Hibernate最重要的对象: 只用使用hibernate与数据库操作,都用到这个对象
  • session.beginTransaction(); 开启一个事务; hibernate要求所有的与数据库的操作必须有事务的环境,否则报错!

4.4 Session是hibernate最重要的对象, 所有hibernate与数据库操作都需要!维护了一个与数据库的会话

4.4.1 插入记录

save()方法

4.4.2 更新记录

update()方法

saveOrUpdate()方法

4.4.3 查询记录

get()方法

load()方法

4.4.4 Demo:

将上述例子中的APP类代码修改为:

package per.liyue.code.hibernatehello;

import java.util.Date;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test; /*
* hibernate测试类
*/
public class App { //使用全局静态对象避免重复创建
private static SessionFactory sessionFactory;
static{
//这里记得一定要加载cuonfigure函数!!!
sessionFactory = new Configuration().configure().buildSessionFactory();
} /*
* 实例:插入
*/
@Test
public void insertDemo(){ Employee e = new Employee();
//这里对应的表主键,非空,自增长。才可以插入
//e.setEmpId(1);
e.setEmpName("李四");
e.setWorkDate(new Date()); //获取Session对象
Session s = sessionFactory.openSession();
//下面函数同样可以获取Session对象
//Session s = sessionFactory.getCurrentSession(); //打开事务!hibernate所有业务都需要打开事务!!!
Transaction t = s.beginTransaction(); //执行业务
s.save(e);
//提交
t.commit(); //关闭
s.close();
sessionFactory.close();
} /*
* 实例:更新
*/
@Test
public void updateDemo(){
Employee e = new Employee();
//这里对应的表主键,非空,自增长。才可以插入
e.setEmpId(1);
e.setEmpName("王五");
e.setWorkDate(new Date()); //获取Session对象
Session session = sessionFactory.openSession();
//打开事务
Transaction transaction = session.beginTransaction();
//执行业务
/*
* 更新的时候必须有主键!!!
*/
session.update(e);
//提交
transaction.commit();
//关闭
session.close();
sessionFactory.close(); } /*
* 实例:更新或保存
*/
@Test
public void updateOrSaveDemo(){
Employee e = new Employee();
//这里对应的表主键,非空,自增长。才可以插入
e.setEmpId(1);
e.setEmpName("赵二");
e.setWorkDate(new Date()); //获取Session对象
Session session = sessionFactory.openSession();
//打开事务
Transaction transaction = session.beginTransaction();
//执行业务
/*
* 1.如果没有主键则执行保存
* 2.如果有主键则执行更新
* 3.如果主键有错误则报错
*/
session.saveOrUpdate(e);
//提交
transaction.commit();
//关闭
session.close();
sessionFactory.close(); } /*
* 查询
*/
@Test
public void SelectDemo(){
//获取Session
Session session = sessionFactory.openSession();//.getCurrentSession(); //打开事务
Transaction t = session.beginTransaction(); //执行 业务
Employee employee = (Employee) session.get(Employee.class, 1);
/*
* load支持懒加载
*/
//Employee employee = (Employee) session.load(Employee.class, 1);
System.out.println(employee); //提交
t.commit();
//关闭
session.close();
sessionFactory.close(); } /*
* 删除
*/ @Test
public void DeleteOneData(){
Session s = sessionFactory.openSession();
Transaction t = session.beginTransaction(); //删除需要先查找到后再删除
Object obj = session.get(Employee.class, 2);
if(null != obj){
s.delete(obj);
} t.commit();
session.close();
sessionFactory.close();
}
}
上一篇:mybatis整合hikariCP(非spring)


下一篇:seajs+spm之再研究