SSH框架之Hibernate第一篇
程序员文章站
2022-07-20 10:30:04
1.2Hibernate的概述: 1.2.1 什么Hibernate? Hibernate(开发源代码的对象关系映射框架)是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系, 是一个全自动的orm框架,hibernate可以自动生成SQL语... ......
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(); }