springboot jpa访问/操作关系型数据库(以mysql为例)

springboot是一种程序设计框架,其中集成了多个常用的模块用来完成许多常见的操作,比如web请求(springboot web)、关系型(springboot JPA)/非关系型数据库访问(比如springboot mongodb)等,框架的使用可以简化开发工作减少业务代码,因为许多底层的代码都被封装好了,开发人员只需要调用框架中给出的接口即可。

本文将介绍如何利用springboot JPA模块来操作关系型数据库(以mysql为例)。本文提供的程序可以实现在web端网址中传递参数来完成对mysql的查询、插入以及删除操作。查询全表数据并以json格式返回到web端的示例如下:

person表中的数据:
mysql> select * from person;
+-----+-------+------+--------+
| id  | name  | age  | gender |
+-----+-------+------+--------+
|   1 | liu   |    9 |      1 |
|   3 | zhang |    9 |      1 |
|   6 | lee   |   11 |      1 |
|   7 | zhang |   11 |      1 |
|   8 | li    |   11 |      1 |
|   9 | wang  |   11 |      1 |
|  10 | zhang |  100 |      1 |
|  11 | zhang |  100 |      1 |
|  12 | zhang |  100 |      1 |
|  13 | zhang |  100 |      1 |
|  16 | zhang |  100 |      1 |
| 106 | zhang |  100 |      1 |
+-----+-------+------+--------+
12 rows in set (0.00 sec)
web端发起查询请求

注意:web http请求参数以?开头并用&分隔参数。
图1. web端传入参数发起查询mysql person表的请求

