前后端分离
- 1.创建springboot工程,配置目录(省略导包)
- 2.application.yml
- 3.pom.xml(重要的部分)
- 4. cn.kgc.entity/Student
- 5.resources/mapper/StudentMapper.xml(省略开头)
- 6. cn.kgc.mapper/StudentMapper
- 7. cn.kgc.service/StudentService、StudentServiceImpl
- 8.cn.kgc.service/Studentcontroller
- 9.SpringbootAllDemo01Application
- 10 简单测试
- 11.html(static下)
- 12.综合测试(省略)
- 13.题外话
- 13.1 热部署
- 13.2 正则表达式
- 13.3 jQuery post() 方法(摘录菜鸟教程)
- 13.4 注解介绍(摘录)
- 13.4.1 @SpringBootApplication
- 13.4.2 @Mapper作用:
- 13.4.3 @MapperScan作用:
- 13.4.4 @Select("select * from t_user")
- 13.4.5 @RestController(一般springboot中使用)
- 13.4.6 @Controller (ssm中使用)
- 13.4.7 @RequestParam
- 13.4.8 @ResponseBody
- 13.4.9 @RequestBody
- 13.4.10 @RequestMapping("/xxx")
- 13.4.11 @DateTimeFormat(pattern = "yyyy-MM-dd")
- 13.4.12 @JsonFormat(pattern = "yyy-MM-dd")
1.创建springboot工程,配置目录(省略导包)
注意: 导入js包的时候,在static先建html,不然会static/js
2.application.yml
server:
port: 9000
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_211224_student?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&zeroDateTimeBehavior=CONVERT_TO_NULL
username: root
password: zjj
mybatis:
mapper-locations: classpath:mapper/*.xml
pagehelper:
helper-dialect: mysql
reasonable: true
3.pom.xml(重要的部分)
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!-- <scope>runtime</scope>-->
<version>8.0.21</version>
</dependency>
4. cn.kgc.entity/Student
@Data
public class Student implements Serializable {
private Integer sid;
private String sname;
private Integer sage;
private Double score;
@DateTimeFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
// 前端的date类型转换为实体类的date类型
@JsonFormat(pattern = "yyy-MM-dd",timezone = "GMT+8")//返回到前端
//date类型用实体类可能会出问题 所以加个注解 所以还是用map好 的两个注解都加可以
private Date borndate;
}
timezone = “GMT+8” 不然会有差值,前端和后端时间不匹配
5.resources/mapper/StudentMapper.xml(省略开头)
<mapper namespace="cn.kgc.mapper.StudentMapper">
<select id="findAll" resultType="java.util.Map">
select * from t_student
</select>
<select id="findAllByPage" resultType="java.util.Map">
select * from t_student
</select>
<insert id="addStudent" parameterType="cn.kgc.entity.Student">
insert into t_student(sname,sage,score,borndate)
values (#{sname},#{sage},#{score},#{borndate})
</insert>
<delete id="del" parameterType="java.lang.Integer">
delete from t_student where sid = #{sid}
</delete>
</mapper>
6. cn.kgc.mapper/StudentMapper
@Mapper
public interface StudentMapper {
//查询(无分页版)
List<Map<String,Object>> findAll();
//查询(分页版)
List<Map<String,Object>> findAllByPage();
//添加
Integer addStudent(Student student);
Integer del(Integer sid);
@Select("select * from t_student where sid = #{sid}")
Map<String,Object> findById(Integer sid);
@Update("update t_student set sname=#{sname},sage=#{sage},score=#{score},borndate=#{borndate} where sid = #{sid}")
Integer updateStudent(Student student);
}
7. cn.kgc.service/StudentService、StudentServiceImpl
StudentService
public interface StudentService {
List<Student> find();
List<Map<String,Object>> findAll();
PageInfo<Map<String,Object>> findAllByPage(Integer pageNo);
Integer addStudent(Student student);
Integer del(Integer sid);
Map<String,Object> findById(Integer sid);
Integer updateStudent(Student student);
}
StudentServiceImpl
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper;
@Override
public List<Student> find() {
return studentMapper.find();
}
@Override
public List<Map<String, Object>> findAll() {
return studentMapper.findAll();
}
@Override
public PageInfo<Map<String, Object>> findAllByPage(Integer pageNo) {
PageHelper.startPage(pageNo,2);
return new PageInfo<>(studentMapper.findAllByPage());
}
@Override
public Integer addStudent(Student student) {
return studentMapper.addStudent(student);
}
@Override
public Integer del(Integer sid) {
return studentMapper.del(sid);
}
@Override
public Map<String, Object> findById(Integer sid) {
return studentMapper.findById(sid);
}
@Override
public Integer updateStudent(Student student) {
return studentMapper.updateStudent(student);
}
}
//@ResponseBody 加在类上的
8.cn.kgc.service/Studentcontroller
@RestController //返回数据
//@Controller 调页面的
public class StudentController {
@Autowired
private StudentService studentService;
@RequestMapping("/findAll")
public List<Map<String,Object>> findAll(){
return studentService.findAll();
}
@RequestMapping("/findAllByPage")
public PageInfo<Map<String,Object>> findAllByPage(Integer pageNo){
return studentService.findAllByPage(pageNo);
}
@RequestMapping("/add")
public String add(Student student){ //@RequestBody 对象 参数作为json 用来测试postman 后面有了serialize就要去掉该注解
studentService.addStudent(student);
return "ok";
// "ok" @ResponseBody 作为json
}
@RequestMapping("/del")
public String del(Integer sid){
studentService.del(sid);
return "ok";
}
@RequestMapping("/findById")
public Map<String,Object> findById(Integer sid){
return studentService.findById(sid);
}
@RequestMapping("/update")
public String update(Student student){
studentService.updateStudent(student);
return "ok";
}
}
9.SpringbootAllDemo01Application
@SpringBootApplication
@MapperScan("cn.kgc.mapper")
public class Sproot1224Application {
public static void main(String[] args) {
SpringApplication.run(Sproot1224Application.class, args);
}
}
10 简单测试
添加方法不写页面进行测试可以选择在postman上测试
其中参数前面加个@RequestBody 与postman中对应、
发送以json的方式,因为add要写参数
结果为“ok”代表添加成功。
11.html(static下)
11(1) findAll.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script>
$(function () {
showData();
})
function showData() {
$.ajax({
url: "http://localhost:9000/findAll",
type: "post",
data: { },
dataType: "json",
async: false,
success:function (data) {
var str = "";
$.each(data,function (i) {
str += "<tr>";
str += " <td>"+data[i].sid+"</td>";
str += " <td>"+data[i].sname+"</td>";
str += " <td>"+data[i].sage+"</td>";
str += " <td>"+data[i].score+"</td>";
str += " <td>"+data[i].borndate+"</td>";
str += "</tr>";
});
$("table").append(str);
},
error: function () {}
})
}
</script>
</head>
<body>
<table border="1px solid">
<tr>
<td>编号</td>
<td>姓名</td>
<td>年龄</td>
<td>分数</td>
<td>出生日期</td>
</tr>
</table>
</body>
</html>
11(2) findAllByPage.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script>
$(function () {
showData(1);
})
function showData(pageNo) {
$.ajax({
url: "http://localhost:9000/findAllByPage",
type: "post",
data: {"pageNo": pageNo},
dataType: "json",
async: false,
success: function (data) {
$(".info").remove();
var str = "";
$.each(data.list, function (i) {
str += "<tr class='info'>";
str += " <td>" + data.list[i].sid + "</td>";
str += " <td>" + data.list[i].sname + "</td>";
str += " <td>" + data.list[i].sage + "</td>";
str += " <td>" + data.list[i].score + "</td>";
str += " <td>" + data.list[i].borndate + "</td>";
str += " <td><a href='javascript:void(0)' οnclick='del(" + data.list[i].sid + ")'>删除</a>"
str += " <a href='update.html?sid="+data.list[i].sid+"'>修改</a></td>"
str += "</tr>";
});
str += "<tr class='info'>";
str += " <td colspan='6' style='text-align: center'>";
str += " <a href='javascript:void(0)' οnclick='showData(1)'>首页</a>";
str += " <c:if test='${pageInfo.hasPreviousPage}'><a href='javascript:void(0)' οnclick='showData(" + data.prePage + ")'>上一页</a></c:if>";
str += " <c:if test='${pageInfo.hasNextPage}'><a href='javascript:void(0)' οnclick='showData(" + data.nextPage + ")'>下一页</a></c:if>";
str += " <a href='javascript:void(0)' οnclick='showData("+data.pages+")'>末页</a>";
// data.lastPage不管用有时候
str += " </td>";
str += "</tr>";
$("table").append(str);
},
error: function () {
}
})
}
function del(sid) {
$.ajax({
url: "http://localhost:9000/del",
type: "post",
data: {"sid":sid},
dataType: "text",
async: false,
success:function (data){
if (data == "ok"){
window.location.href="findAllByPage.html"
}
},
error:function () {}
})
}
</script>
</head>
<body>
<table border="1px solid">
<tr>
<td>编号</td>
<td>姓名</td>
<td>年龄</td>
<td>分数</td>
<td>出生日期</td>
<td>操作</td>
</tr>
</table>
</body>
</html>
11(3) add.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script>
function add() {
$.ajax({
url: "add",
type: "post",
data: $("form").serialize(),
dataType: "text",
async: false,
success: function (data) {
if (data == "ok"){
window.location.href = "findAllByPage.html"
}
},
error:function () {}
});
}
</script>
</head>
<body>
<form>
<table border="1px solid">
<tr>
<td>姓名</td>
<td><input type="text" name="sname" /></td>
</tr>
<tr>
<td>年龄</td>
<td><input type="text" name="sage" /></td>
</tr>
<tr>
<td>分数</td>
<td><input type="text" name="score" /></td>
</tr>
<tr>
<td>出生日期</td>
<td><input type="date" name="borndate" /></td>
</tr>
<tr>
<td><input type="button" value="提交" onclick="add()"></td>
</tr>
</table>
</form>
</body>
</html>
11(4) update.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script>
$(function () {
var sid = /\d+$/.exec(window.location. search)[0];
$.ajax({
url: "findById",
type: "post",
data: {"sid":sid},
dataType: "json",
async: false,
success: function (date){
$("[name=sid]").val(date.sid);
$("[name=sname]").val(date.sname);
$("[name=sage]").val(date.sage);
$("[name=score]").val(date.score);
$("[name=borndate]").val(date.borndate);
},
error:function () {}
})
});
function update() {
$.ajax({
url: "http://localhost:9000/update",
type: "post",
data: $("form").serialize(),
dataType: "text",
async: false,
success: function (data) {
if (data == "ok"){
window.location.href="findAllByPage.html"
}
},
error:function () {}
})
}
</script>
</head>
<body>
<form>
<table border="1px solid">
<input type="hidden" name="sid">
<tr>
<td>姓名</td>
<td><input type="text" name="sname" /></td>
</tr>
<tr>
<td>年龄</td>
<td><input type="text" name="sage" /></td>
</tr>
<tr>
<td>分数</td>
<td><input type="text" name="score" /></td>
</tr>
<tr>
<td>出生日期</td>
<td><input type="date" name="borndate" /></td>
</tr>
<tr>
<td><input type="button" value="修改" onclick="update()"></td>
</tr>
</table>
</form>
</body>
</html>
12.综合测试(省略)
13.题外话
13.1 热部署
springBoot也有热部署,可以配置,但有时候会失效,有bug
13.2 正则表达式
var sid = /\d+$/.exec(window.location.search)[0];
var reg = /表达式/附加参数
$: 匹配字符串的 结束
\d: 匹配一个数字字符,等价于[0 - 9]
+
:多个“\d”
exec(): 检索字符中是正则表达式的区配,返回找到的值,
并确定其位置 返回的是一个数组 所以获取0
search: 从问号(?)开始的URL(查询部分)
[0]: 获取单个值
13.3 jQuery post() 方法(摘录菜鸟教程)
ajax的另一种写法:
$(document).ready(function(){
$("button").click(function(){
$.post("/try/ajax/demo_test_post.php",{
name:"菜鸟教程",
url:"http://www.runoob.com"
},
function(data,status){
alert("数据: \n" + data + "\n状态: " + status);
});
});
});
13.4 注解介绍(摘录)
13.4.1 @SpringBootApplication
是Sprnig Boot项目的核心注解,目的是开启自动配置
13.4.2 @Mapper作用:
在接口类上添加了@Mapper,在编译之后会生成相应的接口实现类
如果想要每个接口都要变成实现类,那么需要在每个接口类上加上@Mapper注解,
比较麻烦,解决这个问题用@MapperScan。
13.4.3 @MapperScan作用:
指定要变成实现类的接口所在的包,(指定要扫描Mapper类的包的路径)然后包下面的所有接口在编译之后都会生成相应的实现类一般是在Springboot启动类上面添加Springboot122301Application 中写
有了这个注解就不用写@Mapper
13.4.4 @Select(“select * from t_user”)
就不用写xml文件了
13.4.5 @RestController(一般springboot中使用)
1.@RestController等价于@Controller和@ResponseBody
2.返回json数据的,返回的内容就是Return 里的内容
3.不会返回jsp或html页面,视图解析器无法解析jsp,html页面
13.4.6 @Controller (ssm中使用)
1.与@RequestMapping一起用,调jsp页面或重定向到对应的url请求
1.与@ResponseBody一起用,将内容以json、XML等等格式返回到指定页面中
2. 用于标记一个类,使他标记的类就是一个SpingMVC Controller 对象,即是一个控制器。
13.4.7 @RequestParam
(value=“参数名”,defaultValue = “1”,required = “true/false”)**
1.将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)
2.defaultValue,默认值为1,
3.required = “false"表示可以不传参数 即是空的,就使用默认值
细节:如果@requestParam注解的参数是int类型,并且required=false,
没给默认值(defaultValue)此时如果不传参数的话,会报错,会给null,
这样null赋值给int,会报错。
13.4.8 @ResponseBody
(返回页面的时候以json格式)
1.作用:返回某种格式的数据(如json、xml等) 不加就是返回页面
2.是根据return后面的数据以某某格式来进行返回
2.通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,
加上 @Responsebody 后返回结果不会被解析为跳转路径而是直接写入HTTP 响应正文中。
3. 该注解用于将Controller的方法返回的对象,
通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
13.4.9 @RequestBody
(json格式提交数据 ) 请求的时候以json的格式
1.@RequestBody是作用在形参列表上,用于将前台发送过来固定格式的数据【xml 格式或者 json等】封装为对应的 JavaBean 对象,封装时使用到的一个对象是系统默认配置的 HttpMessageConverter进行解析,然后封装到形参上。
2.如果没有结果那就再加个@RequestParam(value = “xx”) 可能是编译的问题
3.用来测试postman 后面ajax里有了serialize就要去掉该注解
13.4.10 @RequestMapping("/xxx")
1.在Spring MVC 中使用 @RequestMapping 来映射请求,
也就是通过它来指定控制器可以处理哪些URL请求。
2.可用于类或方法上
13.4.11 @DateTimeFormat(pattern = “yyyy-MM-dd”)
前端的date类型转换为实体类的date类型
13.4.12 @JsonFormat(pattern = “yyy-MM-dd”)
返回到前端
作用: 后台的时间 格式化 发送到前台。
date类型用实体类可能会出问题 所以加个注解 所以还是用map好
两个注解都加可以
----2021.12.24&12.25