第七章 使用JPA操作数据库

本章主要介绍如何在Spring Boot的Web应用中使用Mysq数据库,也充分展示Spring Boot的优势(尽可能少的代码和配置).

数据访问层我们将使用Spring Data JPA和Hibernate(JPA的实现之一).

本章我们使用数据库名称为lightsword;

数据表名ls_user;

字段包括id, username, password, gmt_create, gmt_update。(其中id为主健,int类型, username和password分别为用户名和密码,都是varchar类型, gmt_create为创建日期,datetime类型,gmt_update为更新时间,datetime类型)

配置pom.xml文件

打开pom.xml文件,增加如下依赖:

org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java

配置文件application.properties

在src/main/resources/application.properties中配置数据库,包括url,用户名,密码和driverClassName:

spring.datasource.url = jdbc:mysql://localhost:3306/lightsword?useUnicode=true&characterEncoding=UTF8 spring.datasource.username = root spring.datasource.password = root spring.datasource.driverClassName = com.mysql.jdbc.Driver

上文中的数据库配置,你需要换成你的数据库的地址和用户名密码。

创建实体类

在src->main->java->lightsword下,创建一个package,名称为entity。在entity包下创建java类,名称为User,这就是我们的实体类。User.java内容如下:

package lightsword.entity;

import javax.persistence.*; import java.util.Date;

@Entity @Table(name = "ls_user") public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id;

private String username;
private String password;

private Date gmtCreate;
private Date gmtUpdate;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public Date getGmtCreate() {
    return gmtCreate;
}

public void setGmtCreate(Date gmtCreate) {
    this.gmtCreate = gmtCreate;
}

public Date getGmtUpdate() {
    return gmtUpdate;
}

public void setGmtUpdate(Date gmtUpdate) {
    this.gmtUpdate = gmtUpdate;
}

} 这里我们使用了两个注解@Entity, @Table。 @Entity表示是一个实体类。 @Table用于对应数据库中的表名。

创建Dao层

在src->main->java->lightsword下,创建一个package,名称为dao。在dao包下创建java接口,名称为UserDao,这就是我们的数据访问层。

实体的数据访问层UserDao非常简单,只需要继承CrudRespositroy即可,CrudRespositroy已经实现了save,delete,deleteAll,findOne和findAll. (比较神奇的时这些方法其实CrudRespositroy中其实并没有实现,并且通过对dao层的方法的命名还可以实现新的方法).

当然,如果基本的CRUD方法满足不了我们稍微复杂一些的sql查询,我们可以直接定义sql查询语句,绑定dao层的方法.

UserDao.java内容如下:

package lightsword.dao;

import lightsword.entity.User;
import org.springframework.data.repository.CrudRepository;
import java.util.List;

public interface UserDao extends CrudRepository<User, Integer> {
    List<User> findAll();
}

findAll()是CrudRepository自带的方法。

控制器

回到MainController.java

我们借助@Autowired注解,自动装配Dao层。修改一下hello方法,将用户表的数据查询出来后显示在前端。 完整的MainController.java内容如下:

package lightsword.controller;

import lightsword.dao.UserDao;
import lightsword.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

@Controller
public class MainController {
    @Autowired
    private UserDao userDao;

    @RequestMapping("/hello")
    public ModelAndView hello(Model model){
        ModelAndView modelAndView = new ModelAndView("index");

        String hello = "Hello world";
        model.addAttribute("hello", hello);

        List<User> userList = userDao.findAll();
        model.addAttribute("userList", userList);

        return modelAndView;
    }

    @RequestMapping(value = "/testGet", method = RequestMethod.GET)
    @ResponseBody
    public String testGet(){
        return "this is a get request data";
    }

    @RequestMapping(value = "/testPost", method = RequestMethod.POST)
    @ResponseBody
    public String testPost(@RequestParam String username){
        String result = "hello " + username;
        return result;
    }
}

最后,更新一下src->main->resources->templates目录下的index.html文件。这里为了美化前端,我们引入bootstrap框架。

在resources->static目录下新建一个css目录,将bootstrap.min.css拷贝到css目录里。将bootstrap.min.js拷贝到static->js目录下。(没有这两个文件的可到bootstrap官网下载)

然后修改我们的index.html文件,引入bootstrap文件,定义一个table用于显示ls_user表的数据。我们使用velocity的#foreach语法将数据显示。

为了展示:我们先在数据表ls_user里手动插入几条测试数据。

完整的index.html内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="/css/bootstrap.min.css" rel="stylesheet">
    <script src="/js/jquery.min.js"></script>
    <script src="/js/bootstrap.min.js"></script>
</head>
<body>
<h1>$hello</h1>
<div id="container-get" style="border:1px solid red; width:300px; height:100px;">
    loading...
</div>

<div id="container-post" style="border:1px solid green; width:300px; height:100px;">
    loading...
</div>
<table class="table table-striped">
    <thead>
        <th>ID</th>
        <th>用户名</th>
        <th>密码</th>
    </thead>
    <tbody>
    #foreach($user in $userList)
    <tr>
        <td>$user.id</td>
        <td>$user.username</td>
        <td>$user.password</td>
    </tr>
    #end
    </tbody>
</table>
</body>
</html>
<script type="text/javascript">
    $(function(){
        $.get('/testGet', function(data){
            $("#container-get").html(data);
        });

        var username = "lightsword";
        $.post('/testPost', {username:username}, function(data){
            $("#container-post").html(data);
        });
    });
</script>

运行测试

运行lighsword.java后,浏览器访问:http://127.0.0.1:9527/hello

页面下方输出了我们手动插入的两条测试数据,如下图所示:

results matching ""

    No results matching ""