zoukankan      html  css  js  c++  java
  • SpringBoot入坑-持久化操作

      前面内容中我们已经了解到了SpringBoot关于参数传递的相关知识,本篇我们一起来学习一下SpringBoot关于数据库持久化操作的知识,这里我们使用JPA进行数据库的持久化操作。

      首先由于我们需要进行数据库的操作,所以我们需要引入mysql的驱动包;这里我们介绍两种数据库持久化操作:JdbcTemplate和JpaRepository所以同样需要引入相应的包;这里为例方便进行数据的返回,我们引入阿里的fastjson:

    <!-- mysql数据库连接 start -->
            <!-- MYSQL -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!-- Spring Boot JDBC -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
            <!-- Spring Data JPA -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <!-- mysql数据库连接 end -->
    
            <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.44</version>
            </dependency>

      接下来我们需要配置properties文件:

    spring.datasource.url=jdbc:mysql://localhost:3306/girl
    spring.datasource.username=root
    spring.datasource.password=root
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    
    spring.jpa.show-sql:true
    spring.jpa.hibernate.ddl-auto:update

      这里设置数据库配置,当然我们也可以使用yml进行数据库连接配置。

      有了数据库连接,下面我们配置一下数据库表映射:

    @Entity
    @Table(name = "girl")
    public class Girl implements Serializable{
    
        private static final long serializableUID = 1L;
    
        @Id
        @GeneratedValue
        private Integer id;
        @Column(name = "name")
        private String name;
        @Column(name = "age")
        private Integer age;
        @Column(name = "birthday")
        private Date birthday;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    }

      对于注解的含义,大家如有不懂可以到度娘搜一下,这里不再赘述。

      配置好数据库映射,下面我们就可以进行持久化操作了,这里我们使用三层结构:action、service、dao,来实现持久化操作。这里我们首先使用JdbcTemplate进行持久化操作。

      编写我们的dao层业务逻辑:

    @Repository
    public class GirlDao {
    
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        public List<Girl> findGirls(){
            return jdbcTemplate.query("SELECT * FROM girl", new RowMapper<Girl>(){
                @Override
                public Girl mapRow(ResultSet resultSet, int i) throws SQLException {
                    Girl girl = new Girl();
                    girl.setId(resultSet.getInt("id"));
                    girl.setName(resultSet.getString("name"));
                    girl.setAge(resultSet.getInt("age"));
                    girl.setBirthday(resultSet.getDate("birthday"));
                    return girl;
                }
            });
        }
    
    }

      这里简单说一下注解 @Service用于标注业务层组件、@Controller用于标注控制层组件(如struts中的action)、@Repository用于标注数据访问组件,即DAO组件、@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

      下面编写我们的service层:

    @Service
    public class GirlService {
    
        @Autowired
        private GirlDao girlDao;
    
        public List<Girl> findGirls(){
            List<Girl> girls = girlDao.findGirls();
            return girls;
        }
    
    }

      通过@Autowired注解将Dao层注入

      最后是我们的控制层Action:

    @RestController
    public class GirlAction {
    
        @Autowired
        private GirlService girlService;
    
        @RequestMapping(value = "/findGirls", method = RequestMethod.GET)
        public String findGirls(){
            List<Girl> girls = girlService.findGirls();
            return JSON.toJSONString(girls);
        }
    
    }

      到这里我们的第一个例子就完工了,启动项目,输入http://localhost:8080/findGirls


       下面我们来看一下如何JpaRepository进行持久化操作,JPA是需要Provider来实现其功能的,Hibernate就是JPA Provider中很强的一个,应该说无人能出其右。从功能上来说,JPA就是Hibernate功能的一个子集。看到这里我想你大概已经猜到JPA的用法了。下面我们简单一起来使用一下。

      这里JpaRepository就类似与上面的Dao层,为了方便理解,这里我就将JpaRepository作为Dao层处理:

    public interface GirlDaoJpa extends JpaRepository<Girl, Integer> {
    
        List<Girl> getGirlsByName(final String name);
    
        @Query("select g from Girl g where g.name = ?1")
        List<Girl> findGirlsByName(String name);
    
    }

      你没有看错这里的JpaRepository是一个接口,我们不需要进行接口实现,这就是JpaRepository的便利之处。如何进行使用呢?

      编写我们的service层:

    @Service
    public class GirlServiceJpa {
    
        @Autowired
        private GirlDaoJpa girlDaoJpa;
    
        public Girl saveGirl(Girl girl){
            return  girlDaoJpa.save(girl);
        }
    
        public List<Girl> getGirlsByName(String name){
            return girlDaoJpa.getGirlsByName(name);
        }
    
        public List<Girl> findGirlsByName(String name){
            return girlDaoJpa.findGirlsByName(name);
        }
    
        public List<Girl> findGirls(){
            return girlDaoJpa.findAll();
        }
    
    }

      不知道你注意到没有,我并没有在接口中添加save、findAll方法,这是因为JpaRepository默认为我们提供了保存和查询方法。

      最后是我们的控制层逻辑:

    @RestController
    public class GirlJpaAction {
    
        @Autowired
        private GirlServiceJpa girlServiceJpa;
    
        @RequestMapping(value = "/saveGirlJAP", method = RequestMethod.POST)
        public String saveGirl(){
            Girl girl = new Girl();
            girl.setName("jap测试1");
            girl.setAge(26);
            girl.setBirthday(new Date());
            girl = girlServiceJpa.saveGirl(girl);
            if(null != girl && null != girl.getId()){
                return "添加成功";
            }else{
                return "添加失败";
            }
        }
    
        @RequestMapping(value = "/getGirlByNameJAP", method = RequestMethod.GET)
        public String getGirlByName(){
            List<Girl> girls = girlServiceJpa.getGirlsByName("abc");
            return JSON.toJSONString(girls);
        }
    
        @RequestMapping(value = "/findGirlByNameJAP", method = RequestMethod.GET)
        public String findGirlByName() {
            List<Girl> girls = girlServiceJpa.findGirlsByName("abc");
            return JSON.toJSONString(girls);
        }
    
        @RequestMapping(value = "/findGirlsJPA", method = RequestMethod.GET)
        public String findGirls(){
            List<Girl> girls = girlServiceJpa.findGirls();
            return JSON.toJSONString(girls);
        }
    }

       到这里我么关于JPA的简单实用介绍完毕,最后我再补充三点。

      1、@Query通过注解参数使用:

    @Query("select g from Girl g where g.name = :name")
    List<Girl> findGirlsByName(@Param("name") String name);

      2、原生sql使用:

    @Query(value = "select * from girl g where g.name like %:name%", nativeQuery = true)
    List<Girl> findGirlsByName(@Param("name") String name);

      注意红色字段,两者的区别之处。

      最后聊一下JPA分页查询:

    @Override
    Page<Girl> findAll(@PageableDefault(page = 1, size = 20, sort = {"id"}, direction = Sort.Direction.ASC) Pageable pageable);

      这里的@PageableDefault帮助我们个性化的设置pageable的默认配置。例如@PageableDefault(page = 1, size = 20, sort = { "id" }, direction = Sort.Direction.ASC)表示默认情况下我们按照id正序排列,每一页的大小为20,取第一页数据。

      Pageable是一个接口,这里我们需要编写一个接口实现:

    public class MyPageable implements Pageable {
        private int pageNumber;//当前请求分页
        private int pageSize;//页容量
        private Sort sort;//排序
    
        public void setPageNumber(int pageNumber) {
            this.pageNumber = pageNumber;
        }
    
        public void setPageSize(int pageSize) {
            this.pageSize = pageSize;
        }
    
        public void setSort(Sort sort) {
            this.sort = sort;
        }
    
        @Override
        public int getPageNumber() {
            return pageNumber;
        }
    
        @Override
        public int getPageSize() {
            return pageSize;
        }
    
        @Override
        public int getOffset() {
            return (pageNumber-1)*pageSize;
        }
    
        @Override
        public Sort getSort() {
            return sort;
        }
    
        @Override
        public Pageable next() {
            this.pageNumber = this.pageNumber+1;
            return this;
        }
    
        @Override
        public Pageable previousOrFirst() {
            this.pageNumber = 0 < this.pageNumber ? this.pageNumber-1 : 1;
            return this;
        }
    
        @Override
        public Pageable first() {
            this.pageNumber = 1;
            return this;
        }
    
        @Override
        public boolean hasPrevious() {
            return false;
        }
    }

      好了配置好分页持久层逻辑,下面就是我们的service层逻辑了:

    public List<Girl> findGirlsByPage(Integer stateIndex, Integer maxNum){
            MyPageable myPageable = new MyPageable();
            myPageable.setPageNumber(stateIndex);
            myPageable.setPageSize(maxNum);
            myPageable.setSort(new Sort(Sort.Direction.DESC, new String[]{"id"}));
            return girlDaoJpa.findAll(myPageable).getContent();
        }

      这里注意一个默认查询返回的是Page<Girl>,我们通过getContent可以得到我们的List数据。

      最后是我们的action层:

    @RequestMapping(value = "/findGirlsByPageJPA", method = RequestMethod.GET)
        public String findGirlsByPage(){
            List<Girl> girls = girlServiceJpa.findGirlsByPage(1, 5);
            return JSON.toJSONString(girls);
        }

       好了到这里关于SpringBoot的相关内容就先和大家探讨到这里,如果您与更好的见解,欢迎留言讨论。

  • 相关阅读:
    spring 任务调度quartz
    java增强型for循环
    DateTimeFormat
    Java的同步和异步
    HTTP Status 400,400 (Bad Request)
    com.mysql.jdbc.exceptions.jdbc4.MySQLDataException: '2.34435678977654336E17' in column '3' is outside valid range for the datatype INTEGER.
    Servlet.service() for servlet [appServlet] in context with path [/item] threw exception [Request processing failed
    mysql调优
    Windows nexus 启动失败
    NFS客户端访问行为相关的几个参数解释
  • 原文地址:https://www.cnblogs.com/AndroidJotting/p/8324854.html
Copyright © 2011-2022 走看看