JPA学习之注解总结篇

前言:

现在直接操作数据库广泛使用的就是Mybatis和JPA.两种技术都是很好用的,但是相信使用过JPA的人都很清楚,jpa比较mybatis而言,无论是自动创建表单还是可直接调用的操作数据库的方法,都是mybatis所没有的。

在网上看到不少前辈的文章,本文不在做过多的JPA相关讲解,着重于JPA的应用。JPA的参考资料以及学习视频已经在本篇文章的第二部分给出相关链接。

一、什么是JPA

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

二、JPA的参考资料

  • spring boot 中使用 jpa以及jpa介绍:https://blog.csdn.net/wujiaqi0921/article/details/78789087
  • JPA之常用 基本注解:https://www.cnblogs.com/a8457013/p/7753575.html
  • JPA @Basic 注解:http://fanlychie.github.io/post/jpa-basic-annotation.html
  • JPA的Basic注解:http://www.voidcn.com/article/p-ficnnwzf-bbe.html
  • Hibernate,JPA注解@EmbeddedId:https://www.cnblogs.com/xiluhua/p/4382062.html
  • JPA实体标识的自动生成@ SequenceGenerator @GeneratedValue:https://blog.csdn.net/langjian2012/article/details/38894195
  • 【JPA】对象关系映射_访问模式(ACCESS_TYPE(field|Property)):https://blog.csdn.net/jinghua7/article/details/21455727
  • JPA官网:https://blog.csdn.net/weixin_41244495/article/details/88384799
  • JPA、Hibernate、Spring data jpa之间的关系,终于明白了:https://my.oschina.net/u/3080373/blog/1828589
  • JPA中@Access注解小结:https://my.oschina.net/u/1156626/blog/1619239?utm_medium=referral
  • JPA中@JoinTable和@JoinColumn注解的使用:https://blog.csdn.net/yu870646595/article/details/51064634
  • JPA 唯一约束条件@UniqueConstraint注解在Oracle失效问题(数据库表名字段名长度问题):https://blog.csdn.net/weixin_42142057/article/details/100573260
  • JPA注解添加唯一约束:https://blog.csdn.net/qq_38705025/article/details/86636818
  • Java中的@UniqueConstraint注释:https://www.javaroad.cn/articles/1265
  • 视频:https://www.bilibili.com/video/BV1hE411s72B?from=search&seid=6182882383637815756

三、JPA的应用

3.1 项目结构

 3.2 pom.xml以及application.properties

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>jpa_study</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>jpa_study</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <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>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
server.port=8989
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/student
spring.datasource.username=postgres
spring.datasource.password=root
spring.datasource.driverClassName=org.postgresql.Driver

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

3.3 实体类

package com.example.jpa_study.controller.param;

public class StudentParam {
    private String name;
    private String address;
    private Integer pageNo;
    private Integer pageSize;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Integer getPageNo() {
        return pageNo;
    }

    public void setPageNo(Integer pageNo) {
        this.pageNo = pageNo;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }
}
package com.example.jpa_study.controller.vo;

import java.util.List;

public class PageData<T> {
    private List<T> list;
    private long total;

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        this.total = total;
    }
}
package com.example.jpa_study.repository.entity;

import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.UpdateTimestamp;

import javax.persistence.*;
import java.util.Date;

@Table(name = "tb_student_info")
@Entity
public class Student {
    /**
     * 主键id
     */
    private String id;
    /**
     * 学生姓名
     */
    private String name;
    /**
     * 学生年龄 不放入数据库中
     */
    private Integer age;
    /**
     * 出生年月日
     */
    private Date birthDay;
    /**
     * 家庭住址
     */
    private String address;
    /**
     * 创建时间
     */
    private Date createTime;
    /**
     * 更新时间
     */
    private Date updateTime;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Column(name = "stu_name", length = 20, nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Transient
    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Temporal(TemporalType.DATE)
    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @CreationTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    public Date getCreateTime() {
        if (createTime != null) {
            return (Date) createTime.clone();
        }
        return null;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime == null ? null : (Date) createTime.clone();
    }

    @UpdateTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    public Date getUpdateTime() {
        if (updateTime != null) {
            return (Date) updateTime.clone();
        }
        return null;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime == null ? null : (Date) updateTime.clone();
    }
}

3.4 controller

package com.example.jpa_study.controller;

import com.example.jpa_study.controller.param.StudentParam;
import com.example.jpa_study.controller.vo.PageData;
import com.example.jpa_study.repository.entity.Student;
import com.example.jpa_study.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/student")
public class StudentController {
    @Autowired
    private StudentService studentService;

    @PostMapping("/saveOrUpdate")
    public boolean saveOrUpdate(@RequestBody Student stu) {
        boolean result = false;
        if (stu != null) {
            result = studentService.saveOrUpdate(stu);
        }
        return result;
    }

    @PostMapping("/deleteStudentById")
    public boolean deleteStudentById(@RequestBody List<String> ids) {
        boolean result = studentService.deleteStudentById(ids);
        return result;
    }

