SpringDataJpa和Mybatis一样,在三层架构中处于持久层,就是专门与数据库打交道的,那我用Mybatis用得好好的为什么要再学SpringDataJpa?这就要从定义说起。
JPA,全称是Java Persistence Api,Java持久化接口,它不是一种技术,而是一种 规范 。作为规范,它将Java对象的创建过程和具体的创建形式解耦。我们的程序中并不会把所有的Java对象都进行持久化,只会保留关键业务对象,JPA规范就是允许我们自定义应该保留 哪些 对象,以及 如何 在Java应用程序中保留这些对象。
Hibernate是我在大学的时候也是学的第一门持久化层框架,它就是遵循了JPA规范的框架,也有文章说Hibernate是JPA的前身,简单来说Hibernate是一款重量级的持久化层框架,学习成本较高、全自动化是它的特点,同时这些特点也决定了它不适合做互联网项目。
Mybatis和Hibernate的作用相同,都是与数据库做交互,但定位不同,Mybatis的轻量和它的SQL自定义让它成为互联网项目持久化层框架的首选,当然SQL需要开发人员书写(即使是注解模式)的特点让它在传统项目的面前不如遵循JPA的Hibernate,所以说技术没有高低之分,只有落脚点不同之别。
说了那么多那SpringDataJpa究竟是什么?我的理解是,它还是对JPA的进一步封装,地位处于JPA与实际落地技术(如Hibernate)之间,所以SpringDataJpa仍然不是“干活的技术”,Hibernate才是干活的工人,SpringDataJpa是做指派工作的包工头。原因在于基于SpringDataJpa,还可以再具体指定使用哪个持久层框架来与数据库做交互。另外我认为,在Spring大行天下的当今,在项目技术选型时选用SpringDataJpa可以和Spring有更好的交融,这是个潜藏的优势。具体可以看配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> <!--对Spring和SpringDataJpa进行配置--> <!--1.数据源--> <context:property-placeholder location="classpath*:jdbc.properties"/> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!--2.配置Jpa中一个非常重要的对象——entityManagerFactory 它相当于MyBatis中的SqlSessionFactory,就是一些框架的细节配置--> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <!--配置数据源--> <property name="dataSource" ref="dataSource"/> <!--配置包扫描:packagesToScan ,就是框架要帮我们生成sql,那要帮哪些pojo对应的数据表生成呢?就指定pojo包路径,告诉框架去生成可以操作这个包下的pojo类的sql--> <property name="packagesToScan" value="cn.lamb.pojo"/> <!--指定jpa的具体实现:persistenceProvider(持久化提供者) ,jpa是一种规范,并不直接操作持久层,它的具体实现要靠遵循jap规范的持久化层框架,这里使用的是Hibernate,所以将它指定为jpa的具体实现--> <property name="persistenceProvider"> <bean class="org.hibernate.jpa.HibernatePersistenceProvider"/> </property> <!--指定jpa的方言 ,不同框架对sql的处理是不同的,每种框架都有自己的一套“规则”,所以要指定方言,这里要和persistenceProvider一致--> <property name="jpaDialect"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/> </property> <!--===================既然使用的是Hibernate框架做具体实现,那么也要对hibernate做具体配置========================--> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <!--需不需要在每次程序启动时创建不存在的数据表 ,这个不需要我们操心--> <property name="generateDdl" value="false"/> <!--现在Hibernate要处理什么数据库--> <property name="database" value="MYSQL"/> <!--要和现在使用的数据库有照应 ,数据库之间的语法或多或少有差异,因此要根据database设置方言--> <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/> <!--是否显示SQL ,操作数据库时是否打印SQL--> <property name="showSql" value="true"/> </bean> </property> </bean> <!--3.使用上面的entityManagerFactory <jpa:repositories>配置jpa的Dao层细节 base-package指定Dao层 --> <jpa:repositories base-package="cn.lamb.dao" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="jpaTransactionManager"/> <!--4.事务处理器 ,Mybatis、jdbcTemplate使用的事务管理器是org.springframework.jdbc.datasource.DataSourceTransactionManager jpa使用的事务管理器是org.springframework.orm.jpa.JpaTransactionManager--> <bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!--5.开启Spring包扫描--> <context:component-scan base-package="cn.lamb"/> </beans> 复制代码
谈起操作数据库,大致可以分为两个阶段:
我认为万变不离其宗的还是 JDBC——它贯穿始终,即使到了框架部分,也会对 JDBC 进行整合,所以什么时候回归朴素吧,把JDBC的源码捡一捡。