ORM概述
持久化
把瞬态数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘中的文件、数据库等)
持久化目标一版可以分为
- 无结构文本文件:通过I/O技术读写文件——不需要驱动
- 结构化文本文件:通过SDK提供的API读写文件——非关系型——需要驱动
- 关系型数据库:通过数据库驱动技术(如JDBC)读写DBMS
瞬时状态:保存在内存的程序数据,程序退出后,数据就消失了,称为瞬时状态
持久化:将程序数据在瞬时状态和持久状态之间转换的机制
持久状态:保存在磁盘上的程序数据,程序退出后依然存在,称为程序数据的持久状态
ORM:对象关系映射
完成瞬态的对象数据到持久的关系型数据映射的机制
常见ORM方式
- 传统JDBC
- 简化的JDBC,如Spring JDBC template
- 半自动ORM框架,如Mybatis
- 全自动ORM框架,如Hibernate
Mybatis简介
特点
- 支持普通SQL查询,存储过程和高级映射的优秀持久层框架
- 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索
- 使用简单的XML或注解用于配置和原始的映射,将Java POJOs映射成数据库中的记录
基本原理
- 在XML文件中定义SQL语句,预留参数占位符
- 在运行时,占位符被指定的参数值取代,参数可能来自参数映射表、JavaBean属性、或者简单的参数对象
- 在执行SQL查询时,结果字段被映射到对象,映射的方式与参数映射一样
使用Mybatis开个你家的应用程序的组成
- Configuration.xml文件
- SqlSessionFactory/SqlMapper对象
- Mapper.xml文件
- Mybatis java API
Mybatis使用入门
Mybatis实现DAO
-
导入依赖,编写Configuration.xml文件
-
-
Configuration.xml文件包含两个部分内容:节点和 节点,前者指定数据库环境,后者指定映射器的路径
-
<environments default="demo"> <environment id="demo"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <!--支持数据库连接池--> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mypetstore"/> <property name="username" value=" "/> <property name="password" value=" "/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/demo/domain/UserMapper.xml"/> </mappers>
-
-
获取SqlSessionFactory对象
-
-
public class SessionFactoryUtil{ private static String source="com/demo/dao/Configuration.xml"; public static SqlSessionFactory getSqlSessionFactory(){ SqlSessionFactory sqlSessionFactory=null; try{ Reader reader=Resource.getResourceAsReader(source); sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader); }catch(IOException e){ e.printStackTrace(); } return sqlSessionFactory; }
-
-
编写映射器Mapper.xml文件
-
-
映射器的namespace属性用于以后访问该映射器的唯一标识
-
一个映射器文件(Mapper.xml)中可以博阿寒增删改查等多个SQL语句映射
-
每个SQL语句得到id属性是其唯一标识,通过parameterType属性设置传递给该SQL语句的参数类型,而resultType属性则用于指定该SQL语句执行完成后的结果类型
-
<mapper namespace="org.csu.mypetstore.persistence.AccountMapper"> <select id="getAccountByUsernameAndPassword" parameterType="Account" resultType="Account"> SELECT USERID AS username,EMAIL AS email,FIRSTNAME AS firstName, LASTNAME AS lastName,STATUS,ADDR1 AS address1,ADDR2 AS address2, CITY AS city,STATE,ZIP,COUNTRY,PHONE FROM ACCOUNT WHERE USERID =#{username} </select> </mapper>
-
-
使用Mybatis的Java API实现CRUD
-
-
通过SqlSessionFactory获得SqlSession实例
-
调用SqlSession对象的不同方法进行相应的操作
-
方法一般有两个参数,第一个参数指定映射器和具体的SQL语句,第二个参数为需要传递该SQL语句的对象
-
关闭SqlSession:session.close()
-
sqlSessionFactory = SessionFactoryUtil.getSqlSessionFactory(); session = sqlSessionFactory.openSession(); result = session.selectOne("com.demo.dao.UserDAO.find",user); //UserDAO mapper = session.getMapper(UserDAO.class); //result = mapper.find(user);
-
Hibernate简介
Hibernate实现了较为完整的ORM
- Hibernate是对JDBC的进一步封装
- 将通过SQL语句进行持久化改为直接操作对象(持久化对象)
- 根据持久化对象的状态生成SQL语句
- 利用会话Session维持持久化对象
- 技术上大量的使用反射、事务、缓存
<hibernate-mapping package="org.hibernate.tutorial.domain">
<class name="Event" table="EVENTS">
<id name="id" column="EVENT_ID">
<generator class="native"/>
</id>
<property name="date" type="timestamp" column="EVENT_DATE"/>
<property name="title"/>
</class>
</hibernate-mapping>
private void createAndStoreEvent(String title,Date theDate){
Session session=HibernateUtil.getSessionFactory().getCurrentSession();
Event theEvent=new Event();
theEvent.setTitle(title);
theEvent.setDate(theDate);
session.save(theEvent);
//缓存,当使用了commit会对数据库数据修改
session.getTransacation().commit();
}
Hibernate对持久化对象取值的规定
- 瞬时/临时状态
-
- 由new操作符创建,且尚未与Hibernate Session关联的对象被认定为瞬时的.瞬时对象不会被持久化到数据库中,也不会被赋予持久化标识(identifier)
- 如果瞬时对象在程序中没有被引用,它会被垃圾回收器销毁.使用Hibernate Session可以将其变为持久状态,Hibernate会自动执行必要的SQL语句
- 持久化状态
-
- 持久的实例可能是刚被保存的,或刚被加载的,无论哪一种,安定一存在于相关联的Session作用范围中
- Hibernate会检测到处于持久状态的对象的任何改动,在当前操作单元执行完毕时将对象数据与数据库同步,开发者不需要手动执行UPDATE.将对象从持久状态变成顺瞬时状态同样也不需要手动执行DELETE语句
- 脱管/游离状态
-
- 与持久化对象关联的Session被关闭后,对象就变为脱管的.对脱管对象的引用依然有效,对象可继续被修改.脱管对象如重新关联到某个新的Session上,会再次转变为持久的,在脱管期间的改动将被持久化到数据库
JPA
ORM规范,规定了对象持久化的API
JPA本身并不提供实现,只提供规范,广义上来说JDBC、jdbcTemplate、Mybatis、Hibernate都可以认为是JPA的实现
JAP规范包括三方面内容
- ORM映射元数据,包括XML和注解两种方式
- 用于Java调用API接口
- 面向对象的查询语言JPQL
Mybatis和Hibernate的区别
Mybatis(优):
SQL写在xml里,便于统一管理和优化, 解除sql与程序代码的耦合
提供xml标签,支持编写动态SQL
速度相对于Hibernate的速度较快
Mybatis(缺):
关联表多时,字段多的时候,sql工作量很大
SQL依赖于数据库,导致数据库移植性差
编写动态SQL时,不方便调试,尤其逻辑复杂时
提供的写动态SQL的xml标签功能简单
由于xml里标签id必须唯一,导致DAO中方法不支持方法重载
对象关系映射标签和字段映射标签仅仅是对映射关系的描述,具体实现仍然依赖于sql
Hibernate(优):
数据库移植性良好
拥有完整的日志系统
可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql。
Hibernate(缺):
灵活度上hibernate不及mybatis。
学习门槛不低,精通门槛更高