经历了各种不可控与不可预知的磨难(包括但不限于idea闪退、navicat闪退、系统闪退、莫名其妙的bug无数、疯狂搜索各种注解是为什么无数、jdbcTemplate为什么失效了、@autowired为什么失效了,等等!),终于搞定了这个主题!!!!
本篇就来手把手教你搞定这个应用!
首先,大致总结一下,如果你想要从零开始,利用springboot框架,写一个能访问数据库并进行crud操作的,能给RESTful风格的接口的应用,应该怎么做:
推荐:
装一个postman,方便请求接口查看结果application.properties
文件中,可以配置上连接数据库需要用的信息,也可以配置上想要应用启动所用的端口号controller
、entity
、service
。entity
:用于写数据表对应的字段在java里面对应的对象,需要具有Bean的特征:getter、setter等;service
:用于写mysql语句与对应的jdbc请求controller
:用于调用service,制作对应的get/post接口懂得怎么搞这玩意的可以跳过这一part~~~
另外,此处不讨论如何本地搭一个docker,并在容器里面安装mysql
参考教程:blog.csdn.net/baidu_26315…
免费:mysqlWorkbench 付费:navicat
选择新建用户
添加常规信息,设置用户的名称和密码
添加用户的对象权限
勾选所需要的数据库的权限
利用官网生成一个springboot项目:start.spring.io/
所需要的依赖:
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
runtime
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-starter-test
test
org.springframework
spring-jdbc
5.3.13
compile
复制代码
重点依赖说明:
lombok
:是一个可以简化代码的库,可以帮助你不用自己去写getter()或者setter(),就能自动在调试编译的时候,生成Bean的相关方法。
spring-boot-starter-web
:用于创建springboot的web服务,可以提供REST风格相关api
mysql-connector-java
和spring-boot-starter-jdbc
:提供了mysql的JDBC连接方法,尤其是JdbcTemplate
然后,我们还需要配置这个工程项目和我们创建的数据库的连接信息:
# mysql connection settings
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/spring_example
spring.datasource.username=spring
spring.datasource.password=spring
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
复制代码
正如本篇开头所提到的,按照规范来说,java代码应该分好层次,所以我们会建立以上所示的三个package,分别代表以下含义:
entity
:用于写数据表对应的字段在java里面对应的对象,需要具有Bean的特征:getter、setter等;service
:用于写mysql语句与对应的jdbc请求controller
:用于调用service,制作对应的get/post接口然后分别对应创建相应的class,下面我们会分别讲解:
首先,我们要创建一个对应了数据表字段内容的类,便于我们从数据库取得数据后,可以存放在实例化的对象中。
常规来说,我们需要声明了一堆private的变量,然后写一些公共的getter()、setter()方法,来实现一个标准的java bean,便于我们在其他方法中实例化这个类型的对象。
但是,下面的代码就说明了,我们可以轻轻松松的用lombok的方法,添加@Data
注解,让自己不用再写一长串getter()、setter(),而让代码在编译的时候给我们自动生成这些东西。
package shenling.example.springbootJDBC.entity;
import lombok.Data;
@Data
public class user {
private Integer id;
private String firstname;
private String lastname;
}
复制代码
要注意的是,如果要让lombok生效,还需要让idea中下载并开启插件:lombok
在service层中,我们提供针对这个表的JDBC连接服务。基本上下面代码的逻辑就是:写一个sql,用JdbcTemplate来进行数据库连接和请求。
特别指出:相比起常规的普通框架,这里面由于我们使用了JdbcTemplate这些方法,所以不用再考虑要做database.connection这些“连接数据库 - crud - 关闭连接”这些额外的操作了,让我们更为集中精力在业务逻辑的实现上。这也是springboot的一大特色。
package shenling.example.springbootJDBC.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import shenling.example.springbootJDBC.entity.user;
import java.util.List;
@Service
@Component
public class userService {
@Autowired
private JdbcTemplate jdbcTemplate;
// 请求列表数据
public List getList() {
String sql = "SELECT * FROM user";
List result = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(user.class));
return result;
}
// 新增
public int addUser(user newUser) {
String sql = "INSERT INTO user(id, firstname, lastname)values(?,?,?)";
return jdbcTemplate.update(sql, newUser.getId(), newUser.getFirstname(), newUser.getLastname());
}
}
复制代码
要注意几个点:
我们引入了JdbcTemplate
的对象,来使用相关的方法,对数据库进行sql查询请求,完成crud操作。这里可以参考学习这篇文章:www.jianshu.com/p/f0cbed671…
在springboot里面,只要用@Component
注解过的class,就不用在调用的时候使用new进行实例化对象了,而是用@Autowired
注解搞定。所以:
JdbcTemplate
变量声明的前面添加@Autowired
注解userService
类,要在controller那边通过@Autowired
使用,所以这个类的前面需要添加@Component
注解List
的方法来保存结果,query的第二个参数也是用的这种map类。但是根据一些文的讨论和推荐,更为建议使用RowMapper的方式保存数据结果,认为速度更快更优。在controller里面,便是要创建这些接口了。就可以参考前面的关于如何建接口的demo来理解。
package shenling.example.springbootJDBC.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.web.bind.annotation.*;
import shenling.example.springbootJDBC.entity.response;
import shenling.example.springbootJDBC.entity.user;
import shenling.example.springbootJDBC.service.userService;
import java.util.List;
@RestController
@RequestMapping("/user")
public class userController {
@Autowired
private userService userService;
@Autowired
private response res;
// 获取用户列表
@GetMapping("/list")
public @ResponseBody response getUserList(){
try {
List result = userService.getList();
res.setResult(result);
res.setCode(10000);
res.setMsg("查询成功");
}
catch(DataAccessException e) {
// 异常抛出
e.printStackTrace();
String exceptionMsg = e.getRootCause().getMessage();
res.setCode(500);
res.setMsg(exceptionMsg);
}
return res;
}
}
复制代码
同样的,我们可以在这里面看到几个关键点:
@RestController
:要制作成接口,那么类前面就肯定要写上这个注解才行
@RequestMapping("/user")
:由于我们想要让接口访问的时候,第一段是user,然后才是后面的请求list、新增用户add等,所以要在类前面写上这个。当然如果不需要这一段跳转的话,可以不写。
@Autowired
:我们前面的userService那里用了@Component
注解,所以这里就可以直接用autowired来进行实例化,而不用通过new了
这段代码中,可以看到,我们通过userService.getList()
就可以拿到查询后的结果,并且可以通过抛出异常DataAccessException
抓取到异常日志。但是为了规范化我们的输出结果为msg/code/result的样式,所以我们还需要建一个response的类来声明我们的结果,下一小节会进行说明。
@ResponseBody
:这个写在了方法那里,是为了让方法返回的结果是JSON样式输出的,具有一种格式化、标准化的作用,来实现非常典型的rest接口返回结果风格。
为了让我们的输出结果标准化,所以在entity的package中,我们再建了一个class,去保存我们的输出结果的样子:
package shenling.example.springbootJDBC.entity;
import lombok.Data;
import org.springframework.stereotype.Component;
@Data
@Component
public class response {
private String msg;
private Integer code;
private Object result;
}
复制代码
这里面我们可以看到:
用了@Data
来实现一个Bean的风格的类
用了@Component
来保证在controller中,可以通过autowired进行使用
一般来说,通过官网初始化的springboot应用里面就包含了这个部分了:
package shenling.example.springbootJDBC;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootJdbcApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootJdbcApplication.class, args);
}
}
复制代码
其中,@SpringBootApplication
注解就能让这个应用运行的时候去找到我们的controller
有时候,默认8080端口被占用,所以我们可以查看这个端口号的pid并杀掉这个进程
当然也可以在application.property中设置一个新的端口号,例如:
server.port=1234
复制代码
运行成功后,控制台会显示当前web运行的端口号
当然,我们完全可以用浏览器直接访问get类型的接口,但是为了显得很专业+直观+美观,我们用postman这种接口管理工具
下载本地postman软件:www.postman.com/downloads/?…
发送请求并查看结果: