springData JPA 的web搭建

我爱海鲸 2024-12-06 19:03:43 暂无标签

简介jpa、hibernate、springboot、日期范围查询、时间校验

1、全局pom文件:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>xyz.haijin</groupId>
    <artifactId>springDataTest</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>jpa_hibernate_01</module>
        <module>springdata_jpa_02</module>
        <module>springdata_jpa_03</module>
        <module>springdata_jpa_web</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <querydsl.version>4.4.0</querydsl.version>
        <apt.version>1.1.3</apt.version>
        <mysql.version>8.0.29</mysql.version>
    </properties>


    <!--统一管理SpringData子项目的版本-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-bom</artifactId>
                <version>2021.1.0</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>



</project>

2、项目pom文件:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springdata_jpa_web</artifactId>

    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!--data-jpa的场景启动器-->
        <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.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

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

</project>

3、Customer:

package xyz.haijin.po;

import javax.persistence.*;

@Entity     // 作为hibernate 实体类
@Table(name = "tb_customer")       // 映射的表明
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long custId; //客户的主键

    @Column(name = "cust_name")
    private String custName;//客户名称

    @Column(name="cust_address")
    private String custAddress;//客户地址

    public Long getCustId() {
        return custId;
    }

    public void setCustId(Long custId) {
        this.custId = custId;
    }

    public String getCustName() {
        return custName;
    }

    public void setCustName(String custName) {
        this.custName = custName;
    }

    public String getCustAddress() {
        return custAddress;
    }

    public void setCustAddress(String custAddress) {
        this.custAddress = custAddress;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "custId=" + custId +
                ", custName='" + custName + '\'' +
                ", custAddress='" + custAddress + '\'' +
                "}\n";
    }
}

4、CustomerRepository:

package xyz.haijin.repositories;


import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Component;
import xyz.haijin.po.Customer;


@Component
public interface CustomerRepository extends PagingAndSortingRepository<Customer,Long>{

}

5、CustomerService:

package xyz.haijin.service;


import xyz.haijin.po.Customer;

public interface CustomerService {
    Iterable<Customer> getAll();
}

6、CustomerServiceImple:

package xyz.haijin.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xyz.haijin.po.Customer;
import xyz.haijin.repositories.CustomerRepository;

@Service
public class CustomerServiceImple implements  CustomerService{

    @Autowired
    CustomerRepository repository;

    @Override
    public Iterable<Customer> getAll() {
        return repository.findAll();
    }
}

7、Application:

package xyz.haijin;

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

@SpringBootApplication
public class Application {

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

}

8、CustomerController:

package xyz.haijin;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import xyz.haijin.po.Customer;
import xyz.haijin.service.CustomerService;

@RestController
public class CustomerController {

    @Autowired
    CustomerService customerService;

    @RequestMapping("/customer/all")
    public Iterable<Customer> getAll(){
        return customerService.getAll();
    }
}

9、application.properties:

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://192.168.3.10:3306/springdata_jpa?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=haijinmysql
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql= true 
spring.jpa.properties.hibernate.format_sql=true
server.port=8088

10、访问:http://localhost:8088/customer/all

2024-11-05 start:

SpringData JPA进阶查询—JPQL/原生SQL查询、分页处理、部分字段映射查询 - 星朝 - 博客园

增删改查(分页):

实体类:

@Data
@Entity
@NoArgsConstructor
@Table(name = "test")
public class Testimplements Serializable {

    /**
     * id(不是自增的)
     */
    @Id
    private String id;

    /**
     * 电话号码
     */
    private String telMuber;

    /**
     * 状态 1 可用 0 不可用
     */
    @Column(nullable = false)
    private Integer status;

    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;

    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    private Date updateTime;

    @CreatedBy
    private String createPerson;

    @CreatedBy
    private String updatePerson;

    @PrePersist
    protected void onCreate() {
        // 保存时调用  设置一些逻辑

    }

    @PreUpdate
    protected void onUpdate() {
        // 修改时调用  设置一些逻辑
    }

}

时间查询参数:

@Data
public class TestPageParaVo {

    /**
     * 开始时间
     */
    @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$", message = "startTime的格式为 yyyy-MM-dd HH:mm:ss")  // String类型才生效
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
    private Date startTime;

    /**
     * 结束时间
     */
    @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$", message = "endTime的格式为 yyyy-MM-dd HH:mm:ss")  // String类型才生效
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
    private Date endTime;

}

