文章大纲
一、jdbc介绍
二、Mybatis介绍
三、Hibernate介绍
四、jdbc、Mybatis、Hibernate比较
五、参考文章
一、jdbc介绍
1. jdbc编程步骤
(1)加载数据库驱动
(2)创建并获取数据库链接
(3)创建jdbc statement对象
(4)设置sql语句
(5)设置sql语句中的参数(使用preparedStatement)
(6)通过statement执行sql并获取结果
(7)对sql执行结果进行解析处理
(8)释放资源(resultSet、preparedstatement、connection)
2. jdbc的缺点
(1)工作量比较大,需要连接,然后处理jdbc底层事务,处理数据类型,还需要操作Connection,Statement对象和ResultSet对象去拿数据并关闭他们。
(2)我们对jdbc编程可能产生的异常进行捕捉处理并正确关闭资源。
二、Mybatis介绍
1. Mybatis操作教程
https://www.jianshu.com/p/73cb40bc5d46
2. Mybatis特点
(1)为了解决Hibernate的不足,Mybatis出现了,Mybatis是半自动的框架。之所以称它为半自动,是因为它需要手工匹配提供POJO,sql和映射关系,而全表映射的Hibernate只需要提供pojo和映射关系即可。
(2)Mybatis需要提供的映射文件包含了一下三个部分:sql,映射规则,pojo。在Mybatis里面你需要自己编写sql,虽然比Hibernate配置多,但是Mybatis可以配置动态sql,解决了hibernate表名根据时间变化,
(3)不同条件下列不一样的问题,同时你也可以对sql进行优化,通过配置决定你的sql映射规则,也能支持存储过程,所以对于一些复杂和需要优化性能的sql查询它就更加方便。Mybatis几乎可以做到jdbc所有能做到的事情。
(4)入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。
(5)可以进行更为细致的SQL优化,可以减少查询字段。
(6)缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。
(7)二级缓存机制不佳。
三、Hibernate介绍
1. Hibernate代码实操
1.1 Hibernate的核心组件
在基于MVC设计模式的JAVA WEB应用中,Hibernate可以作为模型层/数据访问层。它通过配置文件(hibernate.properties或hibernate.cfg.xml)和映射文件(***.hbm.xml)把JAVA对象或PO(Persistent Object,持久化对象)映射到数据库中的数据库,然后通过操作PO,对数据表中的数据进行增,删,改,查等操作。
除配置文件,映射文件和持久化类外,Hibernate的核心组件包括以下几部分:
(1)Configuration类:用来读取Hibernate配置文件,并生成SessionFactory对象。
(3)Session接口:用来操作PO。它有get(),load(),save(),update()和delete()等方法用来对PO进行加载,保存,更新及删除等操作。它是Hibernate的核心接口。
(4)Query接口:用来对PO进行查询操。它可以从Session的createQuery()方法生成。
(5)Transaction接口:用来管理Hibernate事务,它主要方法有commit()和rollback(),可以从Session的beginTrancation()方法生成。
1.2 Hibernate的运行过程
(1)应用程序先调用Configration类,该类读取Hibernate的配置文件及映射文件中的信息,并用这些信息生成一个SessionFactpry对象。
(2)然后从SessionFactory对象生成一个Session对象,并用Session对象生成Transaction对象;可通过Session对象的get(),load(),save(),update(),delete()和saveOrUpdate()等方法对PO进行加载,保存,更新,删除等操作;在查询的情况下,可通过Session对象生成一个Query对象,然后利用Query对象执行查询操作;如果没有异常,Transaction对象将 提交这些操作结果到数据库中。
Hibernate的运行过程如下图:
1.3 创建项目并导入jar包
1.4 创建学生实体类
package cn.zhang.entity;
//实体类
public class Student {
private int stuno;
private String stuname;
private int stuage;
private int stuid;
private int stuseat;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String stuname, int stuage, int stuid, int stuseat) {
super();
this.stuname = stuname;
this.stuage = stuage;
this.stuid = stuid;
this.stuseat = stuseat;
}
public Student(int stuno, String stuname, int stuage, int stuid, int stuseat) {
super();
this.stuno = stuno;
this.stuname = stuname;
this.stuage = stuage;
this.stuid = stuid;
this.stuseat = stuseat;
}
public int getStuid() {
return stuid;
}
public void setStuid(int stuid) {
this.stuid = stuid;
}
public int getStuseat() {
return stuseat;
}
public void setStuseat(int stuseat) {
this.stuseat = stuseat;
}
public int getStuno() {
return stuno;
}
public void setStuno(int stuno) {
this.stuno = stuno;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public int getStuage() {
return stuage;
}
public void setStuage(int stuage) {
this.stuage = stuage;
}
}
1.5 在src下设计Hibernate配置文件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>
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
<property name="connection.username">zhangzong</property>
<property name="connection.password">123</property>
<!-- SQL dialect (SQL 方言)-->
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<!-- Echo all executed SQL to stdout 在控制台打印后台的SQL语句-->
<property name="show_sql">true</property>
<!-- 格式化显示SQL -->
<property name="format_sql">true</property>
<!-- JDBC connection pool (use the built-in) -->
<!-- <property name="connection.pool_size">1</property> -->
<!-- Enable Hibernate's automatic session context management -->
<!-- <property name="current_session_context_class">thread</property> -->
<!-- Disable the second-level cache -->
<!-- <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>-->
<mapping resource="cn/zhang/entity/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
1.6 在实体类下设计映射文件Student.hbm.xml(在配置文件hibernate.cfg.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">
<hibernate-mapping package="cn.zhang.entity">
<class name="Student" table="stuinfo">
<id name="stuno" column="stuno">
<!-- 主键生成策略:native:
native:如果后台是Oracle
后台是MySQL,自动应用自增 -->
<generator class="native"/>
</id>
<property name="stuname" type="string" column="stuname"/>
<property name="stuage"/>
<property name="stuid" type="int" column="stuid"/>
<property name="stuseat"/>
</class>
</hibernate-mapping>
1.7 更新(新增)一个学生记录
package cn.zhang.test;
//新增一条数据
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import cn.zhang.entity.Student;
public class InsertTest {
public static void main(String[] args) {
//准备对象
Student student=new Student("光衣", 12,112333,2);//Student.hbm.xml已配置编号为自增,所以这里不用添加编号了
//读取大配置文件,获取要连接的数据库信息
Configuration configuration=new Configuration().configure();
//创建SessionFactory
SessionFactory factory = configuration.buildSessionFactory();
//加工session
Session openSession = factory.openSession();
Transaction beginTransaction = openSession.beginTransaction();
openSession.save(student);
beginTransaction.commit();
System.out.println("成功");
}
}
1.8 修改一个学生信息
package cn.zhang.test;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import cn.zhang.entity.Student;
public class UpdateTest {
/**
* @param args
*/
public static void main(String[] args) {
//1.读取大配置文件,获取要连接的数据库信息
Configuration conf=new Configuration().configure();
//2.创建SessionFactory
SessionFactory factory =conf.buildSessionFactory();
//3加工session
Session session = factory.openSession();
Transaction tx=session.beginTransaction();
//获取对象
Student stu =new Student(1,"光衣", 12,112333,2);
//更新
session.update(stu);
//提交事务
tx.commit();
System.out.println("更新成功");
}
}
1.9 删除一个指定学生信息
package cn.zhang.test;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import cn.zhang.entity.Student;
public class DeleteTest {
public static void main(String[] args) {
//1.读取大配置文件,获取要连接的数据库信息
Configuration conf=new Configuration().configure();
//2.创建SessionFactory
SessionFactory factory =conf.buildSessionFactory();
//3.加工session
Session session = factory.openSession();
Transaction tx=session.beginTransaction();
//获取对象
Student stu =new Student();
stu.setStuno(3);//指定要删除的编号
//删除指定
session.delete(stu);
//提交事务
tx.commit();
System.out.println("删除成功");
}
}
1.10 查询一个指定学生信息
package cn.zhang.test;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import cn.zhang.entity.Student;
public class SelectTest {
public static void main(String[] args) {
//1.读取大配置文件,获取要连接的数据库信息
Configuration conf=new Configuration().configure();
//2.创建SessionFactory
SessionFactory factory =conf.buildSessionFactory();
//3.打开session
Session session = factory.openSession();
//4.加载数据操作
//如果表中没有你指定的主键列,get()方法的是null
Student student =(Student)session.get(Student.class, 4);
//如果表中没有你指定的主键列,程序运行到student.getStuname()时会抛出异常
//Student student =(Student)session.load(Student.class, 4);
//5.输出数据
System.out.println(student.getStuname());
//6.关闭session
session.close();
}
}
2. Hibernate的优点
(1)消除了代码的映射规则,它全部分离到了xml或者注解里面去配置。
(2)无需在管理数据库连接,它也配置到xml里面了。
(3)一个会话中不需要操作多个对象,只需要操作Session对象。
(4)关闭资源只需要关闭一个Session便可。
(5) 这就是Hibernate的优势,在配置了映射文件和数据库连接文件后,Hibernate就可以通过Session操作,非常容易,消除了jdbc带来的大量代码,大大提高了编程的简易性和可读性。Hibernate还提供了级联,缓存,映射,一对多等功能。Hibernate是全表映射,通过HQL去操作pojo进而操作数据库的数据。
3. Hibernate的缺点
(1)全表映射带来的不便,比如更新时需要发送所有的字段。
(2)无法根据不同的条件组装不同的SQL。
(3)对多表关联和复杂的sql查询支持较差,需要自己写sql,返回后,需要自己将数据封装为pojo。
(4)不能有效的支持存储过程。
(5)虽然有HQL,但是性能较差,大型互联网系统往往需要优化sql,而hibernate做不到。
四、jdbc、Mybatis、Hibernate比较
1. 什么时候使用Hibernate,Mybatis
(1)Hibernate作为留下的Java orm框架,它确实编程简易,需要我们提供映射的规则,完全可以通过IDE生成,同时无需编写sql确实开发效率优于Mybatis。此外Hibernate还提供了缓存,日志,级联等强大的功能,
(2)但是Hibernate的缺陷也是十分明显,多表关联复杂sql,数据系统权限限制,根据条件变化的sql,存储过程等场景使用Hibernate十分不方便,而性能又难以通过sql优化,所以注定了Hibernate只适用于在场景不太复杂,要求性能不太苛刻的时候使用。
(3)如果你需要一个灵活的,可以动态生成映射关系的框架,那么Mybatis确实是一个最好的选择。它几(4)但是它的缺陷是需要你提供映射规则和sql,所以开发工作量比hibernate要大些。
(5)mybatis:机械工具,使用方便,拿来就用,但工作还是要自己来作,不过工具是活的,怎么使由我决定。
(6)hibernate:智能机器人,但研发它(学习、熟练度)的成本很高,工作都可以摆脱他了,但仅限于它能做的事。
2. 多维度比较Hibernate,Mybatis
2.1 开发速度
Mybatis其实要比Hibernate要更好上手,因为Hibernate是对JDBC的深度封装,而Mybatis就显得更加开放,而且简单易学。这也是Mybatis更加流行的原因,正因为如此,Mybatis的开发社区近年来也开始活跃起来,下载一些支持开发的工具也较为方便;Mybatis也有自己的代码生成工具,可以生成简单基本的DAO层方法,针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以把更多的精力放在业务流程上。
2.2 系统调优方面
Hibernate可以制定合理的缓存策略,在延迟加载方面处理得较好,有较为合理的Session管理机制,便于批量抓取,同时有合理的O/R映射设计。Mybatis在调优方面,同样有Session机制和二级缓存,同时还可以对SQL进行优化设计;Hibernate一般是查询数据库的所有字段,如果指定字段查询,程序较为繁琐,而Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。虽然Hibernate具有自己的日志统计,但同样可以通过Log4j进行日志记录。
2.3 对象管理方面
Hibernate 是完整的对象/关系映射解决方案,对象管理功能比较完善,使开发者不用再关注底层数据库系统的细节。也就是说,相对于常见的 JDBC/SQL 持久层方案中需要管理 SQL 语句,Hibernate采用了更自然的面向对象的视角来持久化 Java 应用中的数据。而MyBatis在这方面没有特定的文档说明,但也便于开发者发挥自身的想法来对对象进行管理。
2.4 缓存机制方面
Hibernate的一级缓存是Session缓存,一级缓存是与Session的生命周期相关的。而它的二级缓存是SessionFactory级的缓存其中可分为内置缓存和外置缓存,其中的内置缓存中存放了关于SessionFactory对象的一些集合属性包含的数据,包括映射元素据及预定SQL语句等;而Mybatis一般也可分为二级缓存,一级缓存是 SqlSession 级别的缓存二级缓存是 mapper 级别的缓存,多个 SqlSession 共享,而它默认状态是开启一级缓存,这样对开发者而言是一种便捷。但也有人指出,Mybatis的缓存机制在一定程度上限制了Mybatis的推广。
3. Jdbc,Mybatis,Hibernate的区别
(1)从层次上看,JDBC是较底层的持久层操作方式,而Hibernate和MyBatis都是在JDBC的基础上进行了封装使其更加方便程序员对持久层的操作。
(2)从功能上看,JDBC就是简单的建立数据库连接,然后创建statement,将sql语句传给statement去执行,如果是有返回结果的查询语句,会将查询结果放到ResultSet对象中,通过对ResultSet对象的遍历操作来获取数据;Hibernate是将数据库中的数据表映射为持久层的Java对象,对sql语句进行修改和优化比较困难;MyBatis是将sql语句中的输入参数和输出参数映射为java对象,sql修改和优化比较方便。
(3)从使用上看,如果进行底层编程,而且对性能要求极高的话,应该采用JDBC的方式;如果要对数据库进行完整性控制的话建议使用Hibernate;如果要灵活使用sql语句的话建议采用MyBatis框架。