一、ORM

对象关系映射,通过ORM可以把对象映射到关系型数据库中,只要建立对象与数据库的关联,操作对象就可以直接操作数据库中的数据。

特点:
1、可以直接以面向对象的形式操作数据库
2、根据ORM框架能够自动生成SQL(hibernate是全ORM框架,mybatis是半ORM框架)

二、JPA介绍

JPA是一种规范。
使用ORM技术的框架有很多,但是都没有一个统一的规范,增加了开发难度。使用JPA规范后,简化了现有Java EE和JavaSE应用开发工作的同时,整合ORM技术。
1.png

三、JPA入门

引入依赖jar包

  1. <properties>
  2. <!-- 设置默认编码 -->
  3. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  4. </properties>
  5. <dependencies>
  6. <!--Hibernate对JAP的支持包-->
  7. <dependency>
  8. <groupId>org.hibernate</groupId>
  9. <artifactId>hibernate-entitymanager</artifactId>
  10. <version>5.0.12.Final</version>
  11. </dependency>
  12. <!--mysql驱动-->
  13. <dependency>
  14. <groupId>mysql</groupId>
  15. <artifactId>mysql-connector-java</artifactId>
  16. <version>5.1.47</version>
  17. </dependency>
  18. <dependency>
  19. <groupId>junit</groupId>
  20. <artifactId>junit</artifactId>
  21. <version>4.12</version>
  22. </dependency>
  23. </dependencies>

将项目添加为JPA项目,生成JPA核心配置文件
11.png
13.png

创建实体类
实体类需要使用注解 @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 ufrom 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会进行一个回滚操作,需要设置注解 @Rollbackfalse(不自动回滚)
_
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