    @PostMapping("/list")
    public PageData<Student> list(@RequestBody StudentParam params){
        PageData<Student> students = studentService.list(params);
        return students;
    }



}

3.5 service以及impl

package com.example.jpa_study.service;

import com.example.jpa_study.controller.param.StudentParam;
import com.example.jpa_study.controller.vo.PageData;
import com.example.jpa_study.repository.entity.Student;

import java.util.List;


public interface StudentService {
    /**
     * 添加或修改学生信息
     *
     * @param stu
     * @return
     */
    boolean saveOrUpdate(Student stu);

    /**
     * 删除学生信息
     *
     * @param ids
     * @return
     */
    boolean deleteStudentById(List<String> ids);

    /**
     * 多条件模糊查询学生信息
     *
     * @param params
     * @return
     */
    PageData<Student> list(StudentParam params);

}
package com.example.jpa_study.service.impl;

import ch.qos.logback.core.util.TimeUtil;
import com.example.jpa_study.controller.param.StudentParam;
import com.example.jpa_study.controller.vo.PageData;
import com.example.jpa_study.repository.StudentRepository;
import com.example.jpa_study.repository.entity.Student;
import com.example.jpa_study.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentRepository studentRepository;

    @Override
    public boolean saveOrUpdate(Student stu) {
        Student student = studentRepository.save(stu);
        return student != null;
    }

    @Override
    public boolean deleteStudentById(List<String> ids) {
        if (ids != null && ids.size() > 0) {
            int num = 0;
            for (String id : ids) {
                studentRepository.deleteById(id);
                num++;
            }
            return num == ids.size();
        }
        return false;
    }

    @Override
    public PageData<Student> list(StudentParam content) {
        int pageNo = 1;
        int pageSize = 20;
        if (content.getPageNo() != null && content.getPageSize() != null) {
            pageNo = content.getPageNo();
            pageSize = content.getPageSize();
        }
        PageData<Student> basePage = new PageData<>();
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(new Sort.Order(Sort.Direction.DESC, "updateTime"));
        Sort sort = Sort.by(orders);
        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);
        Page page = studentRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (content.getName() != null && content.getName() != "") {
                String title=content.getName();
                if(title.contains("_") || title.contains("%")){
                    //注:"\"被作为转义字符时必须也被转义
                    title = title.replace("\\","\\\\").replace("_","\\_").replace("%","\\%");
                    predicateList.add(criteriaBuilder.and(criteriaBuilder.like(root.get("name"), "%" + title + "%",'\\')));
                }else{
                    predicateList.add(criteriaBuilder.and(criteriaBuilder.like(root.get("name"), "%" + content.getName() + "%")));
                }
            }
            if (content.getAddress() != null && content.getAddress() != "") {
                String title=content.getAddress();
                if(title.contains("_") || title.contains("%")){
                    //注:"\"被作为转义字符时必须也被转义
                    title = title.replace("\\","\\\\").replace("_","\\_").replace("%","\\%");
                    predicateList.add(criteriaBuilder.and(criteriaBuilder.like(root.get("address"), "%" + title + "%",'\\')));
                }else{
                    predicateList.add(criteriaBuilder.and(criteriaBuilder.like(root.get("address"), "%" + content.getAddress() + "%")));
                }
            }
            return criteriaBuilder.and(
                    predicateList.toArray(new Predicate[predicateList.size()]));
        }, pageable);

        if (null != page && page.getSize() > 0) {
            List<Student> result = page.getContent();
            for (Student stu : result) {
                Date birthDay = stu.getBirthDay();
                Integer age=getStudentAge(birthDay);
                stu.setAge(age);
            }
            basePage.setList(result);
            basePage.setTotal(page.getTotalElements());
        }
        return basePage;
    }

    private Integer getStudentAge(Date birthDay) {
        Calendar cal = Calendar.getInstance();
        if (cal.before(birthDay)) {
            //出生日期晚于当前时间,无法计算
            throw new IllegalArgumentException(
                    "The birthDay is before Now.It's unbelievable!");
        }
        //当前年份
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthDay);
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
        //计算整岁数
        int age = yearNow - yearBirth;
        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                //当前日期在生日之前,年龄减一
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                //当前月份在生日之前,年龄减一
                age--;
            }
        } return age;
    }
}

3.6 Repository

package com.example.jpa_study.repository;

import com.example.jpa_study.repository.entity.Student;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface StudentRepository extends JpaRepository<Student,String> {
    /**
     * 多条件模糊查询
     *
     * @param spec
     * @param pageable
     * @return
     */
    Page<Student> findAll(Specification<Student> spec, Pageable pageable);
}

3.7 启动类

package com.example.jpa_study;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JpaStudyApplication {

    public static void main(String[] args) {
        SpringApplication.run(JpaStudyApplication.class, args);
    }

}

3.8 JPA生成的数据库表结构

3.9 数据表中的现有数据

3.10 postman测试(添加和查询)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值