Spring Boot 整合 SSM的简单操作

SpringBoot的主要功能如下:

- 起步依赖:SpringBoot以功能化的方式将需要的依赖进行组装,并且允许程序员以start的方式进行引入
- 默认配置:SpringBoot实现了大量依赖框架的默认配置项,程序员无须再进行自己配置
- 内置Tomcat:SpringBoot内置了一个tomcat,使用它开发的程序无需再进行tomcat部署,可直接运行

创建工程,导入依赖

注意: springboot工程要求必须去继承一个springboot提供的父工程,然后根据业务需要引入指定的starter

<!--父工程-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
    </parent>


<dependencies>
        <!--JDK11中没有的一些xml解析的依赖-->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>

        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>

        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0</version>
        </dependency>

        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

        <!--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.2.2</version>
        </dependency>

        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--springboot单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--mybatis分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.2</version>
        </dependency>
    </dependencies>

创建启动类

//注意启动类的位置,必须位于其他类的父包中

@SpringBootApplication
@MapperScan("com.itheima.mapper")//接口扫描
public class SpringBootDemoApplication {

    public static void main(String[] args){
        SpringApplication.run(SpringBootDemoApplication.class,args);
    }

}

实体类

实体类解决时间格式问题

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private Long id;
    private String number;
    private String userName;
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
    private Date birthday;
    private String address;

}

先使用三层架构写法(面向接口编程)

表示层(web):主要接收前端发送的请求,并响应数据=======>controller

业务层(service): 负责处理具体的业务逻辑=======>service

持久层(dao): 负责对数据库进行增删改查操作========>dao 或 mapper

java文件的命名方式也是domain包的实体类名+对应层的后缀。

service还要创建对应的实现类在业务层Impl包下,名字可以Impl结尾。

比如: domain = User mapper = UserMapper

分别在你的每层上面加上与之对应的实例化注解

@Component

用于实例化对象,它支持一个value属性类定义bean在容器中的唯一标识

如果不写,默认值为类名的首字母小写

@Controller @Service @Repository

这三个注解的功能跟@Component类似,他们分别标注在不同的层上。

@RestController 标注在表示层的类上

@Service 标注在业务层的类上

@Mapper 标注在持久层的类上

推荐使用这三个,当一个类实在不好归属在这三个层上时,再使用@Component

在yaml文档里配置数据源、开启驼峰映射、日志等操作。

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/tlias
    username: root
    password: 1234


mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    #开启驼峰映射
    map-underscore-to-camel-case: true

在dao层接口类写入CRUD方法,在Service层的接口和它实现类中写入CRUD,实现类的重写方法中

利用@Autowired依赖注入获取dao层接口类的对象达到调用方法的作用。

使用@Autowired依赖注入可以在实现类中获取IOC容器中的对象

@Autowired注解,默认是按照类型进行属性的赋值,如果存在多个相同类型的bean,就会报错

@Qualifier(实现类的name)跟@Autowired联合使用,标注在要赋值的属性上,代表在按照类型匹配的基础上,再按照指定名称匹配

@Primary标注在实现类上,表示当一个接口有多个实现的类时,默认使用哪个作为主实现

写controller类要遵守的一些约定

在写controller类的CRUD时候,类名上最好使用@RestController注解,为什么呢?

@RestController = @Controller + @ResponseBody

使用@Autowired注解,在你的controller类中获取service层对象,

然后方法满足Restful规范

保存 @postMapping /user

修改 @putMapping /user/id/1

删除 @DeleteMapping /user/id

查询所有 @GetDeleteMapping /user

查询一个 @GetDeleteMapping /user/id

方法的返回值,还要满足和前端看的懂的形式。

单独写一个类方法vo包下,作为返回的对象。

实现CRUD

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
    private Integer code;//响应码,1 代表成功; 0 代表失败
    private String msg;//响应信息 描述字符串
    private Object data;//返回的数据

    //增删改 成功响应
    public static Result success(){
        return new Result(1,"success",null);
    }
    //查询 成功响应
    public static Result success(Object data){
        return new Result(1,"success",data);
    }
    //失败响应
    public static Result error(String msg){
        return new Result(0,msg,null);
    }
}

Controller类

@RestController
public class StudentController {

    @Autowired
    private StudentService studentService;
	//查询全部
    @GetMapping("/student")
    public Result findAll(){
        List<Student> studentList = studentService.findAll();
        return Result.success(studentList);
    }
	//删除
    @DeleteMapping("/student/{id}")
    public Result deleteById(@PathVariable("id") Long id){
        studentService.deleteById(id);
        return Result.success();
    }
	//查找一个
    @GetMapping("/student/{id}")
    public Result findById(@PathVariable("id") Long id){
        Student byId = studentService.findById(id);
        return Result.success(byId);
    }
	//修改
    @PutMapping("/student")
    public Result updateById(@RequestBody Student student){
        studentService.updateById(student);
        return Result.success();
    }
	//增加
    @PostMapping("/student")
    public Result add(@RequestBody Student student){
        studentService.add(student);
        return Result.success();
    }

}
404 路径问题

