(十一)Spring从入门到入土——Spring整合JPA

1、jpa入门

  • Java持久层api,替代jdbc,Java持久化规范。JPA是Hibernate的一个抽象,是一种ORM规范,是Hibernate功能的一个子集,Hibernate是JPA的一个实现

  • jpa和jdbc优缺点:

    • jdbc:
    • 本质:处理Java对象和关系型数据库表之间的转化

      优点:性能最高,操作数据库最底层

      1.使用复杂(重复代码很多),移植数据库很麻烦

      ​ 2.性能优化需要自己处理,没有提供数据缓存,需要自己实现。

      ​ 3.面向的是sql语句操作,不是面向对象的。

      本质:只是对于jdbc再次做了一层封装

      1.程序员操作很简单,代码简单。

      ​ 2.直接面向持久对象操作

      ​ 3.提供世界级数据缓存(一级缓存,二级缓存,查询缓存)

      ​ 4.数据库移植性很强,很少的修改(通过配置方言):把各种数据库抽取了一个方言接口,不同的数据库实现类一个方言接口,需要换数据库,只需要修改方言实现,驱动jar文件,连接数据库信息(4个:驱动,url地址,用户名,密码)

      1.不能干预sql语句的生成。find方法默认查询表的所有字段

      2.一个项目中如果对sql语句的优化比较高,不适用jpa(不过jpa中有对原生sql的支持)

      ​ 3.如果一个表中有上亿的数据,也不适合用jpa和jdbc(可以使用数据库读写分析,分库分表方案解决)

      • 适用的项目规模:中小型,jpa在性能优化上比较吃力,超大型还是推荐使用MyBatis.
      • ORM框架:就是把数据保存到可掉电式存储设备中,持久层就是dao层,
      • ORM是对象关系映射框架,就是通过Java对象映射到数据库表,通过操作Java对象,就可以完成对数据库表的操作,
      • 2、JPA基本注解

        • @Entity:用于实体类声明语句之前,指出该Java类为实体类,将映射到指定的数据库表。

        • @Table:当实体类与其映射的数据库表名不同名时使用,该标注于@Entity并列使用,置于实体类声明语句之前,可写于单独语句行,也可与声明语句同行。

          • name用于指明数据库的表名
          • catalog和schema用于设置表所属的数据库目录或模式,通常为数据库名
          • uniqueConstraints用于设置约束条件,通常不设置
          • @Id声明一个实体类的属性映射为数据库的主键列。通常位置声明语句之前或者同行,也可以置于属性的getter方法之前。、

          • @GeneratedValue用于标注主键的生成策略,通过strategy属性指定。默认情况下,jpa自动选择一个适合底层数据库的主键生成策略:SqlServer对应identity,MySQL对应auto increment。

            • IDENTITY:采用数据库ID自增长方式来自增主键字段,但是Oracle不支持这种方式
            • AUTO:JPA自动选择合适的策略,是默认选项:
            • SEQUENCE:通过序列产生主键,通过@SequenceGenerator注解指定序列名,但是MySql不支持这种方式
            • TABLE:通过表产生主键,便于数据库的移植
            • @Basic表示一个简单的属性到数据库表的字段的映射对于没有任何标注的get()方法。默认即为@Basic

              • fetch:表示该属性的读取策略,有EAGER和LAZY两种,表示主支抓取和延迟加载,默认为true
              • optional:表示该属性是否允许为null默认为true
              • Column:当实体属性与其映射的数据库表的类不同名时需要使用

              • Transient:表示该属性并非到数据库表的字段的映射,ORM框架将忽略该属性。必须标注

              • Temporal:调整精度

                3、JPA的API

                • Persistence:用于获取EntiryManagerFactory的实例

                  • 常用方法:Persistence. createEntityManagerFactory(persistenceUnitName) 方法
                  • EntiryManagerFactory

                    • 获取EntiryManager
                    • close()方法,关闭自身
                    • EntityManager的常用API

                      • find()方法,在执行find方法时就发送SQL语句(类似于Hibernate中的Session的get()方法)
                      • getReference()方法,若不适用查询的对象则返回一个代理对象,到真正使用的时候才发送SQL语句chax(类似于Hibernate的Session的load()方法)
                      • persistence()方法,类似于 Hibernate 的 save() 方法,与 Hibernate 的 save() 方法不同的是其不能插入一个有 id 属性的对象
                      • remove() 方法,类似于 Hibernate 中 Session 的 delete 方法,但是其不能删除 游离化对象(仅有 id)
                      • merge() 方法,类似于 Hibernate 中 Session 的 saveOrUpdate() 方法
                      • EntityTransaction:JPA中的事务操作

                        • 常用API:begin();commit();rollback()
                        • 4、JPA中映射关联关系

                          • 映射单向多对一的关联关系,many的一方作为关系的维护段,one的一方作为被维护端,one方指定@OneToMany注释并设置mappedBy属性,以指定他是被维护端,many方指定@ManyToOne注解,并使用@JoinColumn指点外键名称

                            • 创建Order实体类:标注注解生成数据表,使用@ManyToOne映射多对一的关联关系,使用@JoinColumn来标注外键。
                            • 单向多对一的保存:保存多对一是,建议先保存1的一段,这样不会多出额外的update语句
                            • 获取操作(find):默认情况下使用左外连接的方式来获取n的一端的对象和其关联的1的一端的对象。可以使用@ManyToOne的fetch属性来修改默认的关联属性的加载策略
                            • 删除操作(remove):不能直接删除1的一端,因为有外键约束
                            • 修改操作:可以根据n的一端对1的一端镜像修改操作。
                            • 映射单项一对多的关联关系Customer:Order 1:n,Customer中有Order的Set稽核属性,Order中没有Customer的属性

                              • 在Customer中添加Order的Set集合属性,并映射1-n关联关系,重新生成数据表
                              • 保存操作(persist):总会多出UPDATE语句,n的一端在插入式不会同时插入外键列
                              • 查询操作(find)默认使用懒加载
                              • 删除操作(remove):默认情况下删除1的一端,会先把关联的n的一端的外键置空,然后再删除,可以通过@OneToMany的cascade属性
                              • 映射双向多对一的关联关系(注:双向多对一通双向一对多)

                                • 实体:Customer中有Order的Set集合属性,Order中有Customer的属性,两个实体映射的外键列必须一致,都为CUSTOMER_ID
                                • 保存操作(persist):
                                • 映射双向一对一的关联关系

                                • 映射双向多对多的关联关系

                                  5、JPA的二级缓存

                                  • 若JPA实现支持二级缓存,该节点可以配置在当前的持久化单位中是否启用二级换窜,可配置如下值:

                                    • ALL:所有实体类都被缓存
                                    • NONE:所有实体类都不能被缓存
                                    • ENABLE_SELECTIVE:表示@Cacheable(true)注解的实体类将被缓存
                                    • DISABLE_SELECTIVE:换窜除表示@Cacheable(false)依赖的所有实体类
                                    • UNSPECIFIED:默认值,JPA产品默认值将被使用
                                    • 6、JPQL

                                      • JPQL语言的语句是select语句,update语句或delete语句,他们都通过Query接口封装执行

                                      • Query接口封装了执行数据库查询的相关方法。调用 EntityManager的createQuery、createNamedQuery及createNativeQuery方法可以获得查询对象,进而可调用Query接口的相关方法来执行查询操作。

                                      • Query接口的主要方法:

                                        • int executeUpdate()
                                            • 用于执行update或delete语句
                                              • from是必选子句,如果不想返回重复实体,可以使用关键字distinct来进行修饰
                                              • 查询所有实体:select o from Order o
                                              • 调用 EntityManager的createQuery()方法可创建查询对象,接着调用Query接口的getResultList()方法就可获得查询结果集
                                              • where子句用于指定查询条件,也支持包含参数的查询,但是参数名前必须冠以冒号。同样也可以使用参数序号
                                              • order by子句,可以对查询结果镜像排序,默认为升序,asc(升序)desc(降序)
                                              • group by子句与聚合查询,通常的聚合函数:AVG,COUNT,MAX,MIN
                                              • having子句用于对group by分组设置约束条件,用法与where子句基本相同,having子句作用于分组,用于选择满足条件的组,其条件表单时中通常会使用聚合函数
                                              • 关联查询。默认左关联,
                                              • 子查询:常出现在any,all,exist s表达式中用于集合匹配查询
                                              • JPQL函数:字符串处理函数,算术函数和日期函数

                                              • UPDATE语句:用于执行数据更新操作,主要用于针对单个实体类的批量更新

                                              • DELETE语句:用于执行数据更新操作

                                                7、整合Spring

                                                三种整合方式

                                                • LocalEntityManagerFactoryBean:适用于那些仅使用 JPA 进行数据访问的项目,该 FactoryBean 将根据JPA PersistenceProvider 自动检测配置文件进行工作,一般从“META-INF/persistence.xml”读取配置信息,这种方式最简单,但不能设置Spring 中定义的DataSource,且不支持 Spring管理的全局事务
                                                • 从JNDI中获取:用于从 Java EE 服务器获取指定的EntityManagerFactory,这种方式在进行 Spring 事务管理时一般要使用 JTA 事务管理
                                                • LocalContainerEntityManagerFactoryBean**:适用于所有环境的 FactoryBean,能全面控制 EntityManagerFactory 配置,如指定 Spring 定义的 DataSource 等等。
                                                  • 如果觉得看完有收获,希望能给我点个赞,这将会是我更新的最大动力,感谢各位的支持
                                                  • 欢迎各位关注我的公众号【java冢狐】,专注于java和计算机基础知识,保证让你看完有所收获,不信你打我