Spring Data Jpa

1. JPA是什么?

Java Persistence API:用于对象持久化的一组API。spring

JPA的思想就是:能够用Java代码实现的,为何还要本身去编写sql语句?其核心的一切都是围绕如何拼接SQL语句进行的。sql

二、Spring Data

Spring Data 是 Spring 的一个子项目。用于简化数据库访问,支持NoSQL 和 关系型数据存储。其主要目标是使数据库的访问变得方便快捷。Spring Data 具备以下特色:数据库

一、SpringData 项目支持 NoSQL 存储: express

MongoDB (文档数据库)
Neo4j(图形数据库)
Redis(键/值存储)
Hbase(列族数据库)框架

二、SpringData 项目所支持的关系型数据存储技术: ide

JDBC
JPA源码分析

三、使用jpa须要给实体类加注解

@Entity(name = "t_book")
public class Book {
    private Long id;
    private String name;
    private String author;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }
    // 省略其余getter/setter
}

@Entity注解表示这是一个实体类,那么在项目启动时会自动针对该类生成一张表,默认的表名为类名,若是使用了name属性表示自定义生成的表名。@Id注解表示这个字段是一个id,@GeneratedValue注解表示主键采用自增加策略,对于类中的其余属性,默认都会根据属性名在表中生成相应的字段,字段名和属性名相同,若是开发者想要对字段进行定制,可使用@Column注解,去配置字段的名称,长度,是否为空等等。学习

四、多条件单表查询

构建谓语

Specification<Product> specification = new Specification<Product>() {
            @Override
            public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Expression<String> idCol = root.get("id");
                Expression<BigDecimal> rewardRateCol = root.get("rewardRate");
                Expression<String> statusCol = root.get("status");
                List<Predicate> predicates = new ArrayList<>();
                if (idList != null && idList.size() > 0) {
                    predicates.add(idCol.in(idList));   //##1
                }
                if (minRewardRate != null && BigDecimal.ZERO.compareTo(minRewardRate) < 0) {
                    predicates.add(cb.ge(rewardRateCol, minRewardRate));     //##2
                }
                if (maxRewardRate != null && BigDecimal.ZERO.compareTo(maxRewardRate) < 0) {
                    predicates.add(cb.le(rewardRateCol, maxRewardRate));
                }
                if (statusList != null && statusList.size() > 0) {
                    predicates.add(statusCol.in(statusList));
                }

                query.where(predicates.toArray(new Predicate[0]));
                return null;
            }
        };
        Page<Product> page = repository.findAll(specification, pageable);

谓语是什么呢?按个人理解,谓语就是一个条件限定词。
一、使用Expression的in方法构建了一个包含的条件(或谓语),查询结果的id须要包含在idList里。
二、咱们使用criteriaBuilder的ge方法构建了一个大于的条件(或谓语),该条件要求收益率大于指定的值。ui

五、自定义查询@Query的使用

@Query(value = "SELECT CONCAT_WS('|', order_id,outer_order_id,chan_id,chan_user_id,product_id,order_type,amount,DATE_FORMAT( create_at,'%Y-%m-%d %H:%i:%s')) FROM order_t WHERE order_status = 'success' AND chan_id = ?1 AND create_at >= ?2 AND create_at < ?3",nativeQuery = true)
    List<String> queryVerifiableOrders(String chanId, Date start, Date end);

这里有三个参数,对应三个占位符,占位符是固定写法。还有另一种使用命名参数的方式。
nativeQuery = true表示这里使用的是原生态的sql查询语句。翻译

六、合法参数校验

Spring 采用一个 org.springframework.util.Assert 通用类完成这一任务。
Assert 翻译为中文为“断言”,使用过 JUnit 的读者都熟知这个概念,它判定某一个实际的运行值和预期想同样,不然就抛出异常。Spring 对方法入参的检测借用了这个概念,其提供的 Assert 类拥有众多按规则对方法入参进行断言的方法,能够知足大部分方法入参检测的要求。这些断言方法在入参不知足要求时就会抛出 。IllegalArgumentException。
经常使用断言方法源码分析:

public static void notNull(@Nullable Object object, String message) {
        if (object == null) {
            throw new IllegalArgumentException(message);
        }
    }

当object为null时抛出异常。


public static void isTrue(boolean expression, String message) {
        if (!expression) {
            throw new IllegalArgumentException(message);
        }
    }

当 expression 为true经过,flase时抛出异常。

七、Log4j

Log4j建议只使用四个级别,优先级从高到低分别是 ERROR、WARN、INFO、DEBUG。

经过在这里定义的级别,您能够控制到应用程序中相应级别的日志信息的开关。好比在这里定义了INFO级别, 则应用程序中全部DEBUG级别的日志信息将不被打印出来。优先级高的将被打印出来。项目上生产环境时候必定得把debug的日志级别从新调为warn或者更高,避免产生大量日志。

八、配置多数据源

目标

@Test
public void queryOrder(){
    System.out.println(orderRepository.findAll());
    System.out.println(readOrderRepository.findAll());
}

orderRepository.findAll()链接的是主库、生成订单。

readOrderRepository.findAll()链接的是从库、生成对帐文件、保存渠道的订单信息。

目标定好了,如何实现呢?
有什么方法帮助本身找到答案?

九、学习经验

一、若是若是遇到不太熟悉的代码,主要经过点击方法查看源码寻找答案,JDK相关的才看官方API文档。框架相关的资料大多不完善,找文档很费时间,点击方法看看源码是怎么实现的,足以解决问题。

相关文章
相关标签/搜索