405 请求方式错误

400 请求参数错误

500 后台错误

200 成功

还是要根据实际情况写。

无条件分页查询

-- 总结: 查询第page页,每页pageSize条 select * from emp limit (page-1)*pageSize,pageSize;

添加依赖
<!--mybatis分页插件-->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.4.2</version>
</dependency>
示例代码:
PageBean类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean<T> {
    //数据的总数
    //private Long total;
    private Long total;
    //每页返回的数据
    //private List<T> rows;
    private List<T> rows;
}

dao层

@Select("select * from emp")
public List<Emp> list();

service实现类

@Override
public PageBean<Emp> findByPage(Integer page, Integer pageSize) {
    //1 设置分页参数
    PageHelper.startPage(page,pageSize);
    //2 执行查询
    List<Emp> empList = empMapper.list();
    //3 查询结果转Page对象
    Page<Emp> p = (Page<Emp>) empList;
    //4 封装对象查询
    return new PageBean<Emp>(p.getTotal(),p.getResult());

controller层

@GetMapping("/emps")
public Result findByPage(
    	//分页查询的页码,如果未指定,默认为1
        @RequestParam(defaultValue = "1") Integer page,
        @RequestParam(defaultValue = "10") Integer pageSize
){
    PageBean<Emp> pageBean = empService.findByPage(page,pageSize);
    return Result.success(pageBean);
}

带条件分页查询

dao层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.itheima.mapper.EmpMapper">
    <select id="findList3" resultType="com.itheima.pojo.Emp">
        select * from emp
        <where>
            <if test="name != null and name != ''">
                and name like concat("%",#{name},"%")
            </if>
            <if test="gender != null">
                and gender = #{gender}
            </if>
            <if test="begin != null and end != null">
                and entrydate between #{begin} and #{end}
            </if>
        </where>
    </select>
</mapper>

SpringAOP优化代码

AOP

AOP是一种思想,把核心和非核心的业务代码进行分离,解耦合。

还能再原有的基础上进行额外的操作。

如果有接口,就采用jdk动态代理

如果没接口,就采用cglib的方式

Spring AOP(面向切面编程)

Spring Aop 底层基于jdk动态代理和cglib动态代理。

当我们需要在核心代码增加一个非核心功能时,可以单独给这个非核心功能写一个增强类里,并且加上@Aspect//切面注解

在增强类中写一个切点(切点表达式)----->\作用:可以标注在要增强的方法上面。

//切点表达式

 //@Pointcut("execution( com.itheima.service.Impl..(..))")

 @Pointcut("@annotation(com.itheima.annotation.LogAnno)")//自定义切点

  public void pt(){}

AOP获取目标对象

@Aspect
@Component
public class MyAop {
    //切点:controller所有方法
    @Pointcut("execution (* com.itheima.controller.*.*(..))")
    public void myPointcut(){

    }

    @Around("myPointcut()")
    public Object m1(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        //被切方法只有一个参数
        if (args.length==1 && args[0] instanceof Emp){
            Emp emp = (Emp) args[0];
            emp.setUpdateTime(LocalDateTime.now());
        }

        Object object = pjp.proceed();

        return object;
    }
}

AOP使用日志技术统计方法前后所费的时间

日志在yml文件如何配置?

# 设置                      输出
# debug                     debug  info  warn  error
# info                      info  warn  error
# warn                      warn  error
# error                     error

logging:
  level: #指定每个包下来要记录的日志级别
    com.itheima:info
  file: #制定日志输出路径文件
    name: D:\springboot.log
@Aspect
@Component
@Slf4j
public class LogAop {
	//切点:controller所有方法
    @Pointcut("execution(* com.itheima.controller.*.*(..))")
    public void logAop(){}

    @Around("logAop()")
    public Object m1(ProceedingJoinPoint pjp) throws Throwable {

        Object obj = null;
        long start = System.currentTimeMillis();
        String format1 = new SimpleDateFormat("HH:mm:ss").format(start);
        log.info(format1);
        obj=pjp.proceed();
        long end = System.currentTimeMillis();
        String format2 = new SimpleDateFormat("HH:mm:ss").format(end);
        log.info(format2);
        log.info(String.valueOf(end-start)+"ms");
        return obj;

    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值