Hibernate学习笔记①
---恢复内容开始---
1、JavaEE的三层结构
WEB层--Service层--DAO层
2、Hibernate版本
Hibernate3.x 4.x 5.x
4版本是过渡版本 不使用 5.x推荐
3.ORM(Object Relation Mapping,对象关系映射)
Hibernate使用了ORM思想
javabean在Hibernate中被称为实体类
做法:①实体类与数据库的表一一对应(实体类与数据库的表进行对应【有User类就有User表】,实体类的属性和数据库表的字段进行对应)
②不需要操作数据库,操作表对应的实体类
Hibernate将JDBC的功能封装进了Session类里面,不用写重复的代码。
4.搭建Hibernate环境、
1.Jar包:required里面和JPA里面的需要有,以及Log4j和common两个日志输出jar包(我的hibernate版本里面没有jap文件夹,貌似也可以正常运行)
2.配置文件:实体映射文件 hibernate核心配置文件
实体映射文件官方建议的命名格式是:实体名.hbm.xml 位置没有要求,一般与实体类放在同一个包
hibernate核心配置文件 位置必须是src下,名称必须为hibernate.cfg.xml
3.实体类 就是一个javabean
package tech.youngs.entity; public class User { /*Hibernate要求有一个属性是唯一的 --> 对应的主键*/ private int uid; private String username; private String password; private String address; public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
4.映射配置文件:命名为User.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- 引入XML dtd 约束 --> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- hibernate mapping是根标签 --> <hibernate-mapping> <!-- class 配置类和表的映射关系 @param name ※实体类的全路径 @param table 实体类对应的表的名称 --> <class name="tech.youngs.entity.User" table="t_user"> <!-- 属性字段对应 --> <!-- 实体类id与表的id对应 pk --> <!-- @param name 实体类唯一属性的属性名 @param column 表中对应的唯一属性的字段名[主键] --> <id name="uid" column="uid"> <!-- 设置数据库表内id的生成策略 [自增][主键] @param class - native 主键且自增长 --> <generator class="native"></generator> </id> <!-- 配置其他属性和表的字段对应 --> <!-- @param name 实体类的属性名称 @param column 实体类对应的字段的名称 [可以省略,创建的字段名默认和name属性值一样] [@param type 设置实体类的字段类型,Hibernate会自动生成对应的类型] --> <property name="username" column="username"></property> <property name="password" column="password"></property> <property name="address" column="address"></property> </class> </hibernate-mapping>
5.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> <!-- ① 配置数据库信息 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql:///hibernate_demo1</property> <property name="connection.username">root</property> <property name="connection.password">996225</property> <!-- ② 配置hibernate信息 [可选] --> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- format SQL --> <property name="format_sql">true</property> <!-- Drop and re-create the database schema on startup --> <!-- 值有很多 create update delete 最常用的是update 有表更新 无表创建 --> <property name="hbm2ddl.auto">update</property> <!-- SQL dialect --> <!-- 每个数据库 都有自己的SQL标准 比如分页在mysql中用limit,oracle用rownum 让hibernate识别特有的语句[SQL标准之外的] --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- ③ 引入映射文件 --> <mapping resource="tech/youngs/entity/User.hbm.xml"/> </session-factory> </hibernate-configuration>
6.测试类
package tech.youngs.hibernatetest; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.Test; import tech.youngs.entity.User; public class HibenateDemo { @Test public void add() { /*第一步 加载Hibernate核心核心配置文件*/ /* 详解Configuration * 作用:去src下找hibernate.cfg.xml,加载核心配置文件 * */ Configuration cfg = new Configuration(); /*会找hibernate.cfg.xml的文件 加载进来*/ cfg.configure(); /*第二步 创建SessionFactory对象*/ /*会根据引入的映射文件 在数据库中生成表*/ /* 详解SessionFactory * 作用: * 在创建过程中:根据数据库配置和映射文件配置生成表【非常耗费资源】 * 一般的时候会一个项目只创建一个SessionFactory对象 * ->创建一个工具类,使用静态代码块(类加载时只执行一次) * SessionFatory sessionFactory = HibernateUtil.getSessionFactory(); * * */ SessionFactory sessionFactory = cfg.buildSessionFactory(); /*第三步 创建session*/ /* 详解Session * 作用 CURD操作 * 常用方法:save[添加] update[修改] delete[删除] get[根据id查数据] * 特点:单线程对象[只能自身使用,无法共用] * */ /*类似于JDBC的Connection*/ Session session = sessionFactory.openSession(); /*第四步 开启事务*/ /*详解 Transaction * 提交事务:commit * 回滚事务:rollback -> 回到操作之前的状态 * 事务 * 特性:原子性[要么都成功,要么都失败] * 一致性[数据要前后要一致,一个账户钱减少了,另一个就要多,不能说这边少了那边没有多,账户的总数就不一致] * 隔离性[事务与事务之间不受影响] * 持久性 [数据库提交,数据持久化了] * */ Transaction tx = session.beginTransaction(); /*第五步 CURD操作*/ User user = new User(); user.setUsername("小明"); user.setPassword("123456"); user.setAddress("Xianyang"); /*使用session中的save添加*/ session.save(user); /*第六步 提交事务*/ tx.commit(); /*第七步 关闭资源*/ session.close(); sessionFactory.close(); } }
上面需要注意得一个问题就是SessionFactory创建过程中会根据映射文件创建表,这是一个非常耗费资源的过程,如果每一次访问都要创建资源的话,不仅用户体验不好而且服务器也很耗费资源,所以在开发过程中一般会单独的创建一个Util类,在类中的静态代码块中完成Configuration和SessionFactory的创建,并声明一个返回SessionFactory的方法即可。由于静态代码块在类创建的时候就执行而且只执行一次,所以这样一定程度上解决了问题。下面是Util的代码:
package tech.youngs.utils; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static Configuration cfg = null; private static SessionFactory sessionFactory = null; static{ //加载配置文件 cfg = new Configuration().configure(); sessionFactory = cfg.buildSessionFactory(); } public SessionFactory getSessionFactory() { return sessionFactory; } }
---恢复内容结束---