Spring Boot入门40-65操作MySQL/RESTFul风格
开始时间:2022-04-16
课程链接:动力节点springboot
第四章 ORM 操作 MySQL
使用MyBatis框架操作数据, 在SpringBoot框架集成MyBatis
使用步骤:
-
mybatis起步依赖 : 完成mybatis对象自动配置, 对象放在容器中
-
pom.xml 指定把src/main/java目录中的xml文件包含到classpath中
-
创建实体类Student
-
创建Dao接口 StudentDao , 创建一个查询学生的方法
-
创建Dao接口对应的Mapper文件, xml文件, 写sql语句
-
创建Service层对象, 创建StudentService接口和他的实现类。 去调用dao对象的方法。完成数据库的操作
-
创建Controller对象,访问Service。
-
写application.properties文件
配置数据库的连接信息。
创建一个模块
添加的依赖有
<!--web起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatis起步依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
新建文件的时候要勾选
创建实体类Student,包含三个字段 id name age
创建dao类
package com.bjpowernode.dao;
import com.bjpowernode.model.Student;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @Mapper:告诉MyBatis这是dao接口,创建此接口的代理对象。
* 位置:在类的上面
*/
@Mapper
public interface StudentDao {
Student selectById(@Param("stuId") Integer id);
}
首先明确这个注解Param是为SQL语句中参数赋值而服务的。原文链接
@Param的作用就是给参数命名,比如在mapper里面某方法A(int id),当添加注解后A(@Param(“userId”) int
id),也就是说外部想要取出传入的id值,只需要取它的参数名userId就可以了。将参数值传如SQL语句中,通过#{userId}进行取值给SQL的参数赋值。
写StudentDao.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjpowernode.dao.StudentDao">
<!--定义sql语句-->
<select id="selectById" resultType="com.bjpowernode.model.Student">
select id,name,age from student where id=#{stuId}
</select>
</mapper>
写业务层对象
定义接口和实现类
package com.bjpowernode.service;
import com.bjpowernode.model.Student;
public interface StudentService {
Student queryStudent(Integer id);
}
package com.bjpowernode.service.impl;
import com.bjpowernode.dao.StudentDao;
import com.bjpowernode.model.Student;
import com.bjpowernode.service.StudentService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class StudentServiceImpl implements StudentService {
@Resource
private StudentDao studentDao;
@Override
public Student queryStudent(Integer id) {
Student student = studentDao.selectById(id);
return student;
}
}
原文链接:
这里的注解@Resource也是用来自动注入的
@Resource(属于Java)有两个属性是比较重要的,分别是name和type;Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,按type进行注入的自动注入策略。
@AutoWired是spring的注解,Autowired只根据type进行注入,不会去匹配name。如果涉及到type无法辨别注入对象时,那需要依赖
创建StudentController
@Controller
public class StudentController {
@Resource
private StudentService studentService;
@RequestMapping("/student/query")
@ResponseBody
public String queryStudent(Integer id){
Student student = studentService.queryStudent(id);
return student.toString();
}
}
配置pom文件
让xml文件能输出到target目录中
不加的话只会输出resources目录下的配置文件
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
application.properties
server.port=9001
server.servlet.context-path=/orm
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT+8
spring.datasource.username=root
spring.datasource.password=333
然后发现启动的时候报错
ERROR 24288 — [nio-9001-exec-1] com.zaxxer.hikari.pool.HikariPool
&serverTimezone=Asia/Shanghai
暂时先搁置一下吧
问题找到了,因为我是导入的文件,所以resource文件夹没有mark as resource
这里处理一下就行了
第一种方式 : @Mapper
@Mapper:放在dao接口的上面, 每个接口都需要使用这个注解。
/**
* @Mapper:告诉MyBatis这是dao接口,创建此接口的代理对象。
* 位置:在类的上面
*/
@Mapper
public interface StudentDao {
Student selectById(@Param("stuId") Integer id);
}
第二种方式:MapperScan
/**
* @MapperScan: 找到Dao接口和Mapper文件
* basePackages:Dao接口所在的包名
*/
@SpringBootApplication
@MapperScan(basePackages = {"com.bjpowernode.dao","com.bjpowernode.mapper"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
我们可以把
放在一起
再在properties中注明我们这个地方要在mapper下找
mapper文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml
#打日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
第三种方式: Mapper文件和Dao接口分开管理
现在把Mapper文件放在resources目录下
1)在resources目录中创建子目录 (自定义的) , 例如mapper
2)把mapper文件放到 mapper目录中
3)在application.properties文件中,指定mapper文件的目录
#指定mapper文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml
#指定mybatis的日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
在pom.xml中指定 把resources目录中的文件 , 编译到目标目录中
<!--resources插件-->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
Spring框架事务
Spring框架中的事务:
1) 管理事务的对象: 事务管理器(接口, 接口有很多的实现类)
例如:使用Jdbc或mybatis访问数据库,使用的事务管理器:DataSourceTransactionManager
2 ) 声明式事务: 在xml配置文件或者使用注解说明事务控制的内容
控制事务: 隔离级别,传播行为, 超时时间
3)事务处理方式:
1) Spring框架中的@Transactional
2) aspectj框架可以在xml配置文件中,声明事务控制的内容
SpringBoot中使用事务: 上面的两种方式都可以。
1)在业务方法的上面加入@Transactional , 加入注解后,方法有事务功能了。
2)明确的在 主启动类的上面 ,加入@EnableTransactionManager
例子
/**
* @Transactional: 表示方法的有事务支持
* 默认:使用库的隔离级别, REQUIRED 传播行为; 超时时间 -1
* 抛出运行时异常,回滚事务
*/
@Transactional
@Override
public int addStudent(Student student) {
System.out.println("业务方法addStudent");
int rows = studentDao.insert(student);
System.out.println("执行sql语句");
//抛出一个运行时异常, 目的是回滚事务
//int m = 10 / 0 ;
return rows;
}
通过逆向工程生成dao下的mapper文件
以及resource下mapper里面的.xml文件
此时写service业务层的代码
写一个接口完成addStudent工作
再去实现他
package com.bjpowernode.service.impl;
import ...;
import javax.annotation.Resource;
@Service
public class StudentServiceImpl implements StudentService {
@Resource
private StudentMapper studentDao;
/**
* @Transactional: 表示方法的有事务支持
* 默认:使用库的隔离级别, REQUIRED 传播行为; 超时时间 -1
* 抛出运行时异常,回滚事务
*/
@Transactional
@Override
public int addStudent(Student student) {
System.out.println("业务方法addStudent");
int rows = studentDao.insert(student);
System.out.println("执行sql语句");
//抛出一个运行时异常, 目的是回滚事务
//int m = 10 / 0 ;
return rows;
}
}
写一个controller方法操作他
public class StudentController {
@Resource
private StudentService service;
@RequestMapping("/addStudent")
@ResponseBody
public String addStudent(String name,Integer age){
Student s1 = new Student();
s1.setName(name);
s1.setAge(age);
int rows = service.addStudent(s1);
return "添加学生:" rows;
}
这样添加学生
如果我们把除以0放进去
public int addStudent(Student student) {
System.out.println("业务方法addStudent");
int rows = studentDao.insert(student);
System.out.println("执行sql语句");
//抛出一个运行时异常, 目的是回滚事务
int m = 10 / 0;
return rows;
}
添加不了了
但我们再恢复过来添加,会发现由于主键自增,两个数据间的序号会相差2
接口的架构风格RESTful
接口: API(Application Programming Interface,应用程序接口)是一些预先定义的接口(如函数、HTTP接口),或指软件系统不同组成部分衔接的约定。 用来提供应用程序与开发人员基于某软件或硬件得以访问的一组例程,而又无需访问源码,或理解内部工作机制的细节。
接口(API): 可以指访问servlet, controller的url, 调用其他程序的 函数
架构风格: api组织方式(样子)
例如我们上面写的就是一个传统的: http://localhost:9002/mytrans/addStudent?name=lisi&age=26
在地址上提供了 访问的资源名称addStudent, 在其后使用了get方式传递参数。
REST : (英文: Representational State Transfer , 中文: 表现层状态转移)。
是一种接口的架构风格和设计的理念,不是标准。 (不强制)
表现层状态转移:
表现层就是视图层, 显示资源的, 通过视图页面,jsp等等显示操作资源的结果。
状态: 资源变化
转移: 资源可以变化的。 资源能创建,new状态, 资源创建后可以查询资源, 能看到资源的内容,
这个资源内容 ,可以被修改, 修改后资源 和之前的不一样。
使用url表示资源 ,使用http动作操作资源。
2)REST中的要素:
用REST表示资源和对资源的操作。 在互联网中,表示一个资源或者一个操作。
资源使用url表示的(我们包络外部使用queryStudent,一定对应了我们controller中调用的queryStudent功能的方法), 在互联网, 使用的图片,视频, 文本,网页等等都是资源。
资源是用名词表示。
比如我要保存图片,图片的地址就有:
https://gimg2.百度.com/image_search/src=http://wx2.sinaimg.cn/crop.0.6.1920.1067/99710220ly1h11a8ofn44j21hc0u07d7.jpg&refer=http://wx2.sinaimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1652749662&t=ebaa0e8ed1caa65079746753660d5e3c
对资源的处理也是增删改查
资源使用url表示,通过名词表示资源。
在url中,使用名词表示资源, 以及访问资源的信息, 在url中,使用“ / " 分隔对资源的信息
http://localhost:8080/myboot/student/1001
使用http中的动作(请求方式), 表示对资源的操作(CURD)
GET: 查询资源 – sql select
处理单个资源: 用他的单数方式
http://localhost:8080/myboot/student/1001
http://localhost:8080/myboot/student/1001/1
查询多个学生,处理多个资源:使用复数形式
http://localhost:8080/myboot/students/1001/1002
POST: 创建资源 – sql insert
http://localhost:8080/myboot/student
在post请求中传递数据
<form action="http://localhost:8080/myboot/student" method="post">
姓名:<input type="text" name="name" />
年龄:<input type="text" name="age" />
</form>
PUT: 更新资源 – sql update
<form action="http://localhost:8080/myboot/student/1" method="post">
姓名:<input type="text" name="name" />
年龄:<input type="text" name="age" />
<input type="hidden" name="_method" value="PUT" />
</form>
DELETE: 删除资源 – sql delete
<a href="http://localhost:8080/myboot/student/1">删除1的数据</a>
需要的分页, 排序等参数,依然放在 url的后面, 例如
http://localhost:8080/myboot/students?page=1&pageSize=20
注解
注解名 | 作用 |
---|---|
@PathVariable | 从url中获取数据 |
@GetMapping | 支持的get请求方式, 等同于 @RequestMapping( method=RequestMethod.GET) |
@PostMapping | 支持post请求方式 ,等同于 @RequestMapping( method=RequestMethod.POST) |
@PutMapping | 支持put请求方式, 等同于 @RequestMapping( method=RequestMethod.PUT) |
@DeleteMapping | 支持delete请求方式, 等同于 @RequestMapping( method=RequestMethod.DELETE) |
@RestController | 复合注解, 是@Controller 和@ResponseBody组合。 |
在类的上面使用@RestController , 表示当前类者的所有方法都加入了 @ResponseBody
写代码实验一下
package com.bjpowernode.controller;
import org.springframework.web.bind.annotation.*;
@RestController
public class MyRestController {
// 学习注解的使用
//查询id=1001的学生
/**
* @PathVariable(路径变量) : 获取url中的数据
* 属性: value : 路径变量名
* 位置: 放在控制器方法的形参前面
*
* http://localhost:8080/myboot/student/1002
*
* {stuId}:定义路径变量, stuId自定义名称
*/
@GetMapping("/student/{stuId}")
//拿到的{stuId}将要传给studentId
public String queryStudent(@PathVariable("stuId") Integer studentId){
return "查询学生studentId=" studentId;
}
/***
* 创建资源 Post请求方式
* http://localhost:8080/myboot/student/zhangsan/20
*/
@PostMapping("/student/{name}/{age}")
public String createStudent(@PathVariable("name") String name,
@PathVariable("age") Integer age){
return "创建资源 student: name=" name "#age=" age;
}
/**
* 更新资源
*
* 当路径变量名称和 形参名一样, @PathVariable中的value可以省略
*/
@PutMapping("/student/{id}/{age}")
public String modifyStudent(@PathVariable Integer id,
@PathVariable Integer age){
return "更新资源, 执行put请求方式: id=" id "#age=" age;
}
可以使用postman工具来辅助验证,: 可以测试 get ,post , put ,delete 等请求
不用自己写页面以及在浏览器中来实现请求测试了
/**
* 删除资源
*/
@DeleteMapping("/student/{id}")
public String removeStudentById(@PathVariable Integer id){
return "删除资源,执行delete, id=" id;
}
}
5.2 在页面中或者ajax中,支持put,delete请求
在SpringMVC中 有一个过滤器, 支持post请求转为put ,delete
过滤器: org.springframework.web.filter.HiddenHttpMethodFilter
作用: 把请求中的post请求转为 put , delete
实现步骤:
- application.properties(yml) : 开启使用 HiddenHttpMethodFilter 过滤器
- 在请求页面中,包含 _method参数, 他的值是 put,delete,发起这个请求使用的post方式
注意,使用时url的请求方式要唯一,防止有歧义
结束时间:2022-04-17
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhhacjja
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13