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

原文地址:https://www.cnblogs.com/AndroidJotting/p/8324854.html

时间: 2024-10-07 18:49:33

SpringBoot入坑-持久化操作的相关文章

SpringBoot入坑-请求参数传递

前一篇我们探讨了关于springboot的配置文件和Controller的使用,本篇我们来一起探讨一下关于springboot如何传递参数的知识. 参数传递我们最常见的就是在url后通过?/&两个符号来将参数传递到后台,当然springboot也是也一样,我们可以通过这种方式将参数传递到后台,那么后台如何接收这些参数呢?下面我们一起学习一下: 这里我们将用到@RequestParam注解,这个注解有三个参数分别是:value.required.defaultValue,具体的用法,下面一一为大家

SpringBoot入坑-spring-boot-starter-web配置文件使用

经过上一篇的介绍,相信小伙伴们已经按奈不住内心对springboot的向往,本篇我将继续向小伙伴介绍springboot配置文件的配置,已经全局配置参数如何使用,好了下面开始我们今天的内容介绍. 我们知道Spring Boot支持容器的自动配置,默认是Tomcat,当然我们也是可以进行修改的: 1.首先我们排除spring-boot-starter-web依赖中的Tomcat:在pom文件中排除tomcat的starter <dependency> <groupId>org.spr

新人入坑Redis必会的吐血总结

新人入坑Redis必会的吐血总结 一.什么是Redis Redis是一个使用C语言开发的开源的高性能的key-value存储系统,我们可以把它近似理解为Java Map.简单来讲,Redis是一种NOSQL内存数据库,小伙伴们可不要把它理解为NO SQL(不是SQL),它的全称是Not Only SQL(不仅仅是SQL),换个层面来讲,它是一种非关系型的数据库,它是作为关系型数据库的良好补充,它与传统的MySQL,Oracle不同之处在于,它是通过在内存中读写数据,大大提高了读写速度.可以说,R

Spring Cloud Gateway入坑记

Spring Cloud Gateway入坑记 前提 最近在做老系统的重构,重构完成后新系统中需要引入一个网关服务,作为新系统和老系统接口的适配和代理.之前,很多网关应用使用的是Spring-Cloud-Netfilx基于Zuul1.x版本实现的那套方案,但是鉴于Zuul1.x已经停止迭代,它使用的是比较传统的阻塞(B)IO + 多线程的实现方案,其实性能不太好.后来Spring团队干脆自己重新研发了一套网关组件,这个就是本次要调研的Spring-Cloud-Gateway. 简介 Spring

VPS 入坑之路

一.入坑动机: 以前一直的FQ服务也被请喝茶了,仅限企业客户使用.于是想到租用一个VPS,搭个梯子. 二.入坑之路: 1.购买 想起在G+看见有人推荐搬瓦工性价比很高,去了解了一下,最低配置19.99刀一年,折合人民币也就十块一个月的样子,果断入之. 2.SS 以前在虚拟机稍微接触过linux,比如ubuntu和fedora,然而都是在图形界面瞎搞.这次终于有机会在终端操作了.各种命令上手确实不容易,只会cd,ls...突然发现控制面板有一键搭建SS,后来又放弃了敲命令...有一天心血来潮,决定

web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史

秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知,不问自晓,古今行事,未之有也 」 我们都知道如今流行的框架:Vue.Js.AngularJs.ReactJs.已经逐渐应用到各个项目和实际应用中,它们都是MVVM数据驱动框架系列的一种. 在了解MVVM之前,我们先回想一下前端发展的历史阶段,做到心中有数,才会更好理解. 这段回想历史.由于网上就可查不少资料,

webpack入坑之旅(二)loader入门

这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack 在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不是开始的开始 webpack入坑之旅(二)loader入门 webpack入坑之旅(三)webpack.config入门 webpack入坑之旅(四)扬帆起航 webpack入坑之旅(五)加载vue单文件组件 webpack入坑之旅(六)配合vue-router实现SPA 引子 在上一篇博客中我们已

web前端入坑第四篇:你还在用 jQuery?

web前端入坑第四篇:你还在用 jQuery? 大妈都这么努力,我们有几个人回家还看书的? 先来补齐[web前端入坑系列]前三篇的连接web前端入坑系列:点击标题进入第一篇: web 前端入坑第一篇:web前端到底是什么?有前途吗第二篇: web前端入坑第二篇:web前端到底怎么学?干货资料!第三篇:web前端入坑第三篇 | 一条"不归路" - 学习路线! 再说这个话题之前,我们先来扫盲普及一下 [jquery] 到底是什么以及它火爆将近十年的重要原因. [ 重新认识 - Jquery

gulp入坑系列(2)——初试JS代码合并与压缩

在上一篇里成功安装了gulp到项目中,现在来测试一下gulp的合并与压缩功能 gulp入坑系列(1)--安装gulp(传送门):http://www.cnblogs.com/YuuyaRin/p/6159809.html 在之前建立的项目中写入,在根目录新建js文件夹,并在文件夹中新建两个js文件,代码如下: index.js: var index={}; index={ test:function(argument){ console.log('test'); } } index.test()