SpringBoot 学习笔记_整合持久层——Spring Boot JPA

SpringBoot 学习笔记_整合持久层——Spring Boot JPA

声明:

本次学习参考 《SpringBoot + Vue 开发实战》 · 王松(著) 一书。

本文的目的是记录我学习的过程和遇到的一些问题以及解决办法,其内容主要来源于原书。

如有侵权,请联系我删除

SpringBoot 整合持久层开发

整合 Spring Boot JPA

JPA 是一种 ORM 规范。 Spring DataSpring 的一个子项目,致力于简化数据的访问,通过规范的方法名称来分析开发者的意图,进而减少数据库访问层的代码。

  • 创建数据库(表会根据实体类自动创建)

  • 创建 SpringBoot 项目,添加依赖

    <!-- 添加 Spring Boot 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>com.alibaba</groupId>
    	<artifactId>druid</artifactId>
    	<version>1.1.9</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    
  • 数据库配置(application.properties)

    ### 数据库基本配置 ###
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    #spring.datasource.url=jdbc:mysql:///chapter05?serverTimezone=GMT
    spring.datasource.url=jdbc:mysql://localhost:3306/chapter05?serverTimezone=GMT
    spring.datasource.username=root
    spring.datasource.password=root
    #### 数据库配置 —— JPA 相关 ####
    # 表示是否在控制台打印 JPA 打印过程生成的 SQL
    spring.jpa.show-sql=true
    # 表示 JPA 对应的数据库是 MySQL
    spring.jpa.database=mysql
    # 表示在项目启动时根据实体类更新数据库中的表(可选:create、create-drop、validate、no)
    spring.jpa.hibernate.ddl-auto=update
    # 表示使用的数据库方言是 MySQL57Dialect
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
    
  • 创建实体类

    // @Entity 表示该类是一个实体类。在项目启动时会根据该类自动生成一个数据表,表名称即 @Entity 的 name 值,如果不配置,默认为类名。
    @Entity(name = "t_book")
    public class BookJPA {
        // @Id 表示该实体类的主键。所有实体类都要有主键
        @Id
        // @GeneratedValue 表示主键自动生成,strategy 表示生成策略
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;
    
        // @Column 表示表中字段名称和实体类中属性名称的映射。如果不配置,默认生成字段名就是属性名。nullable 表示是否可为空
        @Column(name = "book_name", nullable = false)
        private String name;
    
        private String author;
        private Float price;
    
        // @Transient 表示生成数据表时,忽略该字段
        @Transient
        private String description;
    }
    
  • 创建数据库访问层

    /**
     * 整合 JPA 的 BookDao
     *
     * 自定义 Dao 继承 JpaRepository。JpaRepository 中提供了一些基本的数据操作方法,有增删改查、分页查询、排序查询等。
     */
    public interface BookJPADao extends JpaRepository<BookJPA, Integer> {
    
        //Spring Data JPA 支持既定规范命名查询(方法名复合既定规范,自动生成对应 SQL)
    
        /**
         *     keyWords             示例                                对应 SQL
         *     And                  findByNameAndAge                    where name=? and age=?
         *     Or                   findByNameOrAge                     where name=? or age=?
         *     Is/Equals            findByAgeIs/findByAgeEquals         where age=?
         *     Between              findByAgeBetween                    where age between ? and ?
         *     LessThan/Before      findByAgeLessThan/findByAgeBefore   where age < ?
         *     LessThanEquals       findByAgeLessThanEquals             where age <= ?
         *     GreaterThan/After    findByAgeGreaterThan/findByAgeAfter where age > ?
         *     GreaterThanEquals    findByAgeGreaterThanEquals          where age >= ?
         *     IsNull               findByNameIsNull                    where name is null
         *     IsNotNull/NotNull    findByNameNotNull                   where name is not null
         *     Not                  findByNameNot                       where name <> ?
         *     In                   findByAgeIn                         where age in(?)
         *     NotIn                findByAgeNotIn                      where age not in(?)
         *     NotLike              findByNameNotLike                   where name not like ?
         *     StartingWith         findByNameStartingWith              where name like '?%'
         *     EndingWith           findByNameEndingWith                where name like '%?'
         *     Containing/Contains  findByNameContains                  where name like '%?%'
         *     True                 findByEnabledTrue                   where enabled = true
         *     False                findByEnabledFalse                  where enabled = false
         *     IgnoreCase           findByNameIgnoreCase                where UPPER(name)=UPPER(?)
         *
         *     OrderBy              findByAgeGreaterThanOrderByIdDesc   where age > ? order by id desc
         */
    
        // 查询作者名以某字符开头的所有书
        List<BookJPA> getBooksByAuthorStartingWith(String author);
        // 查询价格大于某值得所有书
        List<BookJPA> getBooksByPriceGreaterThan(Float price);
    
        // Spring Data JPA 支持原生 SQL。 nativeQuery = true 表示使用原生 SQL 语句
        @Query(value = "select * from t_book where id=(select max(id) from t_book)", nativeQuery = true)
        BookJPA getMaxIdBook();
    
        // Spring Data JPA 支持默认的 JPQL。JPQL 是一种可移植的面向对象表达式语言。
        // 通过类名和属性(并非数据库列名)来进行参数绑定。参数需要使用 @Param 绑定。
        @Query("select b from t_book b where b.id > :id and b.author=:author")
        List<BookJPA> getBookByIdAndAuthor(@Param("author") String author, @Param("id") Integer id);
    
        // Spring Data JPA 支持默认的 JPQL。
        // 通过占位符进行参数传递。参数顺序有严格要求。
        @Query("select b from t_book b where b.id < ?2 and b.name like %?1%")
        List<BookJPA> getBooksByIdAndNameAnd(String name, Integer id);
    
        // 如果方法涉及修改操作,需要添加 @Modifying 注解并添加事务
    }
    
  • 创建 Service 和 Controller

    /**
     *  整合 Spring Data JPA 的 Service 层
     */
    @Service
    public class BookJPAService {
        @Autowired
        BookJPADao bookDao;
    
        public void addBook(BookJPA book){
            bookDao.save(book);
        }
    
        public Page<BookJPA> getBookByPage(Pageable pageable){
            return bookDao.findAll(pageable);
        }
    
        public List<BookJPA> getBooksByAuthorStartingWith(String author){
            return bookDao.getBooksByAuthorStartingWith(author);
        }
    
        public List<BookJPA> getBooksByPriceGreaterThan(Float price){
            return bookDao.getBooksByPriceGreaterThan(price);
        }
    
        public BookJPA getMaxIdBook(){
            return bookDao.getMaxIdBook();
        }
    
        public List<BookJPA> getBookByIdAuthor(String author, Integer id){
            return bookDao.getBookByIdAndAuthor(author, id);
        }
    
        public List<BookJPA> getBooksByIdAndName(String name, Integer id){
            return bookDao.getBooksByIdAndName(name, id);
        }
    }
    
    /**
     * 整个 Spring Data JPA 的 Controller 层
     */
    
    @RestController
    public class BookJPAController {
        @Autowired
        BookJPAService bookService;
    
        @GetMapping("/jpa/findAll")
        public void findAll(){
            PageRequest pageable = PageRequest.of(2, 3);
            Page<BookJPA> page = bookService.getBookByPage(pageable);
    
            System.out.println(" 总页数: " + page.getTotalPages());
            System.out.println(" 总记录: " + page.getTotalElements());
            System.out.println(" 查询结果: " + page.getContent());
            System.out.println(" 当前页数: " + page.getNumber() + 1);
            System.out.println(" 当前页记录数: " + page.getNumberOfElements());
            System.out.println(" 每页记录数: " + page.getSize());
        }
    
        @GetMapping("/jpa/search")
        public void search(){
            List<BookJPA> bs1 = bookService.getBookByIdAndAuthor("吴承恩", 1);
            List<BookJPA> bs2 = bookService.getBooksByAuthorStartingWith("施");
            List<BookJPA> bs3 = bookService.getBooksByPriceGreaterThan(0.1F);
            BookJPA book = bookService.getMaxIdBook();
    
            System.out.println(bs1);
            System.out.println(bs2);
            System.out.println(bs3);
            System.out.println(book);
        }
    
        @GetMapping("/jpa/save")
        public void save(){
            BookJPA book = new BookJPA();
            book.setAuthor("卧龙");
            book.setName("卧龙锅巴");
            book.setPrice(3.5F);
    
            bookService.addBook(book);
        }
    }
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章