zoukankan      html  css  js  c++  java
  • 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();
    	}
    }
    
    
    
  • 相关阅读:
    数据库事务的四个隔离级别浅析
    Spring事务管理之几种方式实现事务
    SQL调优简介及调优方式
    Spring MVC工作流程图
    java中的垃圾回收机
    iOS 本地化-国际化-(App名字国际化)
    iOS-自建iPa应用分发平台
    稳定App缓存
    iOS-保存图片到(自定义)相册步骤
    iOS -根据网络状态加载图片
  • 原文地址:https://www.cnblogs.com/bugstar/p/8512826.html
Copyright © 2011-2022 走看看