Spring数据库编程

1.数据库基本操作

增、删、改、查
分页 排序
事务特征:原子性,一致性,独立性,持久性。--ACID
     自动提交、保存点、回滚  COMMIT & ROLLBACK
     批量更新(patch update)
  缓存 、刷新 flush
  动态来构建查询条件
  flush方法的主要作用就是清理缓存,commit方法隐式的调用了flush
  加入flush强制Hibernate将缓存中记录的操作flush入数据库

2.Spring与两种常见的ORM方案集成

ORM框架可以通过javax.persistence包 中元数据标签,使得实体类与数据库中的表建立映射关系
    JPA中,标准查询是以元模型的概念为基础的
    方案一: JPA
    方案二: Hibernate
方案一:
       Hibernate          org.apache.Session
方案二:
    JPA
     01.Java Persistence API
          基于模板的JPA方式
          基于纯粹的JPA方式 
      02.基于Spring Data实现自动化JPA Repository
          public interface CasDao extends JpaRepository<CashShunt, Integer> {}
             集成JpaRepository接口意味着默认已经拥有以下数据访问操作方法
              自定义方式
                @Query ("select P from  Person  where address =?l")

3.JPA的核心概念和基本过程

0.实体生命周期是JPA中非常重要的概念,描述了实体对象从创建到受控、从删除到游离的状态变换。
 对实体的操作主要就是改变实体的状态。
 基本概念:ID生成策略、关联关系、继承关系、事件及监听、事务管理
1.JPA中和数据库中对应关系
         对象端            数据库端            annotion        可选annotion
        Class               Table           @Entity         @Table(name="tablename")
        property            column          –               @Column(name = "columnname")
        property            primary key     @Id             @GeneratedValue 详见ID生成策略
        property            NONE            @Transient   
2.JPA和Hibernate中的对应关系
     org.hibernate                  javax.persistence           说明
     cfg.Configuration              Persistence                 读取配置信息
     SessionFactory                 EntityManagerFactory        用于创建会话/实体管理器的工厂类
     Session                        EntityManager               提供实体操作API,管理事务,创建查询
     Transaction                    EntityTransaction           管理事务
     Query                          Query                       执行查询
3. JPA提供三种查询方式: 1)JPQL 2)Criteria API 3)SQL
1.Criteria API
      01.// 获得实体管理器             EntityManager em = …
        // 获得Criteria建立器            CriteriaBuilder cb = em.getCriteriaBuilder();
        // 建立Criteria查询             CriteriaQuery<Contact> query = cb.greateQuery(Contact.class);
        // 创建查询Root                 Root<Contact> root = query.from(Contact.class);
        // 创建firstName的查询条件,使用静态元模型 Predicate firstNameIs = cb.equal(root.get(Contact_.firstName, "John"));
        // 指定查询的where条件                    query.where(firstNameIs);
        //通过EntityManager创建TypedQuery      TypedQuery<Contact> q = em.createQuery(query);
        // 创建查询并获取结果                           List<Contact> contacts = q.getResultList();
        说明:Root代表要查询的表,
                 CriteriaBuilder创建条件Predicate,Predicate相对于SQL的where条件,多个Predicate可以进行与、或操作
            元模型类,类名最后一个字符为下划线
2.另一种就是使用JPQL查询语言:JPQL全称Java Persistence Query Language,通过 Query 接口封装执行
        JPQL的查询可以分为命名查询和动态查询
        动态:
            EntityManager.createQuery 方法创建动态查询:
                    有位置参数和命名参数,位置前加符号”?”,命名参数是名称前是加符号”:”
                    from后边的Person是实体Bean而不是数据表
        命名查询
                实体bean上通过 @NamedQuery or @NamedQueries预先定义一个或多个查询语句
                当命名查询定义好了之后,我们就可以通过名称执行其查询
        查询的过程
         01// 获得实体管理器   EntityManager em = …
              // 建立JPQL查询       String getByFirstName = "SELECT c FROM Contact c WHERE c.firstName = :firstName";
              // 创建查询实例     TypedQuery<Contact> query = em.createQuery(getByFirstName, Contact.class);
              // 设置查询参数     query.setParameter("firstName", "John");
              // 获取结果               List<Contact> contacts = query.getResultList();
        查询过程说明:利用 EntityManager API 和 Query API 的相应方法
            01、使用注入或通过 EntityManagerFactory 实例获取一个 EntityManager 实例。
            02.   通过调用相应 EntityManager 的方法(如 createQuery ),创建一个 Query 实例。
            03.   相关设置
                        001.如果有查询参数,使用相应 Query 的 setParameter 方法进行设置。
                        002.如果需要,使用 setFlushMode Query 的方法设置查询执行的刷新模式,覆盖实体管理器的刷新模式
                        等,FlushModeType.AUTO 为自动更新数据库记录,FlushMode Type.COMMIT 为直到提交事务时才更新数据库记录
3.  JPA支持本地查询,所谓本地查询,就是使用原生的sql语句(
     根据数据库的不同,在sql的语法或结构方面可能有所区别)进行查询数据库的操作
    01.// 获得实体管理器           EntityManager em = …
    // 建立SQL查询              String getByFirstName = "SELECT * FROM contacts c WHERE c.first_name = ?1";
    // 创建查询实例               Query query = em.createNativeQuery(getByFirstName, Contact.class);  
    // 设置查询参数               query.setParameter(1, "John");
    // 获取结果                     List contacts = query.getResultList();
