中缀,后缀,前缀表达式的计算以及转化详解

本文详细阐述了中缀表达式的计算、转换为后缀表达式、后缀表达式的计算、中缀转前缀及前缀表达式的计算过程,通过实例代码深入解析了栈在这些算法中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据结构正好学到栈,中缀,前缀,后缀表达式把人绕的不行,写一个博客也算是总结一下这5个算法:中缀表达式的计算中缀表达式转后缀表达式后缀表达式计算中缀表达式转前缀表达式前缀表达式计算

中缀表达式的计算

思路:
首先设立两个栈,一个operator(运算符)栈,一个operand(运算数)栈。输入数字进入operand栈,输入运算符进入operator栈,表达式以’#‘开始和结束。
对于字符进栈,需要比较当前输入的字符和operator栈顶字符的优先级大小:若当前运算符优先级高于栈顶运算符,则当前运算符进栈;若当前运算符优先级低于栈顶运算符,则栈顶运算符出栈,并且operand栈顶的两个运算符也出栈,三者进行运算后的结果再次存入operand运算数栈。此时的当前运算符再继续和栈顶运算符比较,直到优先级大于栈顶运算符为止。
当两个’#'相遇时,也就是表达式结束是,读取operand栈的栈顶元素的值,即为中缀表达式的值。

代码共设12个函数:
(1)两个栈的基本操作6个函数:Init(),Push(),Pop()
(2)判断字符是否为数字的函数 In(char ch)
(3)获取数字栈栈顶元素的函数GetTop1(Operand S)
(4)获取运算符栈栈顶元素的函数GetTop2(Operator S)
(5)比较栈顶运算符和当前运算符优先级的函数Compare(Operator S,char ch)
(6)计算pop出的运算符和两个运算数的函数Execute(int a,int b,char op)
(7)计算中缀表达式的值的函数 ExpEvaluation()

在这里我使用了一个二维数组来存储运算符的优先级,需要注意的是要搞清行和列哪一个是当前运算符,哪一个是栈顶运算符

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MAXSIZE 100
char A[7] = {'+','-','*','/','(',')','#'};
char B[7][7] = {
    {'>','>','<','<','<','>','>'},
    {'>','>','<','<','<','>','>'},
    {'>','>','>','>','<','>','>'},
    {'>','>','>','>','<','>','>'},
    {'<','<','<','<','<','=','!'},
    {'>','>','>','>','!','>','>'},
    {'<','<','<','<','<','!','='}
};

