zoukankan      html  css  js  c++  java
  • spring boot2 整合(二)JPA(特别完整!)

    JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

    JPA 的目标之一是制定一个可以由很多供应商实现的API,并且开发人员可以编码来实现该API,而不是使用私有供应商特有的API。

    JPA是需要Provider来实现其功能的,Hibernate就是JPA Provider中很强的一个,应该说无人能出其右。从功能上来说,JPA就是Hibernate功能的一个子集。

    本教程大概流程:

    1. 借助idea实现springboot 和 spring data jpa 整合
    2. 实现JpaRepository接口快捷开发
    3. 自定义Mapper查询接口方法
    4. MVC架构+分页功能实战
    5. QueryDSL工具与之的整合

    首先我的开发环境:
    jdk1.8+maven3+IDEA

    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>springboot-jpa</groupId>
        <artifactId>springboot-jpa</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>springboot-jpa</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.0.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.16.18</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-test</artifactId>
                <version>1.4.5.RELEASE</version>
                <scope>test</scope>
            </dependency>
            <!--querydsl依赖-->
            <dependency>
                <groupId>com.querydsl</groupId>
                <artifactId>querydsl-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>com.querydsl</groupId>
                <artifactId>querydsl-apt</artifactId>
                <scope>provided</scope>
            </dependency>
            <!--阿里巴巴数据库连接池,专为监控而生 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.0.26</version>
            </dependency>
            <!-- 阿里巴巴fastjson,解析json视图 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.15</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.3</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <!--添加QueryDSL插件支持-->
                <plugin>
                    <groupId>com.mysema.maven</groupId>
                    <artifactId>apt-maven-plugin</artifactId>
                    <version>1.1.3</version>
                    <executions>
                        <execution>
                            <configuration>
                                <outputDirectory>target/generated-sources/java</outputDirectory>
                                <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
    
    </project>
    
    

    2. 完善application.properties 文件

    spring.datasource.url=jdbc:mysql://localhost:3306/user
    spring.datasource.username=root
    spring.datasource.password=root
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.type: com.alibaba.druid.pool.DruidDataSource
    spring.datasource.filters:stat
    spring.datasource.maxActive: 20
    spring.datasource.initialSize: 1
    spring.datasource.maxWait: 60000
    spring.datasource.minIdle: 1
    spring.datasource.timeBetweenEvictionRunsMillis: 60000
    spring.datasource.minEvictableIdleTimeMillis: 300000
    spring.datasource.validationQuery: select 'x'
    spring.datasource.testWhileIdle: true
    spring.datasource.testOnBorrow: false
    spring.datasource.testOnReturn: false
    spring.datasource.poolPreparedStatements: true
    spring.datasource.maxOpenPreparedStatements: 20
    
    
    spring.jpa.properties.hibernate.hbm2ddl.auto=update
    spring.jpa.show-sql=true
    

    3. 编写实体类 User.java

    package com.fantj.model;
    
    
    import lombok.Data;
    
    import javax.persistence.*;
    import java.util.Date;
    
    @Data
    @Entity
    @Table(name = "user")
    public class User {
        public User(){
        }
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Integer id;
    
        @Column(nullable = false)
        private String username;
        @Column(nullable = false)
        private Date birthday;
        @Column(nullable = false)
        private String sex;
        @Column(nullable = false)
        private String address;
    }
    

    @Data注解是 lombok 依赖包下的注解,它可以自动帮我们生成set/getter方法,简化代码量。有兴趣的可以详细了解,这里不做多解释。

    4. 实现DAO层

    package com.fantj.repostory;
    
    /**
     * Created by Fant.J.
     */
    @Repository
    public interface UserRepository extends JpaRepository<User, Integer> {
    
        //自定义repository。手写sql
        @Query(value = "update user set name=?1 where id=?4",nativeQuery = true)   //占位符传值形式
        @Modifying
        int updateById(String name,int id);
    
        @Query("from User u where u.username=:username")   //SPEL表达式
        User findUser(@Param("username") String username);// 参数username 映射到数据库字段username
    }
    
    

    注意:只有@Query 的注解下不能使用insert,我们需要在上面再添加个@Modify注解,我习惯都加,nativeQuery 是询问是否使用原生sql语句。多表查询也是在这里手写sql,不做演示。因为后面我们用更好的支持多表查询的工具框架 QueryDSL来帮助我们更简洁的实现它。

    5.实现Service层

    UserService .java

    package com.fantj.service;
    
    /**
     * Created by Fant.J.
     */
    public interface UserService {
        /** 删除 */
        public void delete(int id);
        /** 增加*/
        public void insert(User user);
        /** 更新*/
        public int update(User user);
        /** 查询单个*/
        public User selectById(int id);
        /** 查询全部列表*/
        public Iterator<User> selectAll(int pageNum, int pageSize);
    }
    
    

    UserServiceImpl.java

    package com.fantj.service.impl;
    
    
    /**
     * Created by Fant.J.
     */
    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserRepository userRepository;
    
        /**
         * 删除
         *
         * @param id
         */
        @Override
        public void delete(int id) {
            userRepository.deleteById(id);
        }
    
        /**
         * 增加
         *
         * @param user
         */
        @Override
        public void insert(User user) {
            userRepository.save(user);
        }
    
        /**
         * 更新
         *
         * @param user
         */
        @Override
        public int update(User user) {
            userRepository.save(user);
            return 1;
        }
    
        /**
         * 查询单个
         *
         * @param id
         */
        @Override
        public User selectById(int id) {
            Optional<User> optional = userRepository.findById(id);
            User user = optional.get();
            return user;
        }
    
        /**
         * 查询全部列表,并做分页
         *  @param pageNum 开始页数
         * @param pageSize 每页显示的数据条数
         */
        @Override
        public Iterator<User> selectAll(int pageNum, int pageSize) {
            //将参数传给这个方法就可以实现物理分页了,非常简单。
            Sort sort = new Sort(Sort.Direction.DESC, "id");
            Pageable pageable = new PageRequest(pageNum, pageSize, sort);
            Page<User> users = userRepository.findAll(pageable);
            Iterator<User> userIterator =  users.iterator();
            return  userIterator;
        }
    }
    
    

    分页不止可以这样做,也可以在Controller层进行实例化和初始化然后将Pageable对象传给Service。
    当然也可以对分页进行封装,封装后的展示。

        Page<User> datas = userRepository.findAll(PageableTools.basicPage(1, 5, new SortDto("id")));
    

    是不是很简洁。大家可以自己尝试一下。

    6. 实现Controller
    package com.fantj.controller;
    
    /**
     * Created by Fant.J.
     */
    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @RequestMapping(method = RequestMethod.GET,value = "/delete/{id}")
        public void delete(@PathVariable("id")int id){
            userService.delete(id);
        }
    
        @RequestMapping(method = RequestMethod.POST,value = "/insert")
        public void insert(User user){
            userService.insert(user);
        }
        @RequestMapping(method = RequestMethod.POST,value = "/update/{id}")
        public void update(@RequestParam User user){
            userService.update(user);
        }
    
        @RequestMapping(method = RequestMethod.GET,value = "/{id}/select")
        public User select(@PathVariable("id")int id){
            return userService.selectById(id);
        }
    
        @RequestMapping(method = RequestMethod.GET,value = "/selectAll/{pageNum}/{pageSize}")
        public List<User> selectAll(@PathVariable("pageNum") int pageNum, @PathVariable("pageSize") int pageSize){
            Iterator<User> userIterator = userService.selectAll(pageNum, pageSize);
            List<User> list = new ArrayList<>();
            while(userIterator.hasNext()){
                list.add(userIterator.next());
            }
            return list;
        }
    
    }
    
    
     
     

    QueryDSL工具与上文的整合

    可以参考恒宇少年的四篇文章:

    注意一点,目前springboot2.0 版本对JPA支持有误,如果你用springboot2 来配置querydsl,application启动类会运行不起来,正确的依赖包或者是配置类我还没有找到,希望有点子的朋友可以和我联系。 本人QQ:844072586



    作者:FantJ
    链接:https://www.jianshu.com/p/3b31270a44b1
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

  • 相关阅读:
    C# 设计模式(3)工厂方法模式
    C# 设计模式(2)简单工厂模式
    C# .Net Core读取AppSettings
    C# 设计模式(1)单例模式
    C# MarshalByRefObject
    使用64位TestStand调用32位LabVIEW代码模块
    LIN 总线入门
    C#版本与.NET版本对应关系以及各版本的特性
    数字货币提醒小工具
    C#根据描述获取枚举
  • 原文地址:https://www.cnblogs.com/telwanggs/p/10779839.html
Copyright © 2011-2022 走看看