在使用了许久的MyBatis后,了解到了Spring Data JPA,那家伙,这玩意也挺强大,某种程度上比MyBatis还好用,这不,我在使用的时候就发现了一个神奇的地方,我们可以通过自定义的方法名就可以让JPA自动解析出相应的SQL语句,具体这背后是怎么完成的,我还不咋了解,后续了解了肯定回合大家分享的。废话不多说,直接看代码。
- 首先创建一张Customer表,表的具体结构如下:
- 首先创建一个Spring Boot项目(方便),我用的版本是2.1.8.RELEASE。
- 创建一个映射到数据库的实体类,代码如下:
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 + '\'' + '}'; } }
- 再创建一个继承于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(); }
- 直接上测试类里面去跑一下。
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); } } }
- 控制台打印了sql信息。
- 卧槽,我一句sql没写,咋出来的sql语句啊?这就是JPA的强大了。
- 在JPA中有一个类名解析器,所以将类名按照一定规则进行命名,就可以解析出你想要的SQL语句。具体规则如下(重点啊。。。。。。。。):
-
- 在JPA中有一个类名解析器,所以将类名按照一定规则进行命名,就可以解析出你想要的SQL语句。具体规则如下(重点啊。。。。。。。。):
- 我们用一个我代码中的一个例子实际的讲解一下。在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