导读
本文主要介绍hibernate的入门,主要包括以下内容:hibernate介绍、hibernate环境搭建、hibernate简单测试、测试涉及的api详解。
一、hibernate介绍
JDBC是Java操作数据库的工具,我们可以使用jdbc来书写并执行sql语句来操作数据库,对于普通的业务,jdbc工具是完全可以胜任的,但但当任务复杂,特别是数据库中表格很多的时候,jdbc就会显得力不从心,代码复用率低且sql语句容易出错。
Hibernate框架从jdbc面向过程操作数据库的过程转变为面向对象来操作数据库。其原理是ORM编程,即Object Relational Mapping(对象关系映射)。每一个数据库表对应一个实体类,这个实体类通过映射关系来操作这个数据库表,映射可以理解为平常我们所说的函数,如y=f(x);y是数据库中的表,x是实体类,f(x)即映射关系,我们通过操作x可以改变y值,同样的操作实体类便可以达到操作数据库的目的,这就是通过面向对象方式来操作数据库。
二、hibernate环境搭建
hibernate的环境搭建包括以下部分:1、导入运行环境需要的jar包;2、创建数据库表和对应的实体类;3、编写表和实体之间的映射关系(也叫orm元数据);4、编写主配置文件hibernate.cfg.xml
1、导包
搜索下载压缩包:hibernate-release-5.0.7.Final.zip就可以找到相应的jar包:
注:不要忘了导入数据库驱动包(这里我使用的是mysql数据库),所以还需导入:
2、创建数据库表和实体类
这里假设我们创建了user表:
CREATE TABLE `user` ( `uid` bigint(32) NOT NULL AUTO_INCREMENT, `uname` varchar(32) NOT NULL, PRIMARY KEY (`uid`) )
实体类:User
1 package domain; 2 public class User { 3 private Long uid; 4 private String uname; 5 6 public Long getUid() { 7 return uid; 8 } 9 public void setUid(Long uid) { 10 this.uid = uid; 11 } 12 public String getUname() { 13 return uname; 14 } 15 public void setUname(String uname) { 16 this.uname = uname; 17 } 18 @Override 19 public String toString() { 20 return "User [uid=" + uid + ", uname=" + uname + "]"; 21 } 22 }
3、编写表和实体之间的映射关系(orm元数据)
1)导入dtd约束
hibernate框架使用的是xml文件作为配置文件,所以在编写xml文件之前需要先导入dtd约束(该约束文件也在上面使用到的压缩包里)
导入方式:eclipse-->Preferences-->xml-->XML Catalog-->add
两个文件都添加完成后你的eclipse中有了这个dtd约束了,如果你的eclipse已经有了该dtd约束上面的步骤就可以忽略。
2)配置映射关系:User.hbm.xml
一般该文件的命名格式为(当然你可以随意命名):类名.hbm.xml。且放在和该实体类同一个目录下。
xml简写版:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 6 <hibernate-mapping package="domain" > 7 8 <class name="User" table="user" > 9 <id name="uid" > 10 <generator class="native"></generator> 11 </id> 12 13 <property name="uname" column="uname" ></property> 14 </class> 15 </hibernate-mapping>
xml注释版:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!-- 1、导入dtd约束 --> 3 <!DOCTYPE hibernate-mapping PUBLIC 4 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 5 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 6 7 <!-- 2、ORM元数据:配置表与实体对象的关系(映射关系) --> 8 9 <!-- package属性:填写一个包名.在元素内部凡是需要书写完整类名的属性,可以直接写简答类名了. --> 10 <hibernate-mapping package="domain" > 11 12 <!-- 13 2.1 class元素: 配置实体与表的对应关系的 14 name: 完整类名 15 table:数据库表名 16 --> 17 <class name="User" table="user" > 18 <!-- id元素:配置主键映射的属性 19 name: 填写主键对应属性名 20 column(可选): 填写表中的主键列名.默认值:列名会默认使用属性名 21 type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型. 22 每个类型有三种填法: java类型|hibernate类型|数据库类型 23 not-null(可选):配置该属性(列)是否不能为空. 默认值:false 24 length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度 25 --> 26 <id name="uid" > 27 <!-- generator:主键生成策略(明天讲) --> 28 <generator class="native"></generator> 29 </id> 30 <!-- 2.2property元素:除id之外的普通属性映射 31 name: 填写属性名 32 column(可选): 填写列名 33 type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型. 34 每个类型有三种填法: java类型|hibernate类型|数据库类型 35 not-null(可选):配置该属性(列)是否不能为空. 默认值:false 36 length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度 37 --> 38 <property name="uname" column="uname" ></property> 39 </class> 40 </hibernate-mapping>
4、编写主配置文件
主配置文件一般是整体环境的配置一些数据库操作设置。主要分为:1、必要配置:数据库驱动等配置;2、可选配置;3、引入orm元数据:指定要操作的关系映射。
一般主配置文件都以hibernate.xfg.xml来命名(这样我们在使用时可以直接使用无参方法调用,比较方便)。且需要将文件放到src目录下。
hebernate.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> <!-- #hibernate.dialect org.hibernate.dialect.MySQLDialect #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect #hibernate.connection.driver_class com.mysql.jdbc.Driver #hibernate.connection.url jdbc:mysql:///test #hibernate.connection.username gavin #hibernate.connection.password <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">password</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <mapping resource="domain/User.hbm.xml" /> </session-factory> </hibernate-configuration>
hebernate.cfg.xml注释版:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!-- 导入约束 --> 3 <!DOCTYPE hibernate-configuration PUBLIC 4 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 5 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 6 <!-- 主配置文件 --> 7 <hibernate-configuration> 8 <session-factory> 9 <!-- 10 #hibernate.dialect org.hibernate.dialect.MySQLDialect 11 #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect 12 #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect 13 #hibernate.connection.driver_class com.mysql.jdbc.Driver 14 #hibernate.connection.url jdbc:mysql:///test 15 #hibernate.connection.username gavin 16 #hibernate.connection.password 17 --> 18 <!-- 数据库驱动 --> 19 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 20 <!-- 数据库url --> 21 <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property> 22 <!-- 数据库连接用户名 --> 23 <property name="hibernate.connection.username">root</property> 24 <!-- 数据库连接密码 --> 25 <property name="hibernate.connection.password">password</property> 26 <!-- 数据库方言 27 不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成. 28 sql99标准: DDL 定义语言 库表的增删改查 29 DCL 控制语言 事务 权限 30 DML 操纵语言 增删改查 31 注意: MYSQL在选择方言时,请选择最短的方言. 32 --> 33 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 34 35 36 <!-- #hibernate.show_sql true 37 #hibernate.format_sql true 38 --> 39 <!-- 将hibernate生成的sql语句打印到控制台 --> 40 <property name="hibernate.show_sql">true</property> 41 <!-- 将hibernate生成的sql语句格式化(语法缩进) --> 42 <property name="hibernate.format_sql">true</property> 43 <!-- 44 ## auto schema export 自动导出表结构. 自动建表 45 #hibernate.hbm2ddl.auto create 自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用) 46 #hibernate.hbm2ddl.auto create-drop 自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用) 47 #hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据). 48 #hibernate.hbm2ddl.auto validate 校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败. 49 --> 50 <property name="hibernate.hbm2ddl.auto">update</property> 51 <!-- 引入orm元数据 52 路径书写: 填写src下的路径 53 --> 54 <mapping resource="domain/User.hbm.xml" /> 55 56 </session-factory> 57 </hibernate-configuration>
到这里我们的hibernate环境就搭建完成了,刚开始感觉很多,用多了其实就很可以很快copy这些文件然后改改就o了。
三、hibernate简单测试
1)Demo测试类:
1 package test; 2 3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5 import org.hibernate.Transaction; 6 import org.hibernate.cfg.Configuration; 7 import org.junit.Test; 8 9 import domain.User; 10 11 public class Demo { 12 13 @Test 14 //使用hibernate框架,通过操作User对象往user表中插入一条数据。 15 public void addUser(){ 16 //操作涉及的核心类 17 Configuration config = new Configuration().configure(); 18 SessionFactory factory = config.buildSessionFactory(); 19 Session session = factory.openSession(); 20 Transaction tx = session.beginTransaction(); 21 22 //操作User 23 //----------------------- 24 User user = new User(); 25 user.setUid(1l); 26 user.setUname("张三"); 27 28 session.save(user);//执行 29 //----------------------- 30 31 //关闭资源 32 tx.commit(); 33 session.close(); 34 factory.close(); 35 }
2)执行结果:
四、测试涉及的api详解
1 //1 创建,调用空参构造 2 Configuration conf = new Configuration().configure(); 3 //2 根据配置信息,创建 SessionFactory对象 4 SessionFactory sf = conf.buildSessionFactory(); 5 //3 获得session 6 Session session = sf.openSession(); 7 //4 session获得操作事务的Transaction对象 8 //获得操作事务的tx对象 9 Transaction tx = session.getTransaction(); 10 tx.begin(); 11 //开启事务并获得操作事务的tx对象(建议使用) 12 Transaction tx2 = session.beginTransaction(); 13 //---------------------------------------------- 14 //1 获得要修改的对象 15User u = session.get(User.class, 1l); 16 //2 调用delete删除对象 17 session.delete(u); 18 //---------------------------------------------- 19 tx2.commit();//提交事务 20 session.close();//释放资源 21 sf.close();//释放资源
除了虚线//-----------------之间的操作部分,上下两部分一般都是固定不变的。所以我们可以使用工具类进行抽取,以提高代码复用率:
HibernateUtils:
1 package utils; 2 3 import org.hibernate.HibernateException; 4 import org.hibernate.Session; 5 import org.hibernate.SessionFactory; 6 import org.hibernate.cfg.Configuration; 7 8 public class HibernateUtils { 9 10 // 会话工厂,以单例方式管理 11 private static SessionFactory sessionFactory; 12 13 // ThreadLocal存储session 14 private static ThreadLocal<Session> session = new ThreadLocal<Session>(); 15 16 // 以单例方式管理sessionFactory 17 static { 18 try { 19 sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory(); 20 } catch (HibernateException e) { 21 e.printStackTrace(); 22 throw new HibernateException("初始化会话工厂失败!"); 23 } 24 25 } 26 //得到一个单例的会话工厂 27 public static SessionFactory getSessionFactory(){ 28 return sessionFactory; 29 } 30 //获取一个新session 31 public static Session openSession(){ 32 return sessionFactory.openSession(); 33 } 34 35 public static Session getCurrentSession() throws HibernateException { 36 return sessionFactory.getCurrentSession(); 37 } 38 39 public static void closeSession() throws HibernateException { 40 sessionFactory.getCurrentSession().close(); 41 } 42 43 }