转化日期

{
    "startTime":"2020-12-19",
    "endTime":"2020-12-30"
}

业务操作:

@Service
@Slf4j
@AllArgsConstructor
public class TestService {


    // 解决线程安全的问题
    @PersistenceContext
    private EntityManager em;

    @Resource
    private TestRepository testRepository;


    /**
     * 分页
     * @param para 入参
     * @param pageable 分页参数
     * @return ignore
     */
    @Transactional(readOnly = true)
    public Page<TestVo> userPage(OfficeImUserPageParaVo para, Pageable pageable) {

        // 构建查询的语句
        StringBuilder jpqlBuilder = new StringBuilder("SELECT NEW com.example.TestVo(【设置值】, COALESCE(table.status, 1)(为空时设置一个默认值1 ");
        StringBuilder jpqlBuilderCount = new StringBuilder("SELECT COUNT(DISTINCT table) ");

        String fromStr = "FROM Table table LEFT JOIN LeftTable lt on table.ltId = lt.id where u.isBoolean = false and u.log != '无'";
        jpqlBuilder.append(fromStr);
        jpqlBuilderCount.append(fromStr);

        // 查询的手机号
        String telNumber= para.get【手机号】
        if (StringUtils.isNotBlank(telNumber)) {
            String sqlStr = "AND lt.telNumber= :telNumber";
            jpqlBuilder.append(sqlStr);
            jpqlBuilderCount.append(sqlStr);
        }

boolean hasConditions = false;

// 没有where语句时
    if (orderDescription != null && !orderDescription.isEmpty()) {
                if (!hasConditions) {
                    jpqlBuilder.append("WHERE ");
                    countJpqlBuilder.append("WHERE ");
                    hasConditions = true;
                } else {
                    jpqlBuilder.append("AND ");
                    countJpqlBuilder.append("AND ");
                }
                jpqlBuilder.append("o.description LIKE :orderDescription ");
                countJpqlBuilder.append("o.description LIKE :orderDescription ");
                params.add(orderDescription + "%");
            }



     // 动态添加ORDER BY子句
        if (pageable.getSort().isSorted()) {
            jpqlBuilder.append("ORDER BY ");
            boolean isFirst = true;
            for (Sort.Order order : pageable.getSort()) {
                if ("id".equals(order.getProperty()) || "createTime".equals(order.getProperty())) {
                    if (!isFirst) {
                        jpqlBuilder.append(", ");
                    }
                    // 排序的字段需要是id或者questionTime
                    if ("id".equals(order.getProperty()) || "questionTime".equals(order.getProperty())) {
                        jpqlBuilder.append("o.").append(order.getProperty()).append(" ").append(order.getDirection().name());
                    }
                    isFirst = false;
                }
            }
        }

        String jpql = jpqlBuilder.toString();
        String countJpql = jpqlBuilderCount.toString();
       // Query query = em.createQuery(jpql, TestVo.class);
       TypedQuery<TestPo> query = em.createQuery(jpql, TestPo.class);
        //Query countQuery = em.createQuery(countJpql, Long.class);
       TypedQuery<Long> countQuery = em.createQuery(jpql, Long.class);

        if (StringUtils.isNotBlank(telNumber)) {
            query.setParameter("telNumber",telNumber);
            countQuery.setParameter("telNumber",telNumber);
        }


        // 设置分页参数
        query.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
        query.setMaxResults(pageable.getPageSize());

        // 获取分页结果
        List<TestVo> content = query.getResultList();

        // 获取总记录数
        long totalElements = (long) countQuery.getSingleResult();

        // 创建Page对象,总记录数设为-1表示未知
        Page<TestVo> page = new PageImpl<>(content, pageable, totalElements);


        return page;
    }

    /**
     * 修改(保存)方法
     */
    public void update(TestVo para) {
        Optional<TestPo> testPo = testRepository.findById(【id】);
        if (testPo .isEmpty()) {
            // 抛异常  内容不存在
        }
        TestPo test= new TestPo();
        // TODO 设置值

        // 修改配置
        testRepository.save(test);

    }

    /**
     * 删除
     */
    public void delete(TestVo para) {
       TestPo test= new TestPo();
        TestPo.setId(【id】);
        testRepository.delete(test);
    }
}

分页请求的接口:localhost:8080/test/page?page=1&size=5&sort=createTime,desc

end

你好:我的2025