SpringMVC入门案例工作流程
概述我们现在的Web程序大都基于MVC三层架构来实现的
如果所有的处理都交给 Servlet来处理的话,所有的东西都耦合在一起,对后期的维护和扩展极其不利
所以将后端服务器 Servlet拆分成三层,分别是 web、service和 dao
web层主要由 servlet来处理,负责页面请求和数据的收集以及响应结果给前端
service层主要负责业务逻辑的处理
dao层主要负责数据的增删改查操作
但 servlet处理请求和数据时,存在一个问题:一个 servlet只能处理一个请求
针对 web层进行优化,采用MVC设计模式,将其设计为 Controller、View和 Model
controller负责请求和数据的接收,接收后将其转发给 service进行业务处理
service根据需要会调用 dao对数据进行增删改查
dao把数据处理完后,将结果交给 service,service再交给 controller
controller根据需求组装成 Model和 View,Model和 View组合起来生成页面,转发给前端浏览器
这样做的好处就是 controller ...
复杂链表的复制
题目:请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
示例1:
示例2:
示例3:
示例4:
提示:
-10000 <= Node.val <= 10000
Node.random 为空(null)或指向链表中的节点。
节点数目不超过 1000 。
解题思路复制拼接+拆分链表
考虑构建 原节点 1 -> 新节点 1 -> 原节点 2 -> 新节点 2 -> …… 的拼接链表,如此便可在访问原节点的 random 指向节点的同时找到新对应新节点的 random 指向节点。
图例
复制各节点,构建拼接链表:
构建新链表各节点的 random 指向:
拆分原 / 新链表:
返回新链表的头节点 res 即可
题解:/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
...
Spring AOP
AOP1. 场景模拟1.1 声明接口声明计算器接口Calculator,包含加减乘除的抽象方法
public interface Calculator {
int add(int i, int j);
int sub(int i, int j);
int mul(int i, int j);
int div(int i, int j);
}
1.2 创建实现类
public class CalculatorPureImpl implements Calculator {
@Override
public int add(int i, int j) {
int result = i + j;
System.out.println("方法内部 result = " + result);
return result;
}
@Override
public int sub(int i, int j) {
int result = i - j;
...
SpringMVC获取请求参数的几种方式
SpringMVC获取请求参数1. 通过ServletAPI获取将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象
@RequestMapping("/testParam")
public String testParam(HttpServletRequest request){
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username:"+username+",password:"+password);
return "success";
}
2. 通过控制器方法的形参获取请求参数在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,在DispatcherServlet中就会将请求参数赋值给相应的形参
<a th:h ...
反转链表
题目:
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点示例:
输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL限制:0 <= 节点个数 <= 5000
做题思路:事先保存每个节点的前一个节点,随后在我们遍历链表的过程中,需要将当前节点的next 指针改为指向它的前一个节点
解题步骤:
设置两个指针,curr 指向链表头节点,pre 指向空
暂存 curr 的后继节点,next = curr.next
将 curr.next 反指向pre
将 pre 指向 curr,即 pre 指针后移
将 curr 指向 2 中暂存的 next 节点,即 curr 指针后移 循环 第2 到 5 步,直到 curr 遍历完整个链表
图解:
题解/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ...
从尾到头打印链表
题目:
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)示例:
输入:head = [1,3,2]输出:[2,3,1]
限制:0 <= 链表长度 <= 10000
做题思路:计算长度创建数组,再逆向赋值
题解:/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int[] reversePrint(ListNode head)
{
ListNode node = head;
int count = 0;
while(node!=null)
{
count++;
node = ...
包含min函数的栈
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
示例:MinStack minStack = new MinStack();minStack.push(-2);minStack.push(0);minStack.push(-3);minStack.min(); –> 返回 -3.minStack.pop();minStack.top(); –> 返回 0.minStack.min(); –> 返回 -2.提示:各函数的调用总次数不超过 20000 次
思路:可以在每个元素 n 入栈时把当前栈的最小值 m 存储起来。在这之后无论何时,如果栈顶元素是 n,我们就可以直接返回存储的最小值 m。
算法:按照上面的思路,我们只需要设计一个数据结构,使得每个元素 a 与其相应的最小值 m 时刻保持一一对应。因此我们可以使用一个辅助栈,与元素栈同步插入与删除,用于存储与每个元素对应的最小值。
当一个元素要入栈时,我们取当前辅助栈的栈顶存储的最小值,与当 ...
RequestMapping注解
@RequestMapping注解1. @RequestMapping注解的功能从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求。
2. @RequestMapping注解的位置
@RequestMapping标识一个类:设置映射请求的请求路径的初始信息@RequestMapping标识一个方法:设置映射请求请求路径的具体信息
@Controller
@RequestMapping("/test")
public class RequestMappingController {
//此时请求映射所映射的请求的请求路径为:/test/testRequestMapping
@RequestMapping("/testRequestMapping")
public String testRequestMapping(){
return "success";
}
}
3. @RequestMapp ...
resultMap和resultType的使用
1. resultType该属性就是返回的类型,就是将resultType查询到的结果映射封装成pojo类型中,前提是该pojo类的属性名和查询到的数据库表的字段名一致。这种映射封装mybatis帮我们自动做好了,不需要我们自己考虑。
使用场景:
如果只是返回一个值,比如说String或者int,那直接用resultType就行了<mapper namespace="mapper.StudentMapper">
<select id = "selectStudent" resultType="hashmap">
select * from student
</select>
<mapper>
如果sql查询结果返回的列名和实体类中的字段名一致,可以使用resultType,MyBatis会自动把查询结果赋值给和字段名一致的字段
如若不一致也可以通过起别名的方式使其一致
2. resultMapresultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和lis ...
用两个栈实现队列
题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
示例 1:
输入:
["CQueue","appendTail","deleteHead","deleteHead","deleteHead"]
[[],[3],[],[],[]]
输出:[null,null,3,-1,-1]
示例 2:
输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]
提示:
1 <= values <= 10000
最多会对 appendTail、deleteHead<span> </span>进行 10000 次调用
题解思路将一个栈当作输入栈, ...
MyBatis的增删改查
1.MyBatis的基本增删改查1.1、新增<!--int insertUser();-->
<insert id="insertUser">
insert into t_user values(null,'admin','123456',23,'男')
</insert>
1.2、删除<!--int deleteUser();-->
<delete id="deleteUser">
delete from t_user where id = 7
</delete>
1.3、修改<!--int updateUser();-->
<update id="updateUser">
update t_user set username='ybc',password='123' where id = 6
</update>
1.4、查询一个实体类对象<!--User getUserById();-->
<select id="getUserById" res ...
Mybatis的搭建过程
搭建MyBatis1、开发环境IDE:idea 2019.2
构建工具:maven 3.5.4
MySQL版本:MySQL 8
MyBatis版本:MyBatis 3.5.7
MySQL不同版本的注意事项1、驱动类driver-class-nameMySQL 5版本使用jdbc5驱动,驱动类使用:com.mysql.jdbc.DriverMySQL 8版本使用jdbc8驱动,驱动类使用:com.mysql.cj.jdbc.Driver
2、连接地址urlMySQL 5版本的url:jdbc:mysql://localhost:3306/ssmMySQL 8版本的url:jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC否则运行测试用例报告如下错误:java.sql.SQLException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized orrepresents more
2、创建maven工程
打包方式:jar
引入依赖
<dependencies& ...