SSH框架之Hibernate第一篇

  • 2019 年 10 月 5 日
  • 筆記

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/zhao1299002788/article/details/100622886

1.2Hibernate的概述:  		1.2.1 什么Hibernate?  			Hibernate(开发源代码的对象关系映射框架)是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,  		是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操作数据库.Hibernate可以应用在任何使用JDBC的场合,  		既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具有革命意义的是,Hibernate可以在应用EJB的J2EE框架中取代CMP,完成数据持久化的重任.    		Hibernate就是一个持久层的ORM的框架.对JDBC做了封装.  		对JDBC做了封装: 类似咋们之前的dbutis,都对最底层的jdbc操作做了封装.    		ORM框架 : ORM框架有很多,hibernate框架只是其中的一个    		1.2.2 什么是ORM  		ORM : Object Relational Mapping对象关系映射.  		将对象与数据库中表建立映射关系,操作对象就可以操作数据库中表.就是将java类和数据库的表创建一种关系.    		好处: 创建这种关系的好处?  			以后操作这个java类,就相当于操作数据库的对应的这张表了.    		在dao层操作数据库数据 :  			JDBC+C3P0  			dbutils      		hibernate框架的作用?    			1 : 简化了Dao层的编码工作.  				大大简化了数据访问层繁琐的重复性代码,加快了运行效率.    			2 : 程序更加面向对象  				可以不需要编写SQL语句,只需要操作相应的对象就可以完成数据库数据的crud操作.  			ps : sql语句不需要自己写了,都是Hibernate底层写好了.    			Hibernate对JDBC访问数据库的代码做了轻量级封装,大大简化了数据访问层繁琐的重复性代码,并且减少了内存消耗,加快了运行效率.  			Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,它很大程度的简化了DAO(Data Access Object, 数据访问对象)层编码工作.  			Hibernate的性能非常好,映射的灵活性很出色.它支持很多关系型数据库,从一对一到多对多的各种复杂关系.  			可以扩展性强,由于源代码的开源以及API的开放,当本身功能不够用的时,可以自行编码进行扩展.    	1.3Hibernate入门  		下载Hibernate的开发包.  		解压Hibernate  		在减压的文件夹目录有:  			documentation : Hibernate的开发规范和文档.  			lib 		  : Hibernate的开发使用的jar包.  			project 	  : Hibernate的提供测试的工程.  		1.3.3 创建项目,引入jar包  			引入lib/required/*.jar  			数据库驱动包  			日志包    		1.3.4创建数据库和表  			CREATE TABLE `cst_customer` (  			  `cust_id` int AUTO_INCREMENT COMMENT '客户编号(主键)',  			  `cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',  			  `cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',  			  `cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',  			  `cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',  			  `cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',  			  `cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话',  			  PRIMARY KEY (`cust_id`)  			) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;    		1.3.5 创建实体类  		1.3.5 创建Hibernate 的映射文件  			Hibernate的映射文件只要是一个XML文件就可以了.一般映射命名 : 类名.hbm.xml    		1.3.6    "创建实体类  			<?xml version="1.0" encoding="UTF-8"?>  			<!DOCTYPE hibernate-mapping PUBLIC  			-//Hibernate/Hibernate Mapping DTD 3.0//EN"  				"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  			<hibernate-mapping>  				<!-- 建立映射关系:将类与表建立映射关系 -->  				<!--  					class标签:用于建立类与表的映射  						* name	:类的全路径  						* table	:数据库表名称  				 -->  				<class name="com.baidu.hibernate.domain.Customer" table="cst_customer">  					<!-- 建立类中的属性与表中的字段的映射 -->  					<!--  						id标签:用来建立表中的主键字段与类中的属性的映射  					 -->  					<id name="cust_id" column="cust_id">  						<!-- 主键生成策略: -->  						<generator class="native"/>  					</id>  					<!-- 其他的属性都是用property建立映射 -->  					<property name="cust_name" column="cust_name"/>  					<property name="cust_source" column="cust_source"/>  					<property name="cust_industry" column="cust_industry"/>  					<property name="cust_level" column="cust_level"/>  					<property name="cust_phone" column="cust_phone"/>  					<property name="cust_mobile" column="cust_mobile"/>  				</class>  			</hibernate-mapping>    		1.3.7 创建Hibernate核心配置文件 : 默认SRC下有个hibernate.cfg.xml文件  			<?xml version="1.0" encoding="UTF-8"?>  			<!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>  					<!-- 配置连接数据库的基本的信息 -->  					<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>  					<property name="hibernate.connection.url">jdbc:mysql:///hibernates</property>  					<property name="hibernate.connection.username">root</property>  					<property name="hibernate.connection.password">abcd</property>  					<!-- 配置Hibernate的相关属性 -->  					<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>  					<!-- 可选属性 -->  					<!-- 显示SQL -->  					<property name="hibernate.show_sql">true</property>  					<!-- 格式化SQL -->  					<property name="hibernate.format_sql">true</property>  					<!-- hbm2ddl -->  					<property name="hibernate.hbm2ddl.auto">update</property>    					<!-- 加载映射文件: -->  					<mapping resource="com/baidu/hibernate/domain/Customer.hbm.xml"/>  				</session-factory>  			</hibernate-configuration>  		1.3.8编写代码  			public void t1()  			{  				// 加载数据库核心配置文件  				Configuration con = new Configuration();  				con.configure(); //自动去加载默认地址的默认配置文件名    				// 获取session-factory  连接池  				SessionFactory factory = con.buildSessionFactory();  				// 获取session  连接对象  				Session session = factory.openSession();  				// 开启事务  				Transaction tx = session.beginTransaction();    				// 操作(面对对象)  				Customer ct = new Customer();  				ct.setCust_name("jack");  				// 保存  				session.save(ct); // sql语句虽然生成了,但是需要自己手动提交    				// 手动提交  				tx.commit();    				// 释放资源  				session.close();  				factory.close();    			}    			@Test  			public void t2()  			{  					Configuration con = new Configuration();  					con.configure();  					// 手动加载映射文件  					con.addResource("cn/baidu/domain/Customer.hbm.xml"); // 了解    					SessionFactory factory = con.buildSessionFactory();  					Session session = factory.openSession();  					Transaction tx = session.beginTransaction();      					// 操作(单条数据查询)  					/*Customer ct = session.get(Customer.class, 4L);  // 立即加载: 只要调用方法的时候就把数据全部加载出来  					System.out.println(ct);*/    					Customer ct = session.load(Customer.class, 4L);  // 延迟加载: 在调用方法的时候,先不去查询加载数据,当使用到这个数据的时候才去加载  					System.out.println(ct);    					// 重点面试题(100%): get查询和load查询的区别:  										// 1(重点): get查询是立即加载,load查询是延迟加载  										// 2 : get查询返回的是本身类型的对象,load查询返回的是代理对象  										// 3 : get查询差不多数据会返回null,load查询查不到数据会报错      					// 手动提交  					tx.commit();  					//关闭资源  					session.close();  					factory.close();      			}    			@Test  			public void t3()  			{  				Session session = HibernateUtils.openSession();  				// 开启事务  				Transaction tx = session.beginTransaction();    				// 操作(更新方式一)  				/*Customer ct = new Customer();  				ct.setCust_id(1L);  				ct.setCust_name("jackbbb");  				session.update(ct);*/    				// 更新方式二 先查再改  				Customer ct = session.get(Customer.class, 1L);  				ct.setCust_name("jackccccc");  				session.update(ct);  				// 手动提交  				tx.commit();    				// 释放资源  				session.close();    			}    			@Test  			public void t4()  			{  				Session session = HibernateUtils.openSession();  				Transaction tx = session.beginTransaction();  				//操作(删除-先查再删)  				Customer ct = session.get(Customer.class, 3L);  				session.delete(ct);  				tx.commit();  				session.close();    			}    			@Test // 如果证明咱们使用的连接是从配置好的c3p0里面获取的  			public void t5()  			{  				Session session = HibernateUtils.openSession();  				session.doWork(new Work() {    					@Override  //com.mchange.v2.c3p0.impl.NewProxyConnection  					public void execute(Connection con) throws SQLException {  						System.out.println(con.getClass().getName());  					}  				});  			}  		}  	1.4Hibernate的常见配置  		1.4.2核心配置文件的配置  		Hibernate的核心配置文件的方式有两种  		hibernate.properties	:不能加载映射文件。必须手动编写代码加载映射文件。  		hibernate.cfg.xml		:结构清晰。(工作中使用)  		Hibernate的核心配置文件中的内容:  		数据库连接基本的参数  				<?xml version="1.0" encoding="UTF-8"?>  				<!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> <!-- session-factory:连接池  session:连接对象  -->  											<!-- 5个必选项 -->  											<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>  											<property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>  											<property name="hibernate.connection.username">root</property>  											<property name="hibernate.connection.password">1234</property>  											<!-- 配置方言      分页: limit sqlserver:top oracle:sql嵌套  -->  											<!-- 作用:就是让hibernte自动的匹配符合当前数据库的sql语法 -->  											<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>    											<!-- 可选的 -->  											<!-- 集成c3p0连接池 -->  											<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>    											<!-- 让控制台输出hibernate生成的sql语句  默认是一行-->  											<property name="hibernate.show_sql">true</property>  											<!-- 可以格式化sql语句 -->  											<property name="hibernate.format_sql">true</property>    											<!-- 可以让hibernate根据配置好的映射文件自己生成表 -->  											<!--  											create: 没有 :hibernate根据映射文件创建对应的表,如果有表:删除再创建  											create-drop:没有 :hibernate根据映射文件创建对应的表,如果有表:删除再创建 ,用完就删掉  																	// 测试数据的时候使用  											update: 没有表创建表,有表使用表  											validate: 默认的值 hibernate不会创建任何表    											-->  											<property name="hibernate.hbm2ddl.auto">update</property>    											<!-- 引入映射文件地址 -->  											<mapping resource="cn/baidu/domain/Customer.hbm.xml"/>    								</session-factory>  				</hibernate-configuration>  		Hibernate的属性  		1.4.3 映射文件配置  			映射文件就是将类与表建立映射关系文件,这个文件只要是XML即可.通常名称 : 类名.hbm.xml  			class标签 : 建立类和表的映射  				name : 类的全路径.  				table : 数据库中表的名称.  				catalog : 数据库名称(可以省略)  			id标签 : 建立主键和类中属性映射  				name : 类中的属性的名称  				column : 表中的字段名称.(如果类中的属性名和表中字段名一致,column可以省略)  			property标签 : 建立普通字段与类中属性映射  				name : 类中的属性的名称.  				column : 表中的字段名称.(如果类中的属性名和表中的字段名一致,column可以忽略)  				length : 字段的长度(自动创建表)  				not-null : 非空(自动创建表)  				unique : 唯一(自动创建表)  		1.5Hibernate的常用API  			1.5.1 Configuration : 配置对象  				用来加载核心配置文件 :  					hibernate.cfg.xml  					Configuration cfg = new Configuration();  					cfg.configure();  				用来加载映射文件:  					手动加载 : cfg.addResource("com/heima/domain/Customer.hbm.xml");    		1.5.2 SessionFactory : session工厂对象  			session工厂,是一个线程安全的对象,内容维护Hibernate的连接池.一般一个应用只需要创建一次的对象.  			public class HibernateUtils  			{  					// 加载配置文件  						private static Configuration con =null;  					// 连接池  						private static SessionFactory factory = null;  					static  					{  						con=new Configuration();  						con.configure();  						factory=con.buildSessionFactory();  					}  				// 获取sessionfactory  					public static SessionFactory getSessionFactory()  					{  						return factory;  					}  				// 获取session  					public static Session openSession()  					{  						return factory.openSession();  					}  			}    		1.5.3 Session(...) : 连接对象  			session 相对于Connection ,是线程不安全的,Session是Hibernate持久化操作的核心API.(不要把它放在一个dao层的成员变量)  			Seralizable save(Object obj);  保存数据.  			T get(Class clazz,Serializable id);根据ID查询数据  			T load(Class clazz,Serializable id);根据ID 查询数据    			get和load区别:  				get采用的立即加载(马上发送一条SQL语句)	: 程序执行到这行的时候,就会马上发送SQL语句进行查询.  				get方法查询对象的时候返回的是真实对象本身.  				get方法查询一个找不到的对象的时候输出null.    				load采用的延迟加载(没有马上发送sql语句)	  : 程序执行到这行的时候,不会发送SQL语句,真正使用这个对象的时候(使用非主键属性),才会发送sql语句.  				load方法查询对象的时候返回的是代理对象.  				load查询一个找不到的对象的时候返回ObjectNotFoundException.  			//get方法  			Customer customer = session.get(Customer.class,100L);//马上发送一条SQL语句  			System.out.println(customer);    			//load方法  			Customer customer = session.load(Customer.class,100L);没有马上发送SQL语句  			System.out.println(customer.getCust_name());  			transaction.commit();  			session.close();    		修改id为6的客户的信息  			public void demo3() {  				Session session = HibernateUtils.openSession();  				Transaction transaction = session.beginTransaction();    				//1.直接创建对象,进行修改  				Customer customer = new Customer();  				customer.setCust_id(5L);  				customer.setCust_name("郝芙蓉");  				session.update(customer);  				//2.先查询再修改  				Customer customer = session.get(Customer.class,3L);  				customer.setCust_name("郝强吉吉");  				session.update(customer);    				transaction.commit();  				session.cloase();  			}  		删除操作:  		public void demo4() {  			Session session = HibernateUtil.openSession();  			Transaction transaction = session.beginTransaction();  			//1.直接创建对象,传入id删除  			Customer customer = new Customer();  			customer.setCust_id(2L);  			session.delete(customer);    			//2.先查询再删除(推荐:级联删除)  			Customer customer = session.get(Customer.class,6L);  			session.delete(customer);  			transaction.commit();  			session.cloae();  		}