在使用了许久的MyBatis后,了解到了Spring Data JPA,那家伙,这玩意也挺强大,某种程度上比MyBatis还好用,这不,我在使用的时候就发现了一个神奇的地方,我们可以通过自定义的方法名就可以让JPA自动解析出相应的SQL语句,具体这背后是怎么完成的,我还不咋了解,后续了解了肯定回合大家分享的。废话不多说,直接看代码。

  1. 首先创建一张Customer表,表的具体结构如下:
  2. 首先创建一个Spring Boot项目(方便),我用的版本是2.1.8.RELEASE。
  3. 创建一个映射到数据库的实体类,代码如下:
    package com.hk.springdatajpa.entity;
    
    import javax.persistence.*;
    
    /**
     * 客户的实体类
     * @author by 何坤
     * @Classname Customer
     * @Description TODO
     * @Date 2019/9/23 15:59
     */
    @Entity
    @Table(name = "cst_customer")
    public class Customer {
        /**
         * 自增主键
         */
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "cust_id", nullable = false, length = 32)
        private Long id;
        /**
         * 客户的姓名
         */
        @Column(name = "cust_name", nullable = true, length = 32)
        private String name;
        /**
         * 客户信息的来源
         */
        @Column(name = "cust_source", nullable = true, length = 32)
        private String source;
        /**
         * 客户所属的行业
         */
        @Column(name = "cust_industry", nullable = true, length = 32)
        private String industry;
        /**
         * 客户的级别
         */
        @Column(name = "cust_level", nullable = true, length = 32)
        private String level;
        /**
         * 客户的联系地址
         */
        @Column(name = "cust_address", nullable = true, length = 128)
        private String address;
        /**
         * 客户的手机号码
         */
        @Column(name = "cust_phone", nullable = true, length = 64)
        private String phone;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSource() {
            return source;
        }
    
        public void setSource(String source) {
            this.source = source;
        }
    
        public String getIndustry() {
            return industry;
        }
    
        public void setIndustry(String industry) {
            this.industry = industry;
        }
    
        public String getLevel() {
            return level;
        }
    
        public void setLevel(String level) {
            this.level = level;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        @Override
        public String toString() {
            return "Customer{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", source='" + source + '\'' +
                    ", industry='" + industry + '\'' +
                    ", level='" + level + '\'' +
                    ", address='" + address + '\'' +
                    ", phone='" + phone + '\'' +
                    '}';
        }
    }
  4. 再创建一个继承于CrudRepository接口的CustomerRepository接口,声明表对应的java类以及主键的数据类型(java类中的);
    package com.hk.springdatajpa.dao;
    
    import com.hk.springdatajpa.entity.Customer;
    import org.springframework.data.repository.CrudRepository;
    
    import java.util.List;
    
    /**
     * @author by 何坤
     * @Classname CustomerRepository
     * @Description TODO
     * @Date 2019/9/24 9:08
     */
    public interface CustomerRepository extends CrudRepository<Customer, Long> {
        /**
         * 根据用户的地址进行查询
         * @param address
         * @return java.util.List<com.hk.springdatajpa.entity.Customer>
         * @date 2019/9/24 16:02
         * @author 何坤
         */
        List<Customer> findByAddress(String address);
    
        /**
         * 将查询到的所有用户降序排列
         * @param
         * @return java.util.List<com.hk.springdatajpa.entity.Customer>
         * @date 2019/9/24 16:05
         * @author 何坤
         */
        List<Customer> findAllByOrderByIdDesc();
    
        /**
         * 将查询到的所有用户升序排列
         * @param
         * @return java.util.List<com.hk.springdatajpa.entity.Customer>
         * @date 2019/9/24 16:30
         * @author 何坤
         */
        List<Customer> findAllByOrderByIdAsc();
    }
    

  5. 直接上测试类里面去跑一下。
    package com.hk.springdatajpa;
    
    import com.hk.springdatajpa.dao.CustomerRepository;
    import com.hk.springdatajpa.entity.Customer;
    import com.hk.springdatajpa.service.CustomerService;
    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;
    import java.util.Optional;
    
    /**
     * @author by 何坤
     * @Classname JpaTest
     * @Description TODO
     * @Date 2019/9/24 12:53
     */
    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class JpaTest {
    
        @Autowired
        private CustomerRepository customerRepository;
    
        /**
         * 获取所有的用户信息并倒叙排列输出
         * @param
         * @return void
         * @date 2019/9/24 16:07
         * @author 何坤
         */
        @Test
        public void testFindAllByOrderByIdDesc(){
            List<Customer> customers = customerRepository.findAllByOrderByIdDesc();
            for (Customer customer : customers){
                System.out.println(customer);
            }
        }
    }

  6. 控制台打印了sql信息。

     

  7. 卧槽,我一句sql没写,咋出来的sql语句啊?这就是JPA的强大了。
    • 在JPA中有一个类名解析器,所以将类名按照一定规则进行命名,就可以解析出你想要的SQL语句。具体规则如下(重点啊。。。。。。。。):

  8. 我们用一个我代码中的一个例子实际的讲解一下。在CustomerRepository接口中的findAllByOrderByIdDesc()方法。
    • 首先findAll代表查询全部的信息。
    • By:条件查询,我们这里直接查询全部,所以没有条件。
    • 再OrderBy,进行排序。
    • 排序的条件为Id
    • 降序排序Desc
    • 所以最后的SQL语句就为:SELECT * FROM cust_customer ORDER BY cust_id DESC

 

最后, 我的目录结构如下:

 

 以及相关的配置(application.yml)如下:

server:
  port: 8000
---
spring:
  thymeleaf:
    cache: false
  datasource:
    username: root
    password: Hk123456?
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/jpa?serverTimezone=UTC
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
---
logging:
  level:
    com.hk.springdatajpa.mapper: debug