专栏首页后端Coderjava进阶|JPA系列教程(一)单表操作

java进阶|JPA系列教程(一)单表操作

什么是JPA?

JPA是Java Persistence API的简称,中文名Java持久层API,是JDK5.0注解或XML描述对象-关系表的映射关系,并将运行器的实体对象持久化到数据库中。

本文实现的内容如下:

关于JPA对user表的单表操作,主要包含的内容如下
(1)根据userId获取用户信息。
(2)获取用户列表信息。
(3)保存用户信息。
(4)更新用户信息。
(5)删除用户信息。
(6)分页获取用户列表信息,这个很常用吧,没有见过不分页就对数据表进行查询的,或者基于时间段进行查询。
(7)批量删除,主要根据用户id进行删除,其目的就是提高用户的使用体验。

一,项目依赖的jar包信息

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

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

二,项目所依赖的数据库和JPA信息配置

server:
  port: 8080
spring:
  application:
    name: jpa-springboot
  datasource:
    url: jdbc:mysql://localhost:3306/jpa?serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    show-sql: on
    hibernate:
      ddl-auto: update
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect

说明一下,记得配置JPA的方言,即database-platform。

三,项目需要的基础类

package com.wpw.jpaspringboot.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import javax.persistence.*;
import java.io.Serializable;

/**
 * @author wpw
 */
@Entity
@Table(name = "user")
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@Accessors(chain = true)
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column(name = "username")
    private String userName;
    @Column(name = "password")
    private String passWord;
}
package com.wpw.jpaspringboot.vo;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.util.List;

/**
 * @author wpw
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@Accessors(chain = true)
public class RequestVo {
    private List<Long> idList;
}

四,项目的处理器controller,主要用户接收前端传入的参数,这里基于postman测试工具进行测试。

package com.wpw.jpaspringboot.controller;

import com.wpw.jpaspringboot.vo.RequestVo;
import com.wpw.jpaspringboot.entity.User;
import com.wpw.jpaspringboot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author wpw
 */
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping(value = "/get")
    public User getById(@RequestParam(value = "id") Long id) {
        return userService.getById(id);
    }

    @GetMapping(value = "/listUser")
    public List<User> listUser() {
        return userService.listUser();
    }

    @PostMapping(value = "/save")
    public Long save(@RequestBody User user) {
        return userService.save(user);
    }

    @PutMapping(value = "/update")
    public Long update(@RequestBody User user) {
        return userService.update(user);
    }

    @GetMapping(value = "/listPagination")
    public List<User> listPagination(@RequestParam(value = "pageNumber") Integer pageNumber
            , @RequestParam(value = "pageSize") Integer pageSize) {
        return userService.listPagination(pageNumber, pageSize);
    }

    @DeleteMapping(value = "/delete")
    public void delete(@RequestParam(value = "id") Long id) {
        userService.deleteById(id);
    }

    @DeleteMapping(value = "/batchDelete")
    public void batchDelete(@RequestBody RequestVo requestVo) {
        userService.batchDelete(requestVo.getIdList());
    }

}

五,基于java常用的MVC分层架构的写法,这里我们看下业务逻辑层的实现逻辑和接口定义。

package com.wpw.jpaspringboot.service;

import com.wpw.jpaspringboot.entity.User;

import java.util.List;

/**
 * @author wpw
 */
public interface UserService {
    /**
     * 根据用户id查找用户信息
     *
     * @param id 用户id
     * @return 用户信息
     */
    User getById(Long id);

    /**
     * 获取用户列表信息,这个用法其实很少,谁会全表查呢
     *
     * @return 用户列表信息
     */
    List<User> listUser();

    /**
     * 保存用户信息
     *
     * @param user 用户信息
     * @return 主键
     */
    Long save(User user);

    /**
     * 更新用户信息
     *
     * @param user 用户信息
     * @return 主键
     */
    Long update(User user);

    /**
     * 进行分页数据的查询
     *
     * @param pageNumber 其实页
     * @param pageSize   分页大小
     * @return 返回分页后的数据信息
     */
    List<User> listPagination(Integer pageNumber, Integer pageSize);

    /**
     * 根据用户id删除用户信息
     *
     * @param id 用户id
     */
    void deleteById(Long id);

    void batchDelete(List<Long> idList);
}
package com.wpw.jpaspringboot.service.impl;

