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请求参数以?开头并用&分隔参数。
![](https://img.haomeiwen.com/i13578911/793d98c510bfdbfe.png)
第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访问/操作的基本过程,不对之处敬请大神纠正!
网友评论