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

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

  1. SpringBoot入坑-项目搭建

    对于学过三大框架的小童鞋,从今天开始给大家带来一套新的框架学习,相信对于做程序的小童鞋一定有所耳闻,作为下一代java开发框架springboot,减去了繁琐的xml配置,相信用过spring.sta ...

  2. SpringBoot入坑-请求参数传递

    前一篇我们探讨了关于springboot的配置文件和Controller的使用,本篇我们来一起探讨一下关于springboot如何传递参数的知识. 参数传递我们最常见的就是在url后通过?/& ...

  3. Idea+springboot入坑之路

    环境准备 IDEA 社区版: 2019.3 jdk: 1.8.0_241 tomcat: 7.0.99 maven: 3.6.3 spring-boot:2.2.5.RELEASE 插件 spring ...

  4. SpringBoot入坑指南之六:使用过滤器或拦截器

    在Web应用中,常常存在拦截全部或部分请求进行统一处理的应用场景,如权限校验.参数校验.性能监控等. 在SpringMVC框架中,我们可以通过过滤器或拦截器实现相关功能,spring-boot-sta ...

  5. SpringBoot入坑-配置文件使用

    经过上一篇的介绍,相信小伙伴们已经按奈不住内心对springboot的向往,本篇我将继续向小伙伴介绍springboot配置文件的配置,已经全局配置参数如何使用,好了下面开始我们今天的内容介绍. 我们 ...

  6. 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程

    反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑)   背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...

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

    新人入坑Redis必会的吐血总结 一.什么是Redis Redis是一个使用C语言开发的开源的高性能的key-value存储系统,我们可以把它近似理解为Java Map.简单来讲,Redis是一种NO ...

  8. Spring Cloud Gateway入坑记

    Spring Cloud Gateway入坑记 前提 最近在做老系统的重构,重构完成后新系统中需要引入一个网关服务,作为新系统和老系统接口的适配和代理.之前,很多网关应用使用的是Spring-Clou ...

  9. RoboGuice 3.0 (一)入坑篇

    RoboGuice是什么? 一个Android上的依赖注入框架. 依赖注入是什么? 从字面理解,这个框架做了两件事情,第一是去除依赖,第二是注入依赖.简单理解就是,将对象的初始化委托给一个容器控制器, ...

随机推荐

  1. 48、mysql补充

    一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...

  2. JavaWeb之数据源连接池(1)---DBCP

    何为数据源呢?也就是数据的来源.我在前面的一篇文章<JavaWeb之原生数据库连接>中,采用了mysql数据库,数据来源于mysql,那么mysql就是一种数据源.在实际工作中,除了mys ...

  3. DeepLearning.ai学习笔记(三)结构化机器学习项目--week1 机器学习策略

    一.为什么是ML策略 如上图示,假如我们在构建一个喵咪分类器,数据集就是上面几个图,训练之后准确率达到90%.虽然看起来挺高的,但是这显然并不具一般性,因为数据集太少了.那么此时可以想到的ML策略有哪 ...

  4. 浅谈传统语音通信和APP语音通信音频软件开发之不同点

    本人在传统的语音通信公司做过手机和IP电话上的语音软件开发,也在移动互联网公司做过APP上的语音软件开发.现在带实时语音通信功能的APP有好多,主流的有微信语音.QQ电话.钉钉等,当然也包括我开发过的 ...

  5. xamarin android listview的用法

    listview也许是用的非常频繁的一个控件之一,下面我写一个xamarin的listview栗子,大家尝一尝xamarin android开发的乐趣.原谅我的大小写吧. listview绑定自定义的 ...

  6. ElasticSearch 学习记录之ES如何操作Lucene段

    近实时搜索 提交(Commiting)一个新的段到磁盘需要一个 fsync 来确保段被物理性地写入磁盘,这样在断电的时候就不会丢失数据.但是每次提交的一个新的段都fsync 这样操作代价过大.可以使用 ...

  7. MySQL集群PXC的搭建

    MySQL集群PXC的搭建 最近公司某客户要求我们的数据库搭建PXC集群以保证他们的系统高性能和搞稳定性 以后花费了一些时间去搭建和测试,也踩过一些坑,准备分享出来 系统:centos6.6PXC:5 ...

  8. MySQL数据库学习: 02 —— 数据库的安装与配置

                             MySQL安装图解 一.MYSQL的安装 1.打开下载的mysql安装文件mysql-5.0.27-win32.zip,双击解压缩,运行“setup. ...

  9. parse_str 与 http_build_query的使用

    1 http_build_query() 使用 生成 URL-encode 之后的请求字符串 [建议在使用前,使用array_filter($query) 进行处理] 例子 1. http_build ...

  10. Ruby学习之代码块

    代码块在其他的语言中都或多或少接触过一些,如perl中sort{$a<=>$b}keys,传入代码块实现按数值排序,在swift中用到闭包,更加深入学习到training closure. ...