Spring JPA起航

從一個helloworld開始java

創建好springboot的項目後mysql

pom.xmlweb

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<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.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <optional>true</optional>
</dependency>
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.47</version>
</dependency>
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid</artifactId>
   <version>1.0.29</version>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>8.0.11</version>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
</dependency>

配置文件spring

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/jpa?useSSL=FALSE&serverTimezone=GMT%2B8
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
    filters: stat
    maxActive: 20
    initialSize: 1
    maxWait: 60000
    minIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 'x'
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    maxOpenPreparedStatements: 20
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

實體類sql

@Entity
@Data
@RequiredArgsConstructor
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NonNull
    private String name;
    @NonNull
    private String email;
}

倉庫文件數據庫

public interface UserRepository extends CrudRepository<User,Long> {
}

controllerjson

@RestController
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @SuppressWarnings("unchecked")
    @Transactional
    @GetMapping("/add")
    public Result<String> addNewUser(@RequestParam("name") String name,@RequestParam("email") String email) {
        User user = new User(name,email);
        userRepository.save(user);
        return Result.success("添加用戶成功");
    }

    @GetMapping("/all")
    @SuppressWarnings("unchecked")
    public Result<Iterable<User>> getAllUsers() {
        return Result.success(userRepository.findAll());
    }

    @GetMapping("/user")
    @SuppressWarnings("unchecked")
    public Result<User> getUser(@RequestParam("id") Long id) {
        return Result.success(userRepository.findById(id));
    }
}

也能夠直接用名字查詢springboot

public interface UserAloneRepository extends Repository<User,Long> {
    List<User> findByName(String name);
}

在UserController中添加app

@Autowired
private UserAloneRepository userAloneRepository;
@GetMapping("/user/name")
@SuppressWarnings("unchecked")
public Result<User> getUserByName(@RequestParam("name") String name) {
    return Result.success(userAloneRepository.findByName(name));
}

jpa的一個好處是能夠不用手工去數據庫建表,一運行就能夠自動建表。spring-boot

若是要分頁和排序

public interface UserPagingAndSortingRepository extends PagingAndSortingRepository<User,Long> {
}

Controller中添加

/**
 * 分頁和排序
 * @return
 */
@SuppressWarnings("unchecked")
@GetMapping("/page")
public Result<Page<User>> getAllUserByPage() {
    return Result.success(userPagingAndSortingRepository.findAll(
            new PageRequest(0,2,new Sort(new Sort.Order(Sort.Direction.ASC,"name")))
    ));
}

/**
 * 排序
 * @return
 */
@SuppressWarnings("unchecked")
@GetMapping("/sort")
public Result<Iterable<User>> getAllUserWithSort() {
    return Result.success(userPagingAndSortingRepository.findAll(
            new Sort(new Sort.Order(Sort.Direction.ASC,"name"))
    ));
}

咱們來看一下他的整體繼承關係結構圖

其中SimpleJpaRepository是他們全部接口的實現類,而JpaRepository以上其實都是兼容noSql的接口,而只有JpaRepository如下才是對數據庫特有的接口。

而使用的方法也是同樣,只須要用一個自定義接口繼承便可

public interface UserJpaRespository extends JpaRepository<User,Long> {
}

jpa有本身的根據方法名的查詢生成器機制,例如以前的UserAloneRepository中的findByName,findBy是固定前綴,Name是屬性名。咱們來看幾個and、or的查詢。

public interface UserAloneRepository extends Repository<User,Long> {
    List<User> findByName(String name);
    List<User> findByNameAndEmail(String name,String email);
    List<User> findByNameOrEmail(String name,String email);
}

Controller中的

@SuppressWarnings("unchecked")
@GetMapping("/and")
public Result<List<User>> getUserByNameAndEmail(@RequestParam("name") String name,@RequestParam("email") String email) {
    return Result.success(userAloneRepository.findByNameAndEmail(name,email));
}

@SuppressWarnings("unchecked")
@GetMapping("/or")
public Result<List<User>> getUserByNameOrEmail(@RequestParam("name") String name,@RequestParam("email") String email) {
    return Result.success(userAloneRepository.findByNameOrEmail(name,email));
}

咱們從打印出來的日誌能夠看到