import com.wpw.jpaspringboot.entity.User;
import com.wpw.jpaspringboot.repository.UserRepository;
import com.wpw.jpaspringboot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author wpw
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;

    @Override
    public User getById(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    @Override
    public List<User> listUser() {
        return userRepository.findAll();
    }

    @Override
    public Long save(User user) {
        return userRepository.save(user).getId();
    }

    @Override
    public Long update(User user) {
        preCheck(user);
        return userRepository.save(user).getId();
    }

    @Override
    public List<User> listPagination(Integer pageNumber, Integer pageSize) {
        PageRequest pageRequest = PageRequest.of(pageNumber - 1, pageSize);
        return userRepository.findAll(pageRequest).getContent();

    }

    @Override
    public void deleteById(Long id) {
        preCheckIsExists(id);
        userRepository.deleteById(id);
    }

    @Override
    public void batchDelete(List<Long> idList) {
        List<User> userList = userRepository.findAllById(idList);
        List<Long> idListNew = userList.stream().map(User::getId).collect(Collectors.toList());
        idList.retainAll(idListNew);
        System.out.println("idList = " + idList);
        userRepository.deleteInBatch(userList);
    }

    private void preCheckIsExists(Long id) {
        Optional<User> optionalUser = userRepository.findById(id);
        if (optionalUser.isPresent()) {
            User u = optionalUser.get();
            if (Objects.isNull(u)) {
                return;
            }
        }
    }

    private void preCheck(User user) {
        preCheckIsExists(user.getId());
    }
}

六,操作数据库,用到了JPA提供好的JpaRepository接口,这里面已经实现了基本的增删改查方法,我们直接调用即可。

package com.wpw.jpaspringboot.repository;

import com.wpw.jpaspringboot.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
 * @author wpw
 */
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

与此同时,给截个图看下这里面的方法吧。

是不是很简单,这也是JPA比较好的地方,一款比较优秀的ORM框架,写到这我还是比较喜欢MyBatis这个框架的,因为我刚刚喜欢上MyBatis框架时又去使用JPA上了,后面再去说下为啥自己习惯MyBatis这个框架吧想了解MyBatis的可以看下我之前写的文章,MyBatis系列教程吧,有点扯远了,这里看下项目的结构示例图。

七,这里说下,由于使用JPA可以帮我们自己创建表,这里就没有定义表结构sql,但是为了方便需要的人,这里自己手写了一下sql。

show databases ;
use jpa;
select database();
create table `user`(
    id bigint primary key  comment '主键,用户id',
    username varchar(255) comment '用户名',
    password varchar(255) comment '用户密码'
)engine=InnoDB charset =utf8 comment '用户表'

八,由于个人习惯将写好的代码放到自己的github账户里面,便于查找,所以这里提供一下这个项目的github地址,需要的可以直接下载。

https://github.com/myownmyway/jpa-springboot.git

到这里这篇文章就结束了,喜欢的可以进行点个在看。

本文分享自微信公众号 - WwpwW(gh_245290c1861a),作者:后端Coder

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • java进阶|MyBatis系列文章(七)多表查询操作

    以上jar包依赖主要是mysql连接,支持mybatis操作以及简化get/set方法的lombok包。

    后端Coder
  • 实现java的异步回调

    说下java的异步回调模式,是指当调用者实现了CallBack接口,调用者包含了被调用者的引用,在调用者类中调用被调用者的方法,然后在被调用者类的方法中调用调用...

    后端Coder
  • java进阶|MyBatis系列文章(四)分页查询加动态sql

    后端Coder
  • SpringBoot 整合 elasticsearch 实例

    下载地址:https://www.elastic.co/downloads/past-releases

    ZhangXianSheng
  • spring mvc报错,数据库查询无限死循环

    进行查询的陷入了无限死循环,原因是问题类中包含了回答,回答类中包含了问题,进入了无限死循环 解决方法:在回答类中的问题类属性上加注解:@JsonBackRefe...

    二十三年蝉
  • JDK源码分析 反射

    对于JDK源码分析的文章,仅仅记录我认为重要的地方。源码的细节实在太多,不可能面面俱到地写清每个逻辑。所以我的JDK源码分析,着重在JDK的体系架构层面,具体源...

    Yano_nankai
  • jdk静态代理,jdk动态代理,cglib动态代理

    代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道。如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法...

    互扯程序
  • Java 编写的轻量级高性能手游服务端框架

    mmorpg,是一个用java编写的轻量级高性能手游服务端框架。项目提供各种支持快速二次开发的组件,以及对生产环境的服务进行管理的工具。同时,为了使用户能够快速...

    java架构师
  • 基于OpenCV实现手写体数字训练与识别

    OpenCV实现手写体数字训练与识别 机器学习(ML)是OpenCV模块之一,对于常见的数字识别与英文字母识别都可以做到很高的识别率,完成这类应用的主要思想与方...

    OpenCV学堂
  • pip报错解决集锦

    华创信息技术

扫码关注云+社区

领取腾讯云代金券