一、ORM
对象关系映射,通过ORM可以把对象映射到关系型数据库中,只要建立对象与数据库的关联,操作对象就可以直接操作数据库中的数据。
特点:
1、可以直接以面向对象的形式操作数据库
2、根据ORM框架能够自动生成SQL(hibernate是全ORM框架,mybatis是半ORM框架)
二、JPA介绍
JPA是一种规范。
使用ORM技术的框架有很多,但是都没有一个统一的规范,增加了开发难度。使用JPA规范后,简化了现有Java EE和JavaSE应用开发工作的同时,整合ORM技术。
三、JPA入门
引入依赖jar包
<properties><!-- 设置默认编码 --><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--Hibernate对JAP的支持包--><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>5.0.12.Final</version></dependency><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>
将项目添加为JPA项目,生成JPA核心配置文件

创建实体类
实体类需要使用注解 @Entity 将该实体类标注为实体类,使用 @Table 注解配置对应关联的数据表
字段id需要使用注解 @Id 标注为ID和使用注解 @GeneratedValue 配置主键生成策略(strategy = GenerationType.IDENTITY)
JPA核心配置文件配置
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<!-- 指定持久化单元的名称 (可以定义多个持久化单元)-->
<persistence-unit name="mysql">
<!--JPA实现厂商-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="123456"/>
<!--是否打印sql语句-->
<property name="hibernate.show_sql" value="true"/>
<!--是否格式化sql语句-->
<property name="hibernate.format_sql" value="true"/>
<!--
ddl生成方式
create:每次运行会把原来表删掉,重新创建一张表
create-drop:每次运行都会把原来表删除,重新创建一张表,程序运行结束后,又把表删除
update:如果没有表那么创建一张新的,如果有了则更新数据
validate:不自动建表,如果没有表那么报错
-->
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>
测试
1、指定实体化单元名称获取实体管理对象工厂(名称需要和JPA核心配置文件中的名称一致)EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql");
2、通过工厂获取实体管理对象EntityManager manager = factory.createEntityManager();
3、通过实体管理对象获取事务操作对象EntityTransaction tx = manager.getTransaction();
4、开启事务tx.begin();
5、执行完操作后提交事务tx.commit();
6、释放资源manager.close(); factory.close();
四、复杂查询
使用jpql语句进行数据操作select u from User u 、from User ——User是实体类名称,不是表名称
分页查询实体管理对象.createQuery(查询语句) 查询后得到查询对象查询对象.setFirstResult(0) ——0为起始索引查询对象.setMaxResults(5) ——5为每页显示数据数量
条件查询查询对象.setParameter(问号占位符索引,模糊查询) ——sql语句中需要有问号占位符
排序查询
slq语句中使用 order by 进行排序
统计查询
sql语句中直接进行数据统计,通过 getSingleResult 方法得到总数据条数
五、SpringDataJPA基础配置
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!使用 Spring Data JPA 可以极大提高开发效率!Spring Data Jpa 极大简化了数据库访问层代码。
使用SpringDataJPA后只需要编写dao接口继承相关接口即可实现增删改查和分页查询等方法
引入依赖(依赖jar包版本需要一致,所以需要编写统一版本号)
<properties>
<!-- 设置默认编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<spring.version>4.1.7.RELEASE</spring.version>
<hibernate.version>5.0.12.Final</hibernate.version>
</properties>
<dependencies>
<!--context、beans、aop、core、expression-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--orm、beans、jdbc、tx-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring-aspects、aspectjweaver-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!--context-support、core、beans-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring测试单元-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!--springDataJpa-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
<!--JPA实现厂商-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!--数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.17</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--测试单元-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
编写spring.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<context:property-placeholder location="classpath:db.properties"/> <!--数据库连接配置文件-->
<!--配置数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- 1、数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 2、提供厂商 -->
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider"/>
</property>
<!-- 3、JPA的一些配置 -->
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<!--4、 扫描实体类-->
<property name="packagesToScan" value="com.qt.entity"/>
</bean>
<!-- 配置事务管理 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!--
整合SpringDataJpa
指定接口包扫描路径
指定entityManagerFactory
指定事务管理器transactionManager
-->
<jpa:repositories
base-package="com.qt.dao"
entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager"/>
<!--事务注解驱动-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--开启aop注解支持-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
实体类配置
类需要配置注解 @Entity 和注解 @Table
id主键配置注解 @Id 和注解 @GeneratedValue(strategy=GenerationType.IDENTITY)
Dao层接口配置
继承 JpaRepository<实体类,id类型> 和 JpaSpecificationExecutor<实体类> 接口
JpaRepository用于普通的增删改查
JpaSpecificationExecutor用于复杂的多条件查询
六、SpringDataJPA查询
1、基本查询
查询全部:直接调用 findAll() 方法返回一个实体类对象集合
分页查询:
创建一个页码请求对象 new PageRequest() ,传入参数当前页和页码大小,调用 findAll 方法传入 页码请求对象 参数
返回分页对象,使用 getTotalPages 方法得到总页数,使用 getTotalElements 方法得到总数据条数,使用 getContent 得到查询到的数据
排序查询:创建一个排序对象 new Sort() 传入排序规则(Sort.Direction.ASC)和需要排序的字段,调用 findAll 方法传入 排序对象 参数
2、复杂查询
JPQL方式查询—— @Query("from User where id =?1") User findById(Integer id);
在dao层使用 @Query 注解结合JPQL语句完成查询
如果有多个参数则需要在问号后面加上参数索引 update User set username=?1 where id=?2 ——索引为该对应参数传入的位置
如果是进行更新或者删除操作则必须加上 @Modifying 注解
如果是在测试单元中测试则需要加上事务注解,进行更新操作时spirng会进行一个回滚操作,需要设置注解 @Rollback 为false(不自动回滚)
_
SQL语句查询—— @Query(value = "select * from user where id=?1", nativeQuery = true) User findById_SQL(Integer id);
除了写常规SQL语句外,还需要在注解 @Query 中添加 nativeQuery 属性为true(开启本地sql)
方法命名规则查询—— List<User> findByUsernameLike(String username);
通过方法方法名称就能直接创建查询(需要按照SpringDataJPA定义的规则给方法取名)
方法以 findBy 开头,涉及到条件查询时,条件的属性用条件关键字连接(条件属性首字母需要大写)
| 关键字 | 实例 | 对应的JPQL语句 |
|---|---|---|
| And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
| Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
| Is,Equals | findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
| Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
| LessThan | findByAgeLessThan | … where x.age < ?1 |
| LessThanEqual | findByAgeLessThanEqual | … where x.age ⇐ ?1 |
| GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
| GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
| After | findByStartDateAfter | … where x.startDate > ?1 |
| Before | findByStartDateBefore | … where x.startDate < ?1 |
| IsNull | findByAgeIsNull | … where x.age is null |
| IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
| Like | findByFirstnameLike | … where x.firstname like ?1 |
| NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
| StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
| EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
| Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
| OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
| Not | findByLastnameNot | … where x.lastname <> ?1 |
| In | findByAgeIn(Collection ages) | … where x.age in ?1 |
| NotIn | findByAgeNotIn(Collection age) | … where x.age not in ?1 |
| TRUE | findByActiveTrue() | … where x.active = true |
| FALSE | findByActiveFalse() | … where x.active = false |
| IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
Specifications动态查询
通过匿名内部类的方式创建一个 Specification子类对象 ,复写其方法
参数 Root 用于获取元素属性,参数 CriteriaQuery 为自定义查询对象,参数 CriteriaBuilder 为构建查询的对象
构件查询对象会将多条件拼接成一条动态sql进行查询
| 方法名称 | Sql对应关系 |
|---|---|
| equle | filed = value |
| gt(greaterThan ) | filed > value |
| lt(lessThan ) | filed < value |
| ge(greaterThanOrEqualTo ) | filed >= value |
| le( lessThanOrEqualTo) | filed <= value |
| notEqule | filed != value |
| like | filed like value |
| notLike | filed not like value |