说明
 EntityManager 是JPA中用于增删改查的接口,
它的作用相当于一座桥梁,连接内存中的java对象和数据库的数据存储
 持久化单元(Persistence Unit)
  注入EntityManager对 象时必须指定持久化名称,
  通过 @PersistenceContext注释的unitName属性进行指定
     @PersistenceContext(unitName = "billingEntityManagerFactory")
     private EntityManagerFactory emf;
     EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-1")
         persist方法的一个功能:使对象由临时状态变为持久化状态     
    TypedQuery
      TypedQuery.
         setMaxResults、setFirstResult、 setHint、setParameter、setFlushMode、setLockMode
         getResultList、getSingleResult、
常见的分层设计
T 是指任意类,而PK是指一个继承了Serializable接口的接口或者实现了Serializable的实现类
   public interface IGDAO<T extends Serializable, PK extends Serializable> extends Serializable {
   public abstract class BaseDaoImpl<T extends Serializable, PK extends Serializable> implements IGDAO<T, PK> {
  public interface AccountCodeDao extends IGDAO<Tbillconfig, String>     
  public class AccountCodeDaoImpl extends BaseDaoImpl<Tbillconfig, String> implements AccountCodeDao {

方式二
 BaseDAO, 其他DAO继承这个BaseDAO,根据主键来进行添删改查 ,适用于通用的
    至于具体业务操作的,就一对一写在特定的DAO里面 
   public class BaseDao {
   public interface NewsDao 
public class NewsDaoImpl extends BaseDao implements NewsDao{

方式三
public abstract class BaseDao<T extends Serializable, PK extends Serializable> {
public class  AccountCodeDao extends BaseDao<BankAccountCode, Integer> {

2.serialVersionUID适用于Java的序列化机制。
一个类实现了Serializable接口
   简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的
   serialVersionUID有两种显示的生成方式:        
一是默认的1L,比如:private static final long serialVersionUID = 1L;        
二是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:        
private static final  long   serialVersionUID = xxxxL;

SpringBoot—访问关系型数据库

spring-boot-starter-data-jpa 的 起步依赖
    spring-boot-starter-data-jpa    支持Hibernate的Spring JPA。
      org.springframework.boot.jdbc.DataSourceBuilder
      org.apache.commons.dbcp2.BasicDataSource
 数据库配置--连接和参数设置
01.Tomcat数据源连接池
02.开源数据库连接池主要有c3p0、 dbcp 、proxool三种 com.mchange.c3p0
    DBCP(DataBase connection pool)数据库连接池
    C3P0开源项目有Hibernate,Spring等。c3p0有自己主动回收空暇连接功能
03.Spring Boot中默认支持的连接池: dbcp、 dbcp2  等
    prefix: spring.datasource.dbcp2.*
 org.springframework.boot.jdbc
     Spring Boot实现了自动加载DataSource及相关配置
spring-boot-starter-data-jpa
    SpringDataJPA对类似hibernate这样的框架又做了一层封装
    SpringDataJPA中,我们不在称其为mapper或者dao,而是称为repository
    创建接口,继承自JpaRepository,泛型左边为实体类型,右边为该实体的主键类型
    SpringDataJPA帮我们提供了一套实现,在运行的时候会以代理的形式给我们生成实现类,
    只要你继承了Spring给你的这些Repository接口,那么你就能获得这些方法支持
         自定义的方法一般有两种,第一种就是这种“约定命名”法,
           内部帮我们拼接sql代理生成方法的实现
         第二种方法就是 使用 @Query注解使用JPQL(类似SQL与EL的组合)语句查询,
           直接内部转化成SQL进行执行
关于DAO层的规范 
    1.对于不需要写实现类的情况: 
   定义XxxxRepository 接口
       并继承 JpaRepository 接口, 说明:org.springframework.data.jpa.repository.JpaRepository;
        默认预先生成了一些基本的CURD的方法,例如:增、删、改等等
   如果Spring data 所提供的默 认接口方法不够用, 可以使用 @Query在其中定义个性化的接口方法。
   SpringDataJPA在使用的时候,也只需要声明一个接口,让其Spring以代理的形式生成Dao   
    2.对于需要写实现类的情况:
      定义XxxxDao 接口
          并继承com.aceona.appleframework.persistent.data.GenericDao 
     书写XxxxDaoImpl实现类
          并继承com.aceona.appleframework.persistent.data.GenericJpaDao,同时实现XxxxDao接口中的方法  
 SpringBoot 实现的JPA 封装了JPA的特性,只需要写接口即可
    JpaRepository
Repository(资源库):通过用来访问领域对象的一个类似集合的接口,
    在领域与数据映射层之间进行协调。这个叫法就类似于我们通常所说的DAO
    即 把数据访问层叫Repository
所有继承这个接口的interface都被spring所管理,此接口作为标识接口
    public interface ChargeShuntDao extends JpaRepository<ChargeShunt, Integer>  {}

参考

Spring实战

blogroll

social