第1步:基于maven新建springboot工程
<!-- pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- web依赖 --> 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
           <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--spring-boot-starter-data-jpa依赖于spring-boot-starter-jdbc,  因此添加了data-jpa依赖后不需要在添加jdbc依赖 -->
        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>-->
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
第2步: 配置文件application.properties
# jdbc设置
spring.jpa.database = MYSQL
spring.datasource.url=jdbc:mysql://localhost:3306/alex?useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
第3步:mysql中alex库中新建person表并插入数据
CREATE TABLE `person` (
  `id` int(11) NOT NULL,
  `name` varchar(10) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `gender` tinyint(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8


mysql> select * from person;
+-----+-------+------+--------+
| id  | name  | age  | gender |
+-----+-------+------+--------+
|   1 | liu   |    9 |      1 |
|   3 | zhang |    9 |      1 |
|   6 | lee   |   11 |      1 |
|   7 | zhang |   11 |      1 |
|   8 | li    |   11 |      1 |
|   9 | wang  |   11 |      1 |
|  10 | zhang |  100 |      1 |
|  11 | zhang |  100 |      1 |
|  12 | zhang |  100 |      1 |
|  13 | zhang |  100 |      1 |
|  16 | zhang |  100 |      1 |
| 106 | zhang |  100 |      1 |
+-----+-------+------+--------+
12 rows in set (0.00 sec)
第4步:基于springboot框架编写java程序

基于mvc设计程序:
该程序按照spring mvc来设计,其中entity实体类定义了java类和mysql表之间的映射关系,repository定义了操作mysql底层的方法实现,service层了逻辑处理并调用了repository操作mysql的方法,controller层则定义了和web端交互的逻辑(controller层会与service层和web层打交道,比如响应web层的请求并调用service层(service层会调用repository即DAO层)来访问数据库)。按照mvc设计可以减少程序各层之间的耦合,使得代码层次结构更加清晰,更加易于维护。

/**
 * 定义object relationship mapping
 * 即java类和数据库table的对应关系
 * @Entity申明此类是一个实体类
 * @Table声明表的对应关系
 * */
package com.example.dbaccess;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "person")
public class Person {
    // @Id注解必须要有,否则编译时会报错找不到identifier(Caused by: org.hibernate.AnnotationException: No identifier specified for entity: com.example.dbaccess.Person)
    // 被@Id注解的成员变量对应着table的主键,且被@Id注解的成员变量的数据类型必须和UserRepository的JpaRepository<Person, String>中的ID一致,但是可以和table中对应的字段数据类型不同(比如person表中的id字段就是int类型)。其中第一个参数是bean类,第二个参数是Id
    //@GeneratedValue(strategy=GenerationType.AUTO)
    // @GeneratedValue和@Id配合使用,用于指定主键生成的方式,不显式声明的情况下默认是AUTO,即jpa自动选择。

    @Id
    private Integer id;
    private String name;
    private Integer age;
    private Boolean gender;

    /**
     * springboot中:当声明了有参的构造方法的话,必须显式地声明无参的构造方法,否则汇报如下错误:
     * No default constructor for entity: : com.example.dbaccess.Person; nested exception is org.hibernate.InstantiationException: No default constructor for entity: 
     * */

    // 有参构造方法
    public Person(Integer id, String name, Integer age, boolean gender) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    // 无参构造方法
    public Person() {
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isGender() {
        return gender;
    }

    public void setGender(boolean gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return String.format("{person:{id:%s, name=%s, age=%s, gender=%s}}", id, name, age, gender);
    }
}






/**
 * repository层
 * 对数据库进行操作的代码
 * 由于我们导入了JPA依赖,很多通常的查询,删除,更新等操作可以不用在此编写
 * @Repository注解是告诉Spring Boot这是一个仓库类,会在启动的时候帮你自动注入(查询,删除,更新等操作的代码,比如jdbc)。
 * JpaRepository里面含有一般数据库操作所需要的接口,我们会在service层中调用他们
 * */
package com.example.dbaccess;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;

@Repository
public interface UserRepository extends JpaRepository<Person, Integer> {
    // 其中Person是与数据库表person对应的entity类,Integer是@Id注解的主键列
    // Spring Data Jpa 默认实现时hibernate,我们都知道hibernate使用HQL查询(Hibernate时JPA的实现之一),
    // 而不推荐使用sql查询,因为这样子就跟具体数据库耦合了。
    // 但是如果需要使用原生的sql查询语句就需要将nativeQuery设置为true(默认是false)。
    // @Query--执行sql语句并将结果作为被@Query注解的方法return的内容
   @Query(value = "select name from person", nativeQuery = true)
    List<String> queryAllName();

    @Query(value = "select * from person", nativeQuery = true)
    List<Person> queryAllPerson();
}






/**
 * service层:主要负责业务逻辑处理
 * 在此处我们编写了一个接口和一个实现类。
 * 接口的设计是为了满足松耦合的需求。
 *
 * */
package com.example.dbaccess;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public interface UserService {
    List<Person> getAll();
    List<String> queryAllName();
    List<Person> queryAllPerson();
}



// @Service类
// service层:主要负责业务逻辑处理
package com.example.dbaccess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserRepository userRepository;

    // 调用JpaRepository操作mysql的方法

    @Override
    public List<Person> getAll() {
        return userRepository.findAll();
    }

    @Override
    public List<String> queryAllName() {
        return userRepository.queryAllName();
    }

    @Override
    public List<Person> queryAllPerson() {
        return userRepository.queryAllPerson();
    }

    public void delById(int id){
        userRepository.deleteById(id);
    }

    public void addRecord(Person person){
        userRepository.save(person);
    }
}






/**
 * 编写Control层
 * 此层主要进行对页面的处理(和页面有mapping),包括跳转或者传参等等。
 * */
package com.example.dbaccess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;

@Configuration
@RestController
@RequestMapping("controller")
public class UserController {

    private static Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserServiceImpl userServiceImpl;


    @RequestMapping("/name")
    @ResponseBody
    private List<Person> getNames(){
        List<String> nameArr = new ArrayList<>();
        List<Person> personArr = new ArrayList<>();
        for (Person person: userServiceImpl.getAll()){
            String name =  person.getName();
            logger.info(">>>>>> name is: " + name);
            nameArr.add(name);
            personArr.add(person);
        }
        // return String.join("-", nameArr);
        return personArr;
    }
    /**
     * 注意:class和method上面都需要@RequestMapping标注,这样访问的网址是:
     * localhost:port/controller/name
     * 其中host默认是8080,如果在application.properties中修改了server.port,则以配置文件为准
     * */
    @RequestMapping("/del")
    private String delRecord(@RequestParam("id") int id){
        userServiceImpl.delById(id);
        return String.format(">>>>>> record (id=%s) deleted.", id);
    }

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    private String addRecord(@RequestParam(name="id", required = true) Integer id, @RequestParam(name="name",required=false) String name, @RequestParam(name="age",required=false) Integer age, @RequestParam(name="gender",required=false) Boolean gender) {
        userServiceImpl.addRecord(new Person(id, name, age, gender));
        return String.format(">>>>>> record (id=%s, name=%s, age=%s, gender=%s) added.", id, name, age, gender);
        //return "add succeed.";
    }

    @ResponseBody      // 返回xml、json内容到web端
    @RequestMapping(value = "/query", method = RequestMethod.GET)
    private List<String> queryAllNames(){
        return userServiceImpl.queryAllName();
    }

    @ResponseBody
    @RequestMapping(value = "/queryPerson", method = RequestMethod.GET)
    private List<Person> queryAllPersons(){
        return userServiceImpl.queryAllPerson();
    }
}




//  主类
package com.example.dbaccess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class UserMain {

    @Autowired
    private UserController controller;
    public static void main(String[] args){
        SpringApplication.run(UserMain.class);
    }
}

以上就是基于springboot框架和maven来完成对mysql访问/操作的基本过程,不对之处敬请大神纠正!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值