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的相关内容就先和大家探讨到这里,如果您与更好的见解,欢迎留言讨论。

  • 相关阅读:
    HDU 4539郑厂长系列故事――排兵布阵(状压DP)
    HDU 2196Computer(树形DP)
    HDU 4284Travel(状压DP)
    HDU 1520Anniversary party(树型DP)
    HDU 3920Clear All of Them I(状压DP)
    HDU 3853LOOPS(简单概率DP)
    UVA 11983 Weird Advertisement(线段树求矩形并的面积)
    POJ 2886Who Gets the Most Candies?(线段树)
    POJ 2828Buy Tickets
    HDU 1394Minimum Inversion Number(线段树)
  • 原文地址:https://www.cnblogs.com/AndroidJotting/p/8324854.html
Copyright © 2011-2022 走看看