清茶书香

一杯清茶,一本书籍,一个下午。


  • 首页

  • 归档

  • 分类

  • 关于

  • 搜索
Redis JPA Solr SpringData SpringMVC localRepository local Mapper 事务 Mybatis JDBC AOP DI IOC 常用函数 触发器 存储过程 Promise Gateway SpringCloud vue-cli axios es6 webpack npm vue 个性化 zsh 终端 caffeine jvm缓存 guava cache validation Mapping MapStruct comment 小程序 建站 WeHalo config logback plugins database idea maven spring https http nginx password RabbitMQ 秒杀系统 Windows MySQL 数据备份 halo SpringBoot shell Linux ip Optional Stream Lambda k8s Docker 列编辑 vim MacOS 图片合成 Java 远程联调 nps 内网穿透

了解Spring Data(一)

发表于 2019-08-03 | 分类于 spring系列 | 0 | 阅读次数 195

spring data包含很多与数据库相关的内容,这里我们主要介绍spring data中的jpa、redis、solr的内容。

JPA

简介

Jpa (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范。它为 Java 开发人员提供了一种对象/关联映射工具来管理 Java 应用中的关系数据。它的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术,结束现在 Hibernate,TopLink,JDO 等 ORM 框架各自为营的局面。

注意:Jpa 是一套规范,不是一套产品,那么像 Hibernate,TopLink,JDO 他们是一套产品,如果说这些产品实现了这个 Jpa 规范,那么我们就可以叫他们为 Jpa 的实现产品。

Spring Boot Jpa 是 Spring 基于 ORM 框架、Jpa 规范的基础上封装的一套 Jpa 应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data Jpa 可以极大提高开发效率!

Spring Boot Jpa 让我们解脱了 DAO 层的操作,基本上所有 CRUD 都可以依赖于它来实现

添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <!-- 如果你的是1.5.21版spring boot,或者你的MySQL是5.6及以上版本就可以不指定版本,否则可以指定一下版本,2.x系列spring boot指定的驱动是8.0版的,不指定版本会跟自己的MySQL数据库连接不上(版本不兼容) -->
    <!-- <version>5.1.47</version> -->
</dependency>

使用JPA

创建实体类

下面以我自己的数据库中的一个message表为例

import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.sql.Timestamp;

/**
 * 使用Spring Data JPA操作数据库,实体类上需要加@Entity注解、主键属性上需要加@Id注解.
 * 这个@Entity注解是JPA里提供的注解,标注此类是一个实体类
 *
 * @author bennett
 */

@Setter
@Getter
@Entity
@Table(name = "message")
public class Message {

    /**
     * 消息状态:已读状态
     */
    public static final int STATUS_READED = 1;
    /**
     * 消息状态:未读状态
     */
    public static final int STATUS_UNREAD = 2;
    /**
     * 消息状态:删除状态
     */
    public static final int STATUS_DELETE = 3;

    /**
     * 也是JPA里提供的注解,标注了此属性是主键ID
     */
    @Id
    @GeneratedValue
    private Integer id;

    /**
     * 这里如果用apache的dbutils查询的话,字段名称必须和数据库中完全一样。否则结果集封装不进来
     */
    @Column
    private Integer fromId;
    @Column
    private Integer toId;
    @Column
    private String subject;
    @Column
    private String content;
    @Column
    private Integer status;
    @Column
    private Timestamp createTime;
    @Column
    private String attachment;

    @Override
    public String toString() {
        return "Message{" + "id=" + id + ", fromId=" + fromId + ", toId=" + toId + ", subject='" + subject + '\'' + ", content='" + content + '\'' + ", status=" + status + ", createTime=" + createTime + ", attachment='" + attachment + '\'' + '}';
    }
}

自定义CRUD操作

使用spring data中的jpa就可以让我们自己的接口继承JpaRepository这个接口,这样我们就可以同时使用spring boot JPA提供的一些CRUD方法,也可以添加自定义的方法供我们使用。

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import javax.transaction.Transactional;
import java.util.List;

/**
 * 使用JPA完成数据库的CRUD操作
 *
 * @author bennett
 */

public interface MessageDao extends JpaRepository<Message, Integer> {

    /**
     * 按status字段查找
     *
     * @param status 状态
     * @return Message集合
     */
    List<Message> findMessageByStatus(Integer status);

    /**
     * 自定义SQL查询,此处写的不是标准的SQL语句,而是JPQL
     *
     * @return Message集合
     */
    @Query("select m from Message m")
    List<Message> findMessage();

    /**
     * 事务@Transactional注解必须加到update、save、delete这些修改数据操作上(否则会报没有可用事务异常)
     * 下面的@Query、@Modifying这俩注解是一组,适合于自定义SQL语句时配合使用。
     *
     * @param id
     */
    @Transactional(rollbackOn = java.lang.Exception.class)
    @Query("delete from Message where id = ?1")
    @Modifying
    @Override
    void deleteById(Integer id);
}

?1代表第一个占位符?,后续还有条件可以用?2、?3....表示

配置Spring Boot

要想使用JPA还需要在SpringBoot中添加两个属性(1.5.21不需要第二个)

spring:
  jpa:
    show-sql: true
    hibernate:
      use-new-id-generator-mappings: false #这个属性在2.x系列的spring boot中默认是true,要改为false

Spring Boot JPA提供的方法

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

	List<T> findAll();

     /**
     * 返回所有的实体,根据Sort参数提供的规则排序。
     */
	List<T> findAll(Sort sort);

     /**
     * 根据给定的id集合查询所有对应的实体,返回实体集合。
     */
	List<T> findAllById(Iterable<ID> ids);

    /**
     * 保存提供的所有实体。
     */
	<S extends T> List<S> saveAll(Iterable<S> entities);

     /**
     * 将所有未决的更改刷新到数据库。
     */
	void flush();

    /**
     * 保存一个实体并立即将更改刷新到数据库。
     */
	<S extends T> S saveAndFlush(S entity);

    /**
     * 在一个批次中删除给定的实体集合,这意味着将产生一条单独的Query。
     */
	void deleteInBatch(Iterable<T> entities);

    /**
     * 在一个批次中删除所有的实体。
     */
	void deleteAllInBatch();
    
	T getOne(ID id);
    
    /**
    * 根据扩展的条件查询所有
    */
	@Override
	<S extends T> List<S> findAll(Example<S> example);
    
    /**
    * 根据扩展条件和排序规则查询所有并排序
    */
	@Override
	<S extends T> List<S> findAll(Example<S> example, Sort sort);
}

测试JPA的方法

下面仅测试了JPA中的查询方法和几个自定义的方法

import com.demo.springboot.bean.Message;
import com.demo.springboot.dao.MessageDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

/**
 * 测试JPA里面的方法
 *
 * @author bennett
 */

@RunWith(SpringRunner.class)
@SpringBootTest
public class JpaTest {

    @Autowired
    private MessageDao messageDao;

    /**
     * 调用JPA中原生的findAll方法
     */
    @Test
    public void testQueryMessage() {
        List<Message> messageList = messageDao.findAll();
        System.out.println("一共" + messageList.size() + "条数据");
        for (Message message : messageList) {
            System.out.println(message);
        }
    }

    /**
     * 调用自定义的按照status查询
     */
    @Test
    public void testQueryMessageByStatus() {
        List<Message> messageList = messageDao.findMessageByStatus(3);
        System.out.println("一共" + messageList.size() + "条数据");
        for (Message message : messageList) {
            System.out.println(message);
        }
    }

    /**
     * 调用Spring JPA原生 saveAndFlush修改数据(id存在则更新,否则执行插入)
     */
    @Test
    public void testUpdateMessage() {
        Message message = new Message();
        // message.setId(40);
        message.setContent("Bennett");
        messageDao.saveAndFlush(message);
    }

    /**
     * 调用自定义语句完成删除操作
     */
    @Test
    public void testDeleteMessageById() {
        messageDao.deleteById(29);
    }

    /**
     * 调用自定义语句完成查询
     */
    @Test
    public void testQueryMessageBySQL() {
        List<Message> messageList = messageDao.findMessage();
        System.out.println("一共" + messageList.size() + "条数据");
        for (Message message : messageList) {
            System.out.println(message);
        }
    }
}

JPA关键字

具体的关键字,使用方法和生产成SQL如下表所示

KeywordSampleJPQL snippet
AndfindByLastnameAndFirstname… where x.lastname = ?1 and x.firstname = ?2
OrfindByLastnameOrFirstname… where x.lastname = ?1 or x.firstname = ?2
Is,EqualsfindByFirstnameIs,findByFirstnameEquals… where x.firstname = ?1
BetweenfindByStartDateBetween… where x.startDate between ?1 and ?2
LessThanfindByAgeLessThan… where x.age < ?1
LessThanEqualfindByAgeLessThanEqual… where x.age ⇐ ?1
GreaterThanfindByAgeGreaterThan… where x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqual… where x.age >= ?1
AfterfindByStartDateAfter… where x.startDate > ?1
BeforefindByStartDateBefore… where x.startDate < ?1
IsNullfindByAgeIsNull… where x.age is null
IsNotNull,NotNullfindByAge(Is)NotNull… where x.age not null
LikefindByFirstnameLike… where x.firstname like ?1
NotLikefindByFirstnameNotLike… where x.firstname not like ?1
StartingWithfindByFirstnameStartingWith… where x.firstname like ?1 (parameter bound with appended %)
EndingWithfindByFirstnameEndingWith… where x.firstname like ?1 (parameter bound with prepended %)
ContainingfindByFirstnameContaining… where x.firstname like ?1 (parameter bound wrapped in %)
OrderByfindByAgeOrderByLastnameDesc… where x.age = ?1 order by x.lastname desc
NotfindByLastnameNot… where x.lastname <> ?1
InfindByAgeIn(Collection ages)… where x.age in ?1
NotInfindByAgeNotIn(Collection age)… where x.age not in ?1
TRUEfindByActiveTrue()… where x.active = true
FALSEfindByActiveFalse()… where x.active = false
IgnoreCasefindByFirstnameIgnoreCase… where UPPER(x.firstame) = UPPER(?1)

Redis

Redis 是目前业界使用最广泛的内存数据存储。相比 Mogodb,Redis 支持更丰富的数据结构,例如 hash, list, set ,zset等,同时支持数据持久化。本章主要是介绍redis在spring boot中的应用

添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

SpringBoot redis的使用

下面只是给出了spring boot中使用redis的方式,redis的具体使用方式读者可以去看我写的另一篇关于Redis的一些使用方式和介绍👉Spring Boot中Redis的配置与使用。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

/**
 * 练习redis
 *
 * @author bennett
 */

@Service
public class RedisService {

    /**
     * SpringBoot会自动帮我们装配RedisConnectionFactory, StringRedisTemplate, RedisTemplate这几个类
     * 自动装配的属性可以直接注入到我们的类中使用
     */
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 专门操作String类型的key\value
     */
    private StringRedisTemplate redisTemplateForString;

    /**
     * 添加键与值
     *
     * @param key   键
     * @param value 值
     */
    public void set(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 获取指定键的值
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }
}

测试Redis的方法

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * 测试redis
 *
 * @author bennett
 */

@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTest {

    @Autowired
    private RedisService redisService;

    /**
     * 测试Redis
     */
    @Test
    public void testSet() {
        redisService.set("springboot", "hello redis");
        Assert.assertEquals("没存进去", "hello redis", redisService.get("springboot"));
    }
}

介于篇幅问题,本篇文章就先介绍这么多,至于solr搜索引擎请关注下一篇博客。

Bennett wechat
欢迎收藏我的微信小程序,方便查看更新的文章。
  • 本文作者: Bennett
  • 本文链接: https://hibennett.cn/archives/spring-data-jpa-redis
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
# SpringData # JPA # Redis
了解Spring Data(二)之Solr搜索引擎
Idea中的数据库管理工具
  • 文章目录
  • 站点概览
Bennett

Bennett

60 日志
28 分类
74 标签
RSS
Github E-mail Gitee QQ
Creative Commons
Links
  • MacWk
  • 知了
0%
© 2020 — 2023 hibennett.cn版权所有
由 Halo 强力驱动
|
主题 - NexT.Pisces v5.1.4

浙公网安备 33010802011246号

    |    浙ICP备2020040857号-1