Hibernate: select user0_.id as id1_0_, user0_.email as email2_0_, user0_.name as name3_0_ from user user0_ where user0_.name=? and user0_.email=?
Hibernate: select user0_.id as id1_0_, user0_.email as email2_0_, user0_.name as name3_0_ from user user0_ where user0_.name=? or user0_.email=?

其實就是where語句後面的and和or.

這種and以及or是能夠無限接下去的多條件查詢。如今咱們來看一下去重和取前幾個數據

public interface UserAloneRepository extends Repository<User,Long> {
    List<User> findByName(String name);
    List<User> findByNameAndEmail(String name,String email);
    List<User> findByNameOrEmail(String name,String email);
    //去重
    List<User> findDistinctByName(String name);
    //查找前2個
    List<User> findTop2ByName(String name);
}

只要加上Distinct和Top數字就能夠了

如今給User實體類增長兩個字段

@Entity
@Data
@RequiredArgsConstructor
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NonNull
    private String name;
    @NonNull
    private String email;
    private int age;
    private boolean sex;
}

啓動項目後,數據庫會自動給user表增長上該字段

全部的jpa關鍵字以下

public interface UserAloneRepository extends Repository<User,Long> {
    List<User> findByName(String name);
    List<User> findByNameAndEmail(String name,String email);
    List<User> findByNameOrEmail(String name,String email);
    //去重
    List<User> findDistinctByName(String name);
    //查找前2個
    List<User> findTop2ByName(String name);
    //查找小於age參數的
    List<User> findByAgeBefore(int age);
    //查找小於age參數的
    List<User> findByAgeLessThan(int age);
    //查找小於等於age參數的
    List<User> findByAgeLessThanEqual(int age);
    //查找大於age參數的
    List<User> findByAgeAfter(int age);
    //查找大於age參數的
    List<User> findByAgeGreaterThan(int age);
    //查找大於等於age參數的
    List<User> findByAgeGreaterThanEqual(int age);
    //查找name爲null的
    List<User> findByNameIsNull();
    //查找name不爲null的
    List<User> findByNameNotNull();
    //查找like name的(此處不帶%)
    List<User> findByNameLike(String name);
    //查找not like name的(此處不帶%)
    List<User> findByNameNotLike(String name);
    //查找like %name(無後綴%)
    List<User> findByNameStartingWith(String name);
    //查找like name%(無前綴%)
    List<User> findByNameEndingWith(String name);
    //查找like %name%
    List<User> findByNameContaining(String name);
    //根據name查找,按照age排序
    List<User> findByNameOrderByAgeDesc(String name);
    //查找不等於age的
    List<User> findByAgeNot(int age);
    //根據age查找在ages集合內的
    List<User> findByAgeIn(Set<Integer> ages);
    //根據age查找不在ages集合內的
    List<User> findByAgeNotIn(Set<Integer> ages);
    //查找sex爲1的
    List<User> findBySexTrue();
    //查找sex爲0的
    List<User> findBySexFalse();
    //按照email查找,不區分大小寫
    List<User> findByEmailIgnoreCase(String email);
    //按照name查找總數
    long countByName(String name);
    //按照name刪除
    //此處是根據查找出來的id一條一條刪除的,因此在調用的時候必須加事務
    long deleteByName(String name);
    //按照name刪除
    //此處是根據查找出來的id一條一條刪除的,因此在調用的時候必須加事務
    List<User> removeByName(String name);
}

在刪除時必須帶上事務

@Transactional
@SuppressWarnings("unchecked")
@GetMapping("/delete")
public Result<String> deleteByName(@RequestParam("name") String name) {
    userAloneRepository.deleteByName(name);
    return Result.success("刪除成功");
}

@Transactional
@SuppressWarnings("unchecked")
@GetMapping("/remove")
public Result<List<User>> removeByName(@RequestParam("name") String name) {
    return Result.success(userAloneRepository.removeByName(name));
}

根據打印的日誌能夠看到實際上是按照id來刪除的

Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.email as email3_0_, user0_.name as name4_0_, user0_.sex as sex5_0_ from user user0_ where user0_.name=? Hibernate: delete from user where id=? Hibernate: delete from user where id=?

相關文章
相關標籤/搜索