typedef struct
{
    int* elem;
    int top;
}Operand;//运算数栈
typedef struct
{
    char* elem;
    int top;
}Operator;//运算符栈
void Init_Operand(Operand* S)//初始化数字栈
{
    S->elem = (int*)malloc(sizeof(int)*MAXSIZE);
    S->top = -1;
    if(S->elem == NULL)
    {
        printf("内存分配失败!\n");
        exit(-1);
    }
    else
        printf("内存分配成功!\n");
}
void Push_Operand(Operand* S,int x)//数字x进栈
{
    if(S->top == MAXSIZE-1)
    {
        printf("栈满!\n");
        exit(-1);
    }
    else
    {
        S->top++;
        S->elem[S->top] = x;
        printf("%d\n",S->elem[S->top]);
        printf("入栈成功!\n");
    }
}
void Pop_Operand(Operand* S,int *x)//数字出栈,将值存储在x中
{
    if(S->top<0)
    {
        printf("栈空!\n");
        exit(-1);
    }
    else
    {
        *x = S->elem[S->top];
        S->top--;
        printf("%d\n",*x);
        printf("出栈成功!\n");
    }
}
void Init_Operator(Operator* S)//初始化运算符栈
{
    S->elem = (char*)malloc(sizeof(char)*MAXSIZE);
    S->top = -1;
    if(S->elem == NULL)
    {
        printf("内存分配失败!\n");
        exit(-1);
    }
    else
        printf("内存分配成功!\n");
}
void Push_Operator(Operator* S,char ch)//运算符ch进栈
{
    if(S->top == MAXSIZE-1)
    {
        printf("栈满!\n");
        exit(-1);
    }
    else
    {
        S->top++;
        S->elem[S->top] = ch;
        printf("%c",S->elem[S->top]);
        printf("进栈成功!\n");
    }
}
void Pop_Operator(Operator* S,char* ch)//运算符ch出栈,将值储存在ch中
{
    if(S->top<0)
    {
        printf("栈空!\n");
        exit(-1);
    }
    else
    {
        *ch = S->elem[S->top];
        S->top--;
        printf("%c",*ch);
        printf("出栈成功!\n");
    }
}
bool In(char ch)//判断字符ch是否为数字,不是的话返回true,是的话返回false
{
    for(int i=0;i<7;i++)
    {
        if(ch == A[i])
            return true;
    }
    return false;
}
int GetTop1(Operand S)//获取数字栈栈顶运算符的值
{
    int x;
    x = S.elem[S.top];
    return x;
}
char GetTop2(Operator S)//获取字符栈栈顶运算符的值
{
    char ch;
    ch = S.elem[S.top];
    return ch;
}
char Compare(Operator S,char ch)//比较栈顶运算符和当前运算符的优先级
{
    int temp1,temp2;
    char c = GetTop2(S);//获取栈顶运算符
    for(int i=0;i<7;i++)
    {
        if(c==A[i])
            temp1 = i;//获取二维数组的行坐标
        if(ch==A[i])
            temp2 = i;//获取二维数组的列坐标
    }
    return B[temp1][temp2];
}
int Execute(int a,int b,char op)//b是先弹出的,a是后弹出的
{
    int v;
    switch(op)
    {
        case '+':v = a+b;break;
        case '-':v = a-b;break;
        case '*':v = a*b;break;
        case '/':v = a/b;break;
    }
    return v;
}
void ExpEvaluation()
{
    int value;
    char ch,op,x;
    int a,b;
    Operand s1;
    Operator s2;
    Init_Operand(&s1);//初始化数字栈
    Init_Operator(&s2);//初始化字符栈
    Push_Operator(&s2,'#');
    ch = getchar();
    while(ch!='#'||GetTop2(s2)!='#')
    {
        if(!In(ch))//不是执行运算符if
        {
            ch = ch - '0';
            Push_Operand(&s1,ch);
            fflush(stdin);//清空缓冲区
            ch = getchar();
        }
        else
        {
            switch(Compare(s2,ch))
            {
                case '<':
                //栈顶运算符优先级低于当前运算符,入栈
                    {
                        Push_Operator(&s2,ch);
                        fflush(stdin);
                        ch = getchar();
                    }break;
                case '>':
                //栈顶运算符优先级高于当前运算符,出栈
                    {
                        Pop_Operator(&s2,&op);
                        Pop_Operand(&s1,&b);
                        Pop_Operand(&s1,&a);
                        value = Execute(a,b,op);
                        Push_Operand(&s1,value);
                    }break;
                case '=':
                    {
                        Pop_Operator(&s2,&x);
                        fflush(stdin);
                        ch = getchar();
                    }break;
            }
        }
    }
    value = GetTop1(s1);
    printf("中缀表达式的值为:%d",value);
}
int main()
{
    ExpEvaluation();
    return 0;
}

中缀表达式转后缀表达式并计算

思路:
设立一个运算符栈operator和一个字符数组,字符数组用来存储需要输出的字符(包括数字和运算符),operator栈用来比较当前运算符和栈顶运算符的优先级大小。同样表达式以‘#’开头和结尾。
输入若为数字直接存入字符数组,若为运算符则压入operator栈中,在入栈时,若当前运算符的优先级高于operator栈顶运算符,则当前运算符入栈;若当前运算符优先级低于operator栈顶运算符,则栈顶运算符出栈,进入字符数组中,当前运算符再继续与此时的栈顶运算符进行比较,直到当前运算符的优先级大于栈顶运算符为止。
对于括号,左括号‘(’直接入栈,当遇到右括号’)'时,不管优先级,开始将栈顶运算符按上面规律弹出,直到遇到左括号,将左括号弹出,然后读取下一个字符。
后缀表达式的计算很简单,只需要建立一个operand栈,当遇到数字则入栈,遇到字符,则弹出栈顶的两个元素进行计算后将结果入栈,依次循环。
代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MAXSIZE 100
char A[7] = {'+','-','*','/','(',')','#'};
char B[7][7] = {
    {'>','>','<','<','<','>','>'},
    {'>','>','<','<','<','>','>'},
    {'>','>','>','>','<','>','>'},
    {'>','>','>','>','<','>','>'},
    {'<','<','<','<','<','=','!'},
    {'>','>','>','>','!','>','>'},
    {'<','<','<','<','<','!','='}
};

typedef struct
{
    char* elem;
    int top;
}Operator;//存储运算符的栈operator
typedef struct
{
    char *elem;
    int top;
}Array;//定义一个数组的结构体类型,用来存储字符
typedef struct
{
    int* elem;
    int top;
}Operand;//用来计算后缀表达式的值的数字栈
void Init_Operator(Operator* S)
{
    S->elem = (char*)malloc(sizeof(char)*MAXSIZE);
    S->top = -1;
    if(S->elem == NULL)
    {
        printf("内存分配失败!\n");
        exit(-1);
    }
    else
        printf("内存分配成功!\n");
}
void Push(Operator* S,char ch)
{
    if(S->top == MAXSIZE-1)
    {
        printf("栈满!\n");
        exit(-1);
    }
    else
    {
        S->top++;
        S->elem[S->top] = ch;
        printf("%c\n",S->elem[S->top]);
        printf("入栈成功!\n");
    }
}
void Pop(Operator* S,char* ch)
{
    if(S->top<0)
    {
        printf("栈空!\n");
        exit(-1);
    }
    else
    {
        *ch = S->elem[S->top];
        S->top--;
        printf("%c\n",*ch);
        printf("出栈成功!\n");
    }
}
void Init_Array(Array* A)//初始化字符数组
{
    A->elem = (char*)malloc(sizeof(char)*MAXSIZE);
    A->top = -1;
    if(A->elem == NULL)
    {
        printf("内存分配失败!\n");
        exit(-1);
    }
    else
        printf("内存分配成功!\n");
}
void Add(Array* A,char ch)//因为只需要向字符数组中加入元素,故之定义add()
{
    if(A->top==MAXSIZE)
    {
        printf("栈满!\n");
        exit(-1);
    }
    else
    {
        A->top++;
        A->elem[A->top] = ch;
        printf("%c ",A->elem[A->top]);
        printf("入栈成功!\n");
    }
}
void Init_Operand(Operand* S)//初始化数字栈
{
    S->elem = (int*)malloc(sizeof(int)*MAXSIZE);
    S->top = -1;
    if(S->elem == NULL)
    {
        printf("内存分配失败!\n");
        exit(-1);
    }
    else
        printf("内存分配成功!\n");
}
void Push_Operand(Operand* S,int x)
{
    if(S->top==MAXSIZE-1)
    {
        printf("栈满!\n");
        exit(-1);
    }
    else
    {
        S->top++;
        S->elem[S->top] = x;
        printf("%d ",S->elem[S->top]);
        printf("内存分配成功!\n");
    }
}
void Pop_Operand(Operand* S,int *x)
{
    if(S->top<0)
    {
        printf("栈空!\n");
        exit(-1);
    }
    else
    {
        *x = S->elem[S->top];
        S->top--;
        printf("%d\n",*x);
        printf("出栈成功!\n");
    }
}
bool In(char ch)//是字符返回true,是数字返回false
{
    for(int i=0;i<7;i++)
    {
        if(ch==A[i])
            return true;
    }
    return false;
}
char GetTop(Operator S)
{
    char ch;
    ch = S.elem[S.top];
    return ch;
}
int Execute(int a,int b,char op)
{
    int v;
    switch(op)
    {
        case '+':v = a+b;break;
        case '-':v = a-b;break;
        case '*':v = a*b;break;
        case '/':v = a/b;break;
    }
    return v;
}
char Compare(char ch,Operator S)
{
    int temp1,temp2;
    char c;
    c = GetTop(S);
    for(int i=0;i<7;i++)
    {
        if(c==A[i])
            temp1 = i;
        if(ch==A[i])
            temp2 = i;
    }
    return B[temp1][temp2];
}
void print(char ch)
{
    if(In(ch))//是字符执行if语句
        printf("%c ",ch);
    else
        printf("%d ",ch);
}
void print_Array(Array A)
{
    for(int i=0;i<=A.top;i++)
    {
        printf("%c",A.elem[i]);
    }
}
void Calcul_Exp(Array A)//后缀表达式的计算
{
    int a,b,value;
    //char temp;
    Operand Stack;
    Init_Operand(&Stack);
    for(int i=0;i<=A.top;i++)
    {
        if(!In(A.elem[i]))//是数字,入栈
        {
            A.elem[i] = A.elem[i] - '0';
            Push_Operand(&Stack,A.elem[i]);
        }
        else//字符,故 pop it
        {
            Pop_Operand(&Stack,&b);
            Pop_Operand(&Stack,&a);
            value = Execute(a,b,A.elem[i]);
            Push_Operand(&Stack,value);
        }
    }
    Pop_Operand(&Stack,&value);
    printf("后缀表达式的值为:%d",value);
}
void Transfer()
{
    char ch,op;
    Operator Stack;
    Array A;
    Init_Array(&A);
    Init_Operator(&Stack);
    Push(&Stack,'#');
    ch = getchar();
    while(ch!='#')
    {
        if(!In(ch))//不是字符
        {
            Add(&A,ch);
            fflush(stdin);
            ch = getchar();
        }
        else//是字符
        {
            switch(Compare(ch,Stack))
            {
            case '<'://栈顶运算符优先级低于当前运算符
                {
                    Push(&Stack,ch);
                    fflush(stdin);
                    ch = getchar();
                }break;
            case '>'://栈顶运算符的优先级高于当前运算符
                {
                    if(GetTop(Stack)==')')
                        Pop(&Stack,&op);
                    else
                    {
                        Pop(&Stack,&op);
                        Add(&A,op);
                    }
                }break;
            case '=':
                {
                    Pop(&Stack,&op);
                    fflush(stdin);
                    ch = getchar();
                }break;
            }
        }
    }
    //printf("OK?\n");
    while(GetTop(Stack)!='#')
    {
        Pop(&Stack,&op);
        Add(&A,op);
    }
    print_Array(A);
    Calcul_Exp(A);
}
int main()
{
    Transfer();
    //Calcul_Exp();
    return 0;
}

中缀表达式转前缀表达式

思路:
首先应建立两个数组结构体,一个用来存储输入的中缀表达式,一个用来存储转化后的前缀表达式;再应建立一个运算符operator栈,用来判定运算符的优先级大小。
首先输入中缀表达式,将中缀表达式存放在一个字符数组中,再从右至左读取中缀表达式中的字符,若为数字则直接存放入前缀表达式数组中;若为字符,则需判定该字符与operator栈栈顶字符的优先级:若该字符优先级高于栈顶运算符,则该字符入栈,若低于,则栈顶运算符出栈,该字符再与此时的栈顶运算符比较,直到其优先级高于栈顶运算符为止。
对于右括号‘)’,应压入栈中;对于左括号‘(’,应依次将栈顶运算符弹出直到遇到右括号为止‘)’,值得注意的是,左括号和右括号都不需要进入前缀表达式数组中。
注:为了简便运算,我将运算符优先级表稍作调整

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MAXSIZE 100
char A[7] = {'+','-','*','/','(',')','#'};
char B[7][7] = {//此处对表做了一些修改
    {'>','>','<','<','>','<','>'},
    {'>','>','<','<','>','<','>'},
    {'>','>','>','>','>','<','>'},
    {'>','>','>','>','>','<','>'},
    {'<','<','<','<','>','=','!'},
    {'<','<','<','<','=','<','>'},
    {'<','<','<','<','<','<','='}
};

typedef struct
{
    char* elem;
    int top;
}Operator;
typedef struct
{
    char* elem;
    int top;
}Array;
void Init_Operator(Operator* S)
{
    S->elem = (char*)malloc(sizeof(char)*MAXSIZE);
    S->top = -1;
    if(S->elem == NULL)
    {
        printf("内存分配失败!\n");
        exit(-1);
    }
    else
        printf("内存分配成功!\n");
}
void Push(Operator* S,char ch)
{
    if(S->top == MAXSIZE-1)
    {
        printf("栈满!\n");
        exit(-1);
    }
    else
    {
        S->top++;
        S->elem[S->top] = ch;
        printf("%c\n",S->elem[S->top]);
        printf("入栈成功!\n");
    }
}
void Pop(Operator* S,char* ch)
{
    if(S->top<0)
    {
        printf("栈空!\n");
        exit(-1);
    }
    else
    {
        *ch = S->elem[S->top];
        S->top--;
        printf("%c\n",*ch);
        printf("出栈成功!\n");
    }
}
void Init_Array(Array* A)
{
    A->elem = (char*)malloc(sizeof(char)*MAXSIZE);
    A->top = -1;
    if(A->elem==NULL)
    {
        printf("内存分配失败!\n");
        exit(-1);
    }
    else
        printf("内存分配成功!\n");
}
void Add(Array* A,char ch)
{
    printf("这里呢?\n");
    if(A->top==MAXSIZE-1)
    {
        printf("栈满!\n");
        exit(-1);
    }
    else
    {
        A->top++;
        A->elem[A->top] = ch;
        printf("%c\n",A->elem[A->top]);
        printf("插入成功!\n");
    }
}
bool In(char ch)//是运算符返回true,是数字返回false
{
    for(int i=0;i<7;i++)
    {
        if(ch==A[i])
            return true;
    }
    return false;
}
char GetTop(Operator S)
{
    char ch;
    ch = S.elem[S.top];
    //printf("%c\n",ch);
    return ch;
}
char Compare(char ch,Operator S)
{
    char c;
    int temp1,temp2;
    c = GetTop(S);
    for(int i=0;i<7;i++)
    {
        if(c==A[i])
            temp1 = i;
        if(ch==A[i])
            temp2 = i;
    }
    //printf("%c\n",B[temp1][temp2]);
    return B[temp1][temp2];
}
void print(Array A)
{
    for(int i=A.top;i>=0;i--)
    {
        printf("%c",A.elem[i]);
    }
}
void Transfer()
{
    char ch,op,temp;
    Array A1,A2;
    int i=0;
    Operator Stack;
    Init_Array(&A1);
    Init_Array(&A2);
    Init_Operator(&Stack);
    Push(&Stack,'#');
    printf("请输入中缀表达式:\n");
    ch = getchar();
    while(ch!='#')
    {
        Add(&A1,ch);
        fflush(stdin);
        ch = getchar();
        i = A1.top;
    }
    print(A1);
       while(i>=0)
       {
          if(!In(A1.elem[i]))//是数字执行if语句
          {
             printf("第二步?\n");
             temp = A1.elem[i];
             Add(&A2,temp);
             i--;
          }
          else
          {
             switch(Compare(A1.elem[i],Stack))
             {
              case '<'://栈顶运算符优先级低于当前运算符
                {
                    Push(&Stack,A1.elem[i]);
                    i--;
                }break;
              case '>'://栈顶运算符优先级高于当前运算符
                {
                    Pop(&Stack,&op);
                    Add(&A2,op);
                }break;
              case '=':
                {
                    Pop(&Stack,&op);
                    i--;
                }break;
            }
        }
    }
    while(GetTop(Stack)!='#')
    {
        Pop(&Stack,&op);
        Add(&A2,op);
        printf("%c\n",op);
    }
    print(A2);
}
int main()
{
    Transfer();
    return 0;
}

前缀表达式的计算

思路:
首先建立一个operand栈,由于将中缀表达式转换为前缀后是将其存储在一个字符数组中的,则从左向右读取该数组中的元素,遇到数字进入operand栈,遇到运算符,则将栈顶的两个元素依次弹出与该运算符进行计算,结果再入operand栈。当前缀表达式数组扫描完成后,则operand栈顶的元素值即为前缀表达式的值。
代码:

//将这些语句插入上面代码即可运行
typedef struct
{
    int* elem;
    int top;
}Operand;
void Init_Operand(Operand* S)
{
    S->elem = (int*)malloc(sizeof(int)*MAXSIZE);
    S->top = -1;
    if(S->elem == NULL)
    {
        printf("内存分配失败!\n");
        exit(-1);
    }
    else
        printf("内存分配成功!\n");
}
void Push_Operand(Operand* S,int x)
{
    if(S->top==MAXSIZE-1)
    {
        printf("栈满!\n");
        exit(-1);
    }
    else
    {
        S->top++;
        S->elem[S->top] = x;
        printf("%d ",S->elem[S->top]);
        printf("内存分配成功!\n");
    }
}
void Pop_Operand(Operand* S,int *x)
{
    if(S->top<0)
    {
        printf("栈空!\n");
        exit(-1);
    }
    else
    {
        *x = S->elem[S->top];
        S->top--;
        printf("%d\n",*x);
        printf("出栈成功!\n");
    }
}
int Execute(int a,int b,char op)
{
    int v;
    switch(op)
    {
        case '+':v = a+b;break;
        case '-':v = a-b;break;
        case '*':v = a*b;break;
        case '/':v = a/b;break;
    }
    return v;
}
void Calcul_Exp(Array A)
{
    int a,b,value;
    Operand S;
    Init_Operand(&S);
    for(int i=0;i<=A.top;i++)
    {
        if(!In(A.elem[i]))//是数字执行if语句
        {
            A.elem[i] = A.elem[i] - '0';
            //printf("%d\n",A.elem[i]);
            //exit(-1);
            Push_Operand(&S,A.elem[i]);
        }
        else
        {
            Pop_Operand(&S,&b);
            Pop_Operand(&S,&a);
            value = Execute(a,b,A.elem[i]);
            Push_Operand(&S,value);
        }
    }
    Pop_Operand(&S,&value);
    printf("前缀表达式的值为:%d",value);
}
学习尚硅谷视频整理的文档 Spring Boot 1 1 Spring Boot入门 4 1.1 简介 4 1.2 微服务(martin fowler发表了一篇文章) 5 1.3 环境约束 7 1.4 第一个Spring Boot项目(jar):HelloWorld 8 1.5 入门案例详解 11 1.5.1 POM文件 11 1.5.2 主程序类,主入口类 12 1.6 使用Spring Initializer向导快速创建Spring Boot 16 2 Spring Boot配置 18 2.1 配置文件 18 2.2 YML语法 19 2.3 YML配置文件值获取 21 2.4 properties配置文件乱码问题 24 2.5 @ConfigurationProperties与@Value的区别 25 2.6 配置@PropertySource、@ImportResource、@Bean 27 2.7 配置文件占位符 30 2.8 Profile多环境支持 31 2.9 配置文件的加载位置 33 2.10 外部配置加载顺序 36 2.11 自动配置原理 37 2.12 @Conditional派生注解 41 3 Spring Boot与日志 42 3.1 日志框架分类和选择 42 3.2 SLF4j使用 43 3.3 其他日志框架统一转换成slf4j+logback 44 3.4 Spring Boot日志使用 45 3.5 Spring Boot默认配置 47 3.6 指定日志文件和日志Profile功能 52 3.7 切换日志框架(不使用SLF4j+LogBack) 54 4 Spring Boot与Web开发 55 4.1 Web开发简介 55 4.2 静态资源映射规则 56 4.3 引入Thymeleaf 60 4.4 Thymeleaf语法 61 4.5 SpringMVC自动配置原理 67 4.6 SpringBoot扩展与全面接管 70 4.7 如何修改SpringBoot的默认配置 72 4.8 【实验】CRUD操作 73 4.8.1 默认访问首页 73 4.8.2 登录页面国际化 74 4.8.3 登录 80 4.8.4 拦截器进行登录检查 81 4.8.5 实验要求(没按要求做,不想改了!) 82 4.8.6 CRUD-员工列表 83 4.8.7 CRUD-员工修改 86 4.8.8 CRUD-员工添加 87 4.8.9 CRUD-员工删除 88 4.9 错误处理原理&错误页面定制 90 4.10 配置嵌入式Servlet容器(springboot 1.50版本) 97 4.10.1 如何定制和修改Servelt容器的相关配置 97 4.10.2 注册servlet大组件【servlet,filter,listener】 98 4.10.3 替换为其他嵌入式容器 102 4.10.4 嵌入式servlet容器自动配置原理 103 4.10.5 嵌入式servlet容器启动原理 103 4.11 使用外置的Servlet容器 104 4.11.1 步骤 104 4.11.2 原理 107 5 Spring Boot与Docker(虚拟化容器技术) 110 5.1 简介 110 5.2 核心概念 111 5.3 安装Docker 112 5.4 Docker常用命令&操作 113 5.5 安装MySQL示例 114 6 Spring Boot与数据访问 115 6.1 JDBC 115 6.1.1 实现 115 6.1.2 自动配置原理 116 6.2 整合Durid数据源 117 6.3 整合Mybatis 122 6.3.1 注解版 123 6.3.2 配置文件版 124 6.4 整合SpringData JPA 125 6.4.1 SpringData简介 125 6.4.2 整合 126 7 Spring Boot启动配置原理 128 7.1 启动流程(Springboot 1.50版本) 128 7.1.1 创建SpringApplication对象 129 7.1.2 运行run方法 130 7.1.3 编写事件监听机制 132 8 Spring Boot自定义starters 136 8.1 概述 136 8.2 步骤 137 9 更多Springboot整合示例 144 10 Spring Boot与缓存 145 10.1 JSR107缓存规范 145 10.2 Spring的缓存抽象 146 10.2.1 基本概念 146 10.2.2 整合项目 146 10.2.3 CacheEnable注解 148 10.2.4 Cache注解 150 10.3 整合redis 154 10.3.1 在Docker上安装redis 154 10.3.2 Redis的Template 154 10.3.3 整合(百度) 155
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值