一.springboot入门
1.为什么需要学习Springboot?
使用Spring SpringMVC Mybatis
- 写一堆配置文件 application.xml mybatis springmvc
- 需要maven导入一堆依赖
- 测试开发逻辑 无论是开发还是部署, 需要将项目打成war包,服务器还需要配置好服务器环境
2.什么是SpringBoot?
SpringBoot 基于 Spring开发的, 只是用于快速,敏捷地开发新一代基于spring框架的应用程序,Springboot以约定大于配置的核心思想
3.快速创建一个springboot项目
3.1spring.io创建
3.2aliyun镜像创建
类型Type 选择 Maven
命名都是小写
3.3yml文件配置
- 使用yml文件有层级结构 缩进
- 使用yml文件 key value之间使用:号进行连接
- 赋值时候,:号后面必须加空格
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/数据库名?characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: 数据库账号
password: 数据库密码
driver-class-name: com.mysql.jdbc.Driver
3.4测试
注意添加 @ResponseBody转换成json格式
@Controller
public class UserController {
@RequestMapping("/hello")
@ResponseBody
public String hello(){
System.out.println("yyds");
return "springboot is running";
}
}
3.5主启动类启动
3.6springboot主程序解析
1.注解解析
@CompontScan: 自动扫描并且加载符合条件的组件或者bean对象,将bean对象加载到ioc容器中,规则就是扫描当前包的路径,默认就是扫描主启动类所在的包路径
@EnableAutoConfiguration: 开启自动配置功能,以前我们需要自己编写的配置,现在springboot可以自动帮我们配置
@autoConfigurationPackage: 自动配置包
@import: 给容器导入一个组件
AutoConfigurationImportSelector:自动配置的导入选择器
2.Springboot启动的时候都干了些什么?
Springboot项目在启动时,首先基于主启动类的注解,进行自动配置并且扫描指定包以及子包下面所有的类,进行加载,然后去检测类上是否包含spring框架指定的注解(@component @controller @service).假设类上有spring框架指定的相关注解,就把该类交给spring框架的中beanFactory工厂接口的实现类,此工厂对象基于反射创建的bean对象.当实例创建以后,spring框架还会基于类上的注解去描述作用域,生命周期.
4.Springboot的优点:
- springboot起步依赖(springboot就可以基于功能依赖,通过起步依赖为项目依赖管理提供帮助)
- Starter自动依赖与版本控制
- 大量的自动配置,简化开发
- 使用嵌入式的tomcat容器,应用程序无需打成war包
- 快速的创建独立的spring项目以及与其他主流框架集成
5.其他目录
Resource文件目录结构:
Static:保存所有静态资源(css,js,image,video)
Templates: 保存所有的模板,(springboot默认使用的嵌入式tomcat,默认是不支持jsp),但是可以使用模板引擎(freemarket,thymeleaf)
Application.properties:springboot配置文件的格式中的一种,另外一种(yml)
二. 整合第三方框架
整合Mybatis框架
1.准备mybatisjar包(pom.xml)
<!-- 准备mybatis jar包-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--简化实体类的代码-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
2.实体类编写
@Component
//lombok
@Data
@AllArgsConstructor
@NoArgsConstructor
//开启链式加载
@Accessors(chain = true)
public class User {
private Integer user_id;
private String user_name;
private String user_pwd;
}
3.编写yml
server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/数据库名?characterEncoding=UTF-8&serverTimezone=GMT%2B8 username: 账号 password: 密码 driver-class-name: com.mysql.jdbc.Driver //用于mapper.xml文件 mybatis: mapper-locations: classpath:/mapper/*.xml
4.dao和mapper文件的编写
@Mapper
@Repository
public interface UserDao {
@Select("select * from user")
List<User> findAll();
@Select("select * from user where user_id=#{user_id}")
User findById(@Param("user_id") Integer user_id);
@Insert("insert into user values(null,#{user_name},#{user_pwd})")
int addUser(User user);
@Delete("delete from user where user_id=#{user_id}")
int deleteUser(@Param("user_id") Integer user_id);
@Update("update user set user_name=#{user_name},user_pwd=#{user_pwd} where user_id=#{user_id}")
int updateUser(User user);
int delUser(@Param("ids")Integer...ids);
}
UserMapper.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.chen.springboottest.dao.UserDao"> <!-- int delUser(@Param("ids")Integer...ids);--> <delete id="delUser"> delete from user where user_id in <foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach> </delete> </mapper>
5.测试
@SpringBootTest
class SpringboottestApplicationTests {
@Autowired
private UserDao userDao;
@Test
void contextLoads() {
}
@Test
void findAll(){
List<User> all = userDao.findAll();
for(User u:all){
System.out.println(u);
}
}
@Test
void findById(){
User byId = userDao.findById(23);
System.out.println(byId);
}
@Test
void addUser(){
User user = new User(null,"sun","123123");
int i = userDao.addUser(user);
if(i>0){
System.out.println("添加成功");
}
}
@Test
void deleteUser(){
int i = userDao.deleteUser(23);
if(i>0){
System.out.println("删除成功");
}
}
@Test
void updateUser(){
User user = new User().setUser_name("jack").setUser_pwd("123123").setUser_id(11);
int i = userDao.updateUser(user);
if(i>0){
System.out.println("修改成功"+i);
}
}
@Test
void delUser(){
int i = userDao.delUser(11, 12, 13);
System.out.println(i);
}
}
整合springMVC和mybatis(小案例)
1.进行整合
2.yml配置
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/数据库名字?characterEncoding=utf-8&serverTimezone=UTC username: 账号 password: 密码 thymeleaf: prefix: classpath:/templates/pages/ suffix: .html mybatis: mapper-locations: classpath:/mapper/*.xml
3.相关数据准备
3.1实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Goods {
private Integer id;
private String name;
private String remark;
private Date createdTime;
}
@Mapper
@Repository
public interface GoodsDao {
@Select("select * from tb_goods")
List<Goods> findAll();
@Delete("delete from tb_goods where id=#{id}")
int deleteGoods(@Param("id") Integer id);
@Insert("insert into tb_goods values(null,#{name},#{remark},now())")
int addGoods(Goods goods);
//先找到id对应的数据 在进行修改
@Select("select * from tb_goods where id=#{id}")
Goods findById(@Param("id") Integer id);
@Update("update tb_goods set name=#{name},remark=#{remark} where id=#{id}")
int updateGoods(Goods goods);
}
3.3控制层
@Controller
public class GoodsController {
@Autowired
private GoodsDao goodsDao;
@RequestMapping("/GoodsAll")
public String findAll(Model model){
List<Goods> all = goodsDao.findAll();
model.addAttribute("list",all);
return "index";
}
@RequestMapping("/GoodsDel")
public String deleteGoods(Integer id){
goodsDao.deleteGoods(id);
return "redirect:GoodsAll";
}
@RequestMapping("/GoodAdd")
public String addGoods(Goods goods){
// goodsDao.addGoods(goods);
// return "redirect:GoodsAll";
//根据id进行判断 为空就进行添加 不为空就进行修改操作
if(goods.getId()==null){
goodsDao.addGoods(goods);
}else {
goodsDao.updateGoods(goods);
}
return "redirect:GoodsAll";
}
@RequestMapping("/GoodById")
public String findById(Integer id,Model model){
Goods byId = goodsDao.findById(id);
//将获取的id带过去 这里的goods为index.html中 获取对应值
model.addAttribute("goods",byId);
//当点击修改时 主页面要显示所有数据 这里的list为主页信息显示循环需要的
model.addAttribute("list",goodsDao.findAll());
return "index";
}
}
4.主页数据显示index.html
这里的循环使用的是Thymeleaf模板中的
如果resources下的templates不进行分级 则html放在templates下面直接被解析
进行分级则要告诉指定的对应位置
补充:Thymeleaf语法
th:text在页面输出值
th:value 将一个值放入input 标签的value中
日期格式转换
<td th:text="${#dates.format(c.createdTime,'yyyy-MM-dd HH:mm')}"></td>
迭代遍历
<tr th:each="c:${list}">
<td th:text="${c.id}"></td>
<td th:text="${c.name}"></td>
<td th:text="${c.remark}"></td>
<!-- <td th:text="${c.createdTime}"></td>-->
<!-- ${#dates.format(orderDetail.startTime,'yyyy-MM-dd HH:mm:ss')}-->
<td th:text="${#dates.format(c.createdTime,'yyyy-MM-dd HH:mm')}"></td>
<td><a th:href="@{/delG(id=${c.id})}">删除</a></td>
<td><a th:href="@{/updG(id=${c.id})}">修改</a></td>
</tr>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<form action="/GoodAdd">
<li><input type="hidden" name="id" th:value="${goods!=null?goods.id:''}"></li>
<li>name</li>
<li><input type="text" name="name" th:value="${goods!=null?goods.name:''}"></li>
<li>remark</li>
<li><input type="text" name="remark" th:value="${goods!=null?goods.remark:''}"></li>
<li><input type="submit" value="提交"></li>
</form>
</div>
<table>
<thead>
<tr>
<td>id</td>
<td>name</td>
<td>remark</td>
<td>createdTime</td>
</tr>
</thead>
<tbody>
<!-- 这里的list为GoodsController中model带过来的-->
<tr th:each="c:${list}">
<td th:text="${c.id}"></td>
<td th:text="${c.name}"></td>
<td th:text="${c.remark}"></td>
<td th:text="${c.createdTime}"></td>
<td><a th:href="@{/GoodsDel(id=${c.id})}">删除</a></td>
<td><a th:href="@{/GoodById(id=${c.id})}">修改</a></td>
</tr>
</tbody>
</table>
</body>
</html>
三 .发送Ajax请求
ajax作用 异步加载---->提高响应 局部刷新
必写的参数
url data 回调函数(success error)
这里以上面整合springMVC和mybatis(小案例)为例子进行测试
1.引入js(resources/static/ajax)
jquery-3.6.0.min.js
2.controller代码修改
@Controller
public class GoodsController {
@Autowired
private GoodsDao goodsDao;
@RequestMapping("/ajax")
public String ajaxreq(){
return "ajaxreq";
}
@RequestMapping("/GoodsAll")
@ResponseBody
public List<Goods> findAll(Model model){
return goodsDao.findAll();
}
@RequestMapping("/GoodAdd")
@ResponseBody
public String addGoods(Goods goods){
int i = goodsDao.addGoods(goods);
if(i==0){
return "add error";
}else {
return "add ok";
}
}
}
3.ajaxreq.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/ajax/jquery-3.6.0.min.js"></script>
<script>
function doGet() {
var url="/GoodsAll";
var param="";
$.get(url,param,function(result){
console.log(result)
})
}
//对服务端返回的数据进行json方式处理
function doGetJson() {
var url="/GoodsAll";
var param="";
$.getJSON(url,param,function (result) {
console.log(result)
})
}
function doPost() {
var url="/GoodAdd";
var param="name=张曼玉&remark=BEAUTY&createdTime=2023/1/25 20:24:00";
$.post(url,param,function (result) {
alert(result)
})
}
function doAjax() {
$.ajax({
type:"POST",
url:"/GoodsAll",
data:"",
dataType:"JSON",
async:"true",
contentType:"text/plain",
success:function (result) {
console.log(result)
}
});
}
function doLoad() {
var url="/GoodsAll";
var param="";
$("#context").load(url,param,function (result) {
console.log("load完成")
})
}
</script>
</head>
<body>
<h3>我是用来发送ajax请求</h3>
<div id="context"></div>
<div>
<button onclick="doGet()">get()</button>
<button onclick="doGetJson()">getJson()</button>
<button onclick="doPost()">post()</button>
<button onclick="doAjax()">ajax()</button>
<button onclick="doLoad()">load()</button>
</div>
</body>
</html>
ajax请求将数据在页面显示
这里依旧通过上面整合springMVC和mybatis(小案例)为例子进行测试(此处的修改操作存在部分问题 )
1.controller
package com.chen.springholidaymvc.controller;
import com.chen.springholidaymvc.dao.GoodsDao;
import com.chen.springholidaymvc.pojo.Goods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class GoodsController {
@Autowired
private GoodsDao goodsDao;
@RequestMapping("/indexAjax")
public String indexAjax(){
return "index02";
}
@RequestMapping("/GoodsAll")
@ResponseBody
public List<Goods> findAll(Model model){
return goodsDao.findAll();
}
@RequestMapping("/GoodsDel")
public String deleteGoods(Integer id){
goodsDao.deleteGoods(id);
return "redirect:indexAjax";
}
@RequestMapping("/GoodAdd")
@ResponseBody
public String addGoods(Goods goods){
//根据id进行判断 为空就进行添加 不为空就进行修改操作
if(goods.getId()==null){
goodsDao.addGoods(goods);
}else {
goodsDao.updateGoods(goods);
}
return "redirect:indexAjax";
}
@RequestMapping("/GoodById")
public String findById(Integer id,Model model){
Goods byId = goodsDao.findById(id);
return "redirect:indexAjax";
}
}
2.index02.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>this is my page</h1>
<h3>通过ajax将数据展示到页面</h3>
<form>
<div>
<div>
name:<input type="text" id="getName" name="name" placeholder="name" >
</div>
<div>
remark:<input type="text" id="getRemark" name="remark" placeholder="remark">
</div>
<button onclick="doAdd()">提交</button>
</div>
</form>
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>remark</th>
<th>createdTime</th>
</tr>
</thead>
<!-- 这里的tbody为后面数据显示提供位置-->
<tbody id="tbodyText">
<tr>
<td colspan="4">数据在加载...</td>
</tr>
</tbody>
</table>
<!-- 引入js标签 注意不要将script进行分行-->
<script src="/ajax/jquery-3.6.1.min.js"></script>
<script>
//用于查询所有
function findGoodsAll() {
// var url="/GoodsAll";
// var param="";
// $.getJSON(url,param,function (result) {
// doHandler(result)
// })
$.ajax({
type:"POST",
url:"/GoodsAll",
data:"",
dataType:"JSON",
async:"true",
contentType:"text/plain",
success:function (result) {
doHandler(result)
}
})
}
//对数据存放位置进行处理
function doHandler(result) {
//清空内容
var tbodyText=$("#tbodyText")
tbodyText.empty()
//进行遍历 通过result 传入接收查询所有的数据
for(let i=0;i<result.length;i++){
var tr=`
<tr>
<td>${result[i].id}</td>
<td>${result[i].name}</td>
<td>${result[i].remark}</td>
<td>${result[i].createdTime}</td>
<td><a onclick="deleteById(${result[i].id})">删除</a></td>
<td><a onclick="updateById(${result[i].id})">修改</a></td>
</tr>
`;
//将数据进行添加
tbodyText.append(tr)
}
}
//通过id进行删除 为删除做准备
function deleteById(id) {
console.log("当前id为:"+id)
var url="/GoodsDel";
var param="id="+id;
$.post(url,param,function (result) {
//findGoodsAll 删除后数据在当前页面显示
findGoodsAll()
})
}
//做添加操作处理
function doAdd() {
//获取表单中的数据
var name=$("#getName").val();
var remark=$("#getRemark").val();
var url="/GoodAdd";
//这里进行拼接时 记得添加&
var param="name="+name+"&remark="+remark;
$.post(url,param,function () {
findGoodsAll();
})
}
//进行修改
function updateById(id) {
//获取表单中的数据
var name=$("#getName").val();
var remark=$("#getRemark").val();
var url="/GoodById";
//这里进行拼接时 记得添加&
var param="name="+name+"&remark="+remark;
$.post(url,param,function () {
findGoodsAll();
})
}
//调用方法 在页面上显示
findGoodsAll();
</script>
</body>
</html>