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 equired下

  • libjpa下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();
	}
}


原文地址:https://www.cnblogs.com/bugstar/p/8512826.html