java后端第六阶段:SpringMVC

news2024/11/29 9:59:17

1、Spring

IoC(Inversion of Controller)控制反转

        使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象中创建控制权由程序转移到外部,此思想称为控制反转

Spring技术对IoC思想进行了实现

        Spring提供了一个容器,称为IOC容器,用来充当IOC思想的外部

        IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean

DI(Dependency Injection)依赖注入

        在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入

1.1、IoC入门案例

导入Spring坐标

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.23</version>
</dependency>

创建UserService接口,和UserServiceImpl的实现类  

public interface UserService {
    void save();
}

public class UserServiceImpl implements UserService {
    @Override
    public void save() {
        System.out.println("user running...");
    }
}

创建Spring的配置文件   ----  resourse下右键new ---> XMLConfiguration File--->Spring Config --->applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 1.导入spring的坐标spring-context  -->
    <!-- 2.配置bean-->
    <!-- bean标签标示配置bean id属性标识给bean起的名字 class属性标识给bean定义类型-->
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"></bean>
</beans>

新建测试类

public static void main(String[] args) {
    //3.获取IoC容器
    ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    //4.获取bean
    UserService userService =(UserService) app.getBean("userService");
    userService.save();
}

1.2、DI入门案例

将BookServiceImpl注入到UserServiceImpl

修改UserServiceImpl的实现类,提供Set方法。创建BookService接口,和BookServiceImpl的实现类

public class UserServiceImpl implements UserService {
    private BookService bookService;

    public void setBookService(BookService bookService) {
        this.bookService = bookService;
    }

    @Override
    public void save() {
        bookService.save();
        System.out.println("user running...");
    }
}
public interface BookService {
    void save();
}
public class BookServiceImpl implements BookService {
    @Override
    public void save() {
        System.out.println("book running...");
    }
}

配置Spring配置文件将其注入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
        <!-- 7.配置user和book的关系-->
        <!-- property标签配置当前bean的属性-->
        <!-- name属性标识配置哪一个的属性-->
        <!-- ref属性标识参考那个bean-->
        <property name="bookService" ref="bookService"></property>
    </bean>
</beans>

1.3、Bean基础配置

 name:定义bean的别名,可定义多个,使用逗号(,)分号(;)空格( )分隔

<bean name="service1 service2" id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>

scope:定义bean作用范围,可选范围,singleton,prototype

    <bean scope="singleton" name="service1 service2" id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>

init-method:指定bean初始化方法名        destroy-method:指定bean销毁的方法 或者直接类实现InitializingBean DisposableBean(了解)

    <bean init-method="save" destroy-method="save" id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>

1.4、依赖注入的方式

setter注入------引用类型

public class UserServiceImpl implements UserService {
    private BookService bookService;
    public void setBookService(BookService bookService) {
        this.bookService = bookService;
    }
    @Override
    public void save() {
        bookService.save();
        System.out.println("user running...");
    }
}
<bean  id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>
<bean  id="userService" class="com.itheima.service.impl.UserServiceImpl">
   <property name="bookService" ref="bookService" ></property>
</bean>

setter注入-----基本类型

public class UserServiceImpl implements UserService {
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public void save() {
        System.out.println("姓名:"+name+",年龄:"+age);
    }
}

<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
        <property name="name" value="zhangsan"/>
        <property name="age" value="20"/>
</bean>

构造器注入---引用类型

public class UserServiceImpl implements UserService {
    private BookService bookService;

    public UserServiceImpl(BookService bookService) {
        this.bookService = bookService;
    }

    @Override
    public void save() {
        bookService.save();
        System.out.println("user running...");
    }
}
<bean  id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>
<bean  id="userService" class="com.itheima.service.impl.UserServiceImpl">
    <constructor-arg name="bookService" ref="bookService"/>
</bean>

构造器注入---基本类型-----还有其他方法 type  index

public class UserServiceImpl implements UserService {
    private String name;

    public UserServiceImpl(String name) {
        this.name = name;
    }

    @Override
    public void save() {
        System.out.println("user running..."+name);
    }
}
<bean  id="userService" class="com.itheima.service.impl.UserServiceImpl">
     <constructor-arg name="name" value="张三"/>
</bean>

自动装配 --- autowire 可以根据类型和名称匹配   byType(主要用这个)

        自动装配用于引用类型依赖注入,不能对简单类型进行操作

        使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用

        使用按类型装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置偶尔,不推荐使用

        自动装配优先级低于setter注入与构造器注入,同时出现自动装配配置失效

public class UserServiceImpl implements UserService {
    private BookService bookService;
    public void setBookService(BookService bookService) {
        this.bookService = bookService;
    }
    @Override
    public void save() {
        bookService.save();
        System.out.println("user running...");
    }
}
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl" autowire="byType"/>

集合注入

<bean  id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <property name="array">
            <array>
                <value>1</value>
            </array>
        </property>
        <property name="list">
            <list>
                <array>2</array>
            </list>
        </property>
        <property name="set">
            <set>
                <value>3</value>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="name" value="zhangsan"/>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="age">18</prop>
            </props>
        </property>
</bean>

1.5、容器

1.5.1、创建容器方式

方式一:类路径加载配置文件(常用)

ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");

方式二:文件路径加载配置文件(了解)

ApplicationContext app = new FileSystemXmlApplicationContext("D://applicationContext.xml");

方式三::加载多个配置文件(了解)

ApplicationContext app = new FileSystemXmlApplicationContext("bean1.xml","bean2.xml");

1.5.2、获取bean

方式一:使用bean名称获取

UserService userService =(UserService) app.getBean("userService");

方式二:使用bean名称获取并指定类型

UserService userService =app.getBean("userService",UserService.class);

方式三:使用bean类型获取

UserService userService =app.getBean(UserService.class);

1.5.3、总结

 

1.6、注解开发

1.6.1、注解开发定义bean

将配置文件下方代码的bean改为注释

<bean  id="userService" class="com.itheima.service.impl.UserServiceImpl"/>

在类上面添加一个注解

        Spring提供了@Component注解的三个衍生注解

                @Controller:用于表现层bean定义

                @Service:用于业务层bean定义

                @Repository:用于数据层bean定义

@Component("userService")
public class UserServiceImpl implements UserService {
    @Override
    public void save() {
        System.out.println("user running...");
    }
}

创建java下com.itheima.config.SpringConfig配置文件

        @Configuration:表明这个是配置类        @ComponentScan:包扫描com.itheima下的bean

@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}

 1.6.2、bean管理

bean的作用范围与bean的生命周期管理

@Component
@Scope("singleton")
public class UserServiceImpl implements UserService {
    @Override
    public void save() {
        System.out.println("user running...");
    }

    @PostConstruct
    public void init(){}
    
    @PreDestroy
    public void destory(){}
}

1.6.3、依赖注入---自动装配

使用@Autowired注解将BookServiceImpl注入到UserServiceImpl(按类型)        找不到按名称加上@Qualifier("bookService"),一定要配上@Autowried

@Component
public class UserServiceImpl implements UserService {
    @Autowired
    //@Qualifier("bookService")
    private BookService bookService;

    @Override
    public void save() {
        bookService.save();
        System.out.println("user running...");
    }
}

注入简单类型的值

@Component
public class UserServiceImpl implements UserService {
    @Value("zhangsan")
    private String name;
    @Override
    public void save() {
        System.out.println("user’s"+name);
    }
}

注入properties的值

        @PropertySource("jdbc.properties")加载一个        @PropertySource({"jdbc.properties","jdbc.properties"})加载多个

//在resource下创建jdbc.properties文件
name=lisi
//在SpringConfig配置文件中加上@PropertySource("jdbc.properties")
@Configuration
@ComponentScan("com.itheima")
@PropertySource("jdbc.properties")
public class SpringConfig {
}
//再使用@Value(${name})注入
@Component
public class UserServiceImpl implements UserService {
    @Value("${name}")
    private String name;
    @Override
    public void save() {
        System.out.println("user’s"+name);
    }
}

1.6.4、管理第三方bean

开发管理第三方bena

//导入druid坐标
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.12</version>
</dependency>
//1.再java下新建config.JDBCConfig的类
public class JDBCConfig {
    //1.定义一个方法获得管理的对象
    //2.添加@Bean,表示当前方法返回值是一个bean
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("");
        ds.setUrl("");
        ds.setUsername("");
        ds.setPassword("");
        return ds;
    }
}
//3.在java下新建config.SpringConfig的配置文件
@Configuration
@Import(JDBCConfig.class)
public class SpringConfig {
}
//4.测试文件
public static void main(String[] args) {
  ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class);
  DataSource dataSource = app.getBean(DataSource.class);
  System.out.println(dataSource);
}

注解开发实现为第三方bean注入资源

        简单类型

public class JDBCConfig {
    @Value("com.itheima.com")
    private String className;
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(className);
        ds.setUrl("");
        ds.setUsername("");
        ds.setPassword("");
        return ds;
    }
}

        引用类型----他会根据类型自动装配,但注意SpringConfig加上@ComponentSan还有注意注入的类要加上@Component的注解

public class JDBCConfig {
    @Bean
    public DataSource dataSource(UserService userService){
        userService.save();
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("");
        ds.setUrl("");
        ds.setUsername("");
        ds.setPassword("");
        return ds;
    }
}

1.7、AOP

面向切面编程:在不惊动原始设计的基础上进行功能增强

1.7.1、AOP入门案例

        在每一次执行方法之前输出当前时间

导入坐标

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>

制作连接点方法

@Component
public class BookServiceImpl implements BookService {
    @Override
    public void save() {
        System.out.println("book running...");
    }
}

制作共性功能,新建java下aop.MyAdvice

public class MyAdvice {
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

定义切入点

@Component
@Aspect
public class MyAdvice {
    @Pointcut("execution(void com.itheima.service.UserService.save())")
    private void pt(){}
    
    @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

绑定切入点与通知关系        配置文件加上@EnableAspectJAutoProxy

@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy
public class SpringConfig {
}

1.7.2、AOP通知类型

        @Before、@After、@BeforeThrowing、@BeforeThrowing

@Before("pt()")
public void method(){
    System.out.println(System.currentTimeMillis());
}

       @Around:最常用环绕模式

@Around("pt()")
public void method(ProceedingJoinPoint pjp) throws Throwable {
   //表示对原始操作的调用
   pjp.proceed();
   System.out.println(System.currentTimeMillis());
}

1.7.3、AOP通知获取数据

获取参数:

@After("pt()")
public void method(JoinPoint jp) throws Throwable {
        //表示对原始操作的调用
        Object[] args = jp.getArgs();
        System.out.println(Arrays.toString(args));
        System.out.println(System.currentTimeMillis());
}

1.8、Spring事务

事务作用:在数据层保障一系列的数据库操作同成功同失败

Spring事务作用:在数据层或业务层保障一系列的数据库操作同时成功同失败

 

2、SpringMVC


表现层功能的开发,Web框架

2.1、SpringMVC入门案例

(1)导入SpringMVC坐标与Servlet坐标

<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>3.1.0</version>
   <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId> 
  <version>5.3.23</version>
</dependency>

(2)创建SpringMVC控制类(等同于Servlet功能)        在java下新建com.itheima.controller.UserController

@Controller
public class UserController { 
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("user save...");
        return "{'name':'zhangsan'}";
    }
}

(3)初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对应的bean

@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}

(4)定义一个servlet容器启动的配置类,在里面加载spring的配置        在com.itheima.config下新建

public class ServletContainerInitConfig extends AbstractDispatcherServletInitializer {
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringConfig.class);
        return ctx;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

2.2、请求和响应

2.2.1、设置请求映射文件

名称:@RequestMapping        类型:方法注解 类注解        访问路径

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("save....");
        return "{'name':'zhangsan'}";
    }
}

2.1.2、请求方式

处理中文乱码:在ServletContainnerConfig的配置文件中重写getServletFilters方法

//乱码处理
@Override
protected Filter[] getServletFilters() {
    CharacterEncodingFilter filter = new CharacterEncodingFilter();
    filter.setEncoding("UTF-8");
    return new Filter[]{filter};
}

get与post接收普通参数(参数名称与传递过来的key值一样)

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/save")
    @ResponseBody
    public String save(String name,int age){
        System.out.println("save...."+name+age);
        return "{'name':'zhangsan'}";
    }
}

2.1.2、5种类型参数传递

普通参数名字不同时:使用@RequestParam("name") name

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/save")
    @ResponseBody
    public String save(@RequestParam("name") String name, @RequestParam("age") int age){
        System.out.println("save...."+name+age);
        return "{'name':'zhangsan'}";
    }
}

POJO类型参数:

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/save")
    @ResponseBody
    public String save(User user){
        System.out.println("save...."+user);
        return "{'name':'zhangsan'}";
    }
}

数组:

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/save")
    @ResponseBody
    public String save(@RequestParam("name") String[] name){
        System.out.println("save...."+ Arrays.toString(name));
        return "{'name':'zhangsan'}";
    }
}

集合类型参数:

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/save")
    @ResponseBody
    public String save(@RequestParam List<String> name){
        System.out.println("save...."+ name.toString());
        return "{'name':'zhangsan'}";
    }
}

2.1.3、接收请求中的JSON数据

        只能用于:JSON数组,JSON对象(POJO),JSON数组(POJO)

(1)添加JSON数据转化相关坐标

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>

(2)开启自动自动转换JSON数据的支持

@Configuration
@ComponentScan("com.itheima.controller")
//开启自动转换json数据支持
@EnableWebMvc
public class SpringMvcConfig {
}

(3)接收数据加上@RequestBody

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/save")
    @ResponseBody
    public String save(@RequestBody User user){
        System.out.println("save...."+ user);
        return "{'name':'zhangsan'}";
    }
}

2.1.4、日期参数传递

加上@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")                2023-1-9 20:01:9

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/save")
    @ResponseBody
    public String save(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date){
        System.out.println("save...."+ date);
        return "{'name':'zhangsan'}";
    }
}

2.2、响应

响应页面/跳转页面

@Controller
public class UserController {
    @RequestMapping("/user")
    public String save(){
        return "index.jsp";
    }
}

响应文本

@Controller
public class UserController {
    @RequestMapping("/user")
    @ResponseBody
    public String save(){
        return "index hello";
    }
}

响应POJO

@Controller
public class UserController {
    @RequestMapping("/user")
    @ResponseBody
    public User save(){
        User user = new User("zhangsan", 18);
        return user;
    }
}

响应对象集合转JSON数组

@Controller
public class UserController {
    @RequestMapping("/user")
    @ResponseBody
    public List<User> save(){
        List<User> users = new ArrayList<>();
        users.add(new User("zhangsan", 18));
        users.add(new User("lisi", 19));
        return users;
    }
}

@ResponseBody        设置当前控制器返回值作为响应体

2.3、REST风格

REST(Representational State Transfer)表现形式状态转换                增删改查方法区别

        简化代码开发:将@ResponseBody和@Controller合二为一@RestController       

        请求改为 @GetMapping        @PostMapping        @DeleteMapping        @PutMapping

@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping
    public List<User> save(){
        List<User> users = new ArrayList<>();
        users.add(new User("zhangsan", 18));
        users.add(new User("lisi", 19));
        return users;
    }
}

2.4、SSM整合

2.4.1、表现层数据封装

新建com.itheima.util下的Result类

public class Result {
    private Integer code;
    private Object data;
    private String msg;

    public Result() {
    }

    public Result(Integer code, Object data) {
        this.code = code;
        this.data = data;
    }

    public Result(Integer code, Object data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

使用

@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping
    public Result save(){
        List<User> users = new ArrayList<>();
        users.add(new User("zhangsan", 18));
        users.add(new User("lisi", 19));
        return new Result(200,users);
    }
}

2.4.2、异常处理器

 异常一般处理在表现层。我们在controller下新建ProjectExceptionAdvice

@RestControllerAdvice
public class ProjectExceptionAdvice {
    @ExceptionHandler(Exception.class)
    public Result doException(Exception ex){
        return new Result(401,null,"异常哪里走");
    }
}

异常分类:业务异常、系统异常、其他异常

2.5、拦截器

拦截器(interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行

作用:

        在指定的放法调用前后执行预先设定的代码

        组织原始方法的执行

2.5.1、入门案例

在表现层下新建interceptor.ProjectInterceptor

@Component
public class ProjectInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

在config下面的创建SpringMvcSupport文件

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {

    //注入冒红不是报错
    @Autowired 
    private ProjectInterceptor projectInterceptor;

//   这个负责处理静态资源访问
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
    }

//    这个是拦截器
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor).addPathPatterns("/user");
    }
}

在config的SpringMvcConfig配置文件扫描

@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
//开启自动转换json数据支持
@EnableWebMvc
public class SpringMvcConfig {
}

         preHandle是最常用的

2.5.2、配置多个拦截器

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {

    @Autowired
    private ProjectInterceptor projectInterceptor1;
    @Autowired
    private ProjectInterceptor projectInterceptor2;

//   这个负责处理静态资源访问
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
    }

//    这个是拦截器
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor1).addPathPatterns("/user");
        registry.addInterceptor(projectInterceptor2).addPathPatterns("/user");
    }
}

3、Maven


4、SpringBoot


4.1、spring项目快速启动

打成jar包->执行java -jar springboot.jar

4.2、配置文件格式

位置:resource下application.yml

三种:properties格式、yml格式(常用)、yaml格式        pro>yml>yaml

数据读取yml数据的三种方式:

city: china
user:
  name: zhangsan
  age: 19
方式一:
@RestController
@RequestMapping("/user")
public class UserController {
    @Value("${city}")
    private String city;
    @Value("${user.name}")
    private String name;
    @GetMapping("/{id}")
    public String getUserbyId(@PathVariable Integer id){
        return "hello.springboot"+id+city;
    }
}
方式二:用一个对象进行全封装
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private Environment env;
    @GetMapping("/{id}")
    public String getUserbyId(@PathVariable Integer id){
        return "hello.springboot"+env.getProperty("city")+env.getProperty("user.name");
    }
}
方式三:创建自定义对象封装指定数据
第一步创建:domain.User
@Component
@ConfigurationProperties(prefix = "user")
@Data
public class User {
    private String name;
    private Integer age;
}
第二步:读取
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private User user;
    @GetMapping("/{id}")
    public String getUserbyId(@PathVariable Integer id){
        return "hello.springboot"+user;
    }
}

自定义对象封装数据警告解决方案-----加入坐标

<dependency>
     <groupId>org.springframework.boot</groupId
     <artifactId>spring-boot-configuration-processor</artifactId>
     <optional>true</optional>
</dependency>

4.3、多环境开发

方式一:过时无所谓(推荐)

#设置启用的环境
spring:
  profiles:
    active: pro
---
#开发
spring:
  profiles: dev
server:
  port: 80
---
#生产
spring:
  profiles: pro
server:
  port: 81
---
#测试
spring:
  profiles: test
server:
  port: 82

方式二:不过时

#设置环境
spring:
  profiles:
    active: pro
---
#开发
spring:
  config:
    activate:
      on-profile: dev
server:
  port: 80
---
#生产
spring:
  config:
    activate:
      on-profile: pro
server:
  port: 81
---
#测试
spring:
  config:
    activate:
      on-profile: test
server:
  port: 82

多环境命令启动参数设置

        yml出现中文:先去设置,将编码改为UTF8

java -jar springboot.jar --spring.profiles.active=test
java -jar springboot.jar --server=88 --spring.profiles.active=test

1.SpringBoot整合第三方技术 

整合MyBaties

导入坐标

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.31</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.6</version>
</dependency>

配置文件:properties.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource

创建实体类、domain.User

@Data
public class User {
    private Integer id;
    private String name;
    private Double balance;
}

创建接口方法

@Mapper
public interface UserDao {
    @Select("select * from account where id = #{id}")
    public User getById(Integer id);
}

编写测试类

@Test
void contextLoads() {
   User user = userDao.getById(1);
   System.out.println(user);
}

5、Springboot整合MyBaties-plus


入门案例

MyBatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发,提高效率

1.导入依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.31</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.12</version>
</dependency>

设置配置文件

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource

创建domian下User实体对象

@Data
public class Account{
    private Integer id;
    private String name;
    private Double balance;
}

创建UserDao让其继承BaseMapper<Account>

@Mapper
public interface UserDao extends BaseMapper<Account> {
}

测试类------他找表是根据你的BassMapper(类名) 类名小写的表名

 @Test
void contextLoads() {
    List<Account> users = userDao.selectList(null);
    System.out.println(users);
}

标准数据层开发

@SpringBootTest
class Springboot01QuickstartApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    //新增
    public void insert(){
        userDao.insert(new Account(null,"罗翔",15000.0));
    }

    @Test
    //删除
    public void delete(){
        userDao.deleteById(10);
    }

    @Test
    //修改
    public void update(){
        userDao.updateById(new Account(1,"罗翔",19000.0));
    }

    @Test
    //根据id查询
    public void getById(){
        Account account = userDao.selectById(1);
        System.out.println(account);
    }

    @Test
    //查询所有
    public void selectAll(){
        List<Account> accounts = userDao.selectList(null);
        System.out.println(accounts);
    }
}

lombok

<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>RELEASE</version>
   <scope>compile</scope>
</dependency>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account {
    @TableId(value="id",type= IdType.AUTO)
    private Integer id;
    private String name;
    private Double balance;
}

标准分页功能制作

配置分页拦截器        创建MPConfig配置文件

@Configuration
public class MpConfig {

    @Bean
    public MybatisPlusInterceptor mpInterceptor() {
        //1.定义MP拦截器
        MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
        //2.添加具体的拦截器
        mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mpInterceptor;
    }

}

测试

@Test
//分页
public void testGetByPage(){
  IPage page = new Page(1, 2);
  userDao.selectPage(page, null);
  System.out.println("当前页码值"+page.getCurrent());
  System.out.println("每页显示数"+page.getSize());
  System.out.println("一共多少页"+page.getPages());
  System.out.println("一共多少条数据"+page.getTotal());
  System.out.println("数据"+page.getRecords());
}

开启日志---不出问题一般不开

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

条件查询的三种格式

方式一:按条件查询

@Test
public void testGetByPage(){
    QueryWrapper qw = new QueryWrapper();
    qw.lt("balance", 1990);
    List<Account> list = userDao.selectList(qw);
    System.out.println(list);
}

方式二:lamda格式按条件查询

@Test
public void testGetByPage(){
    QueryWrapper<Account> qw = new QueryWrapper<>();
    qw.lambda().lt(Account::getBalance, 1990);
    List<Account> list = userDao.selectList(qw);
    System.out.println(list);
}

方式三:lamda格式按条件查询

@Test
public void testGetByPage(){
   LambdaQueryWrapper<Account> lqw = new LambdaQueryWrapper<>();
   lqw.lt(Account::getBalance,1231).ge(Account::getBalance,10);
   List<Account> accounts = userDao.selectList(lqw);
   System.out.println(accounts);
}

条件查询---null值处理

@Test
public void testGetByPage(){
    Account account = new Account();
    account.setBalance(1233.0);
    LambdaQueryWrapper<Account> lqw = new LambdaQueryWrapper<>();
    lqw.lt(null != account.getBalance(),Account::getBalance,account.getBalance());
    List<Account> accounts = userDao.selectList(lqw);
    System.out.println(accounts);
}

查询投影----只查询哪些字段

@Test
public void testGetByPage(){
   LambdaQueryWrapper<Account> lqw = new LambdaQueryWrapper<>();
   lqw.select(Account::getName,Account::getBalance);
   List<Account> accounts = userDao.selectList(lqw);
   System.out.println(accounts);
}

查询条件设置

eq=:匹配        le ge between:区间        like tightLike   lefiLike

映射匹配兼容性

问题一:表字段与编码属性设计不同步

@TableField(value = "username")
private String name;

问题二:编码中添加了数据库中未定义的属性

@TableField(exist = false)
private String name;

问题三:采用默认查询更多的字段查看权限

@TableField(select = false)
private String name;

问题四:表名与编码开发设计不同步

@TableName("t_account")
public class Account{}

2.DML编程控制

id生成策略

方法一:

        AUTO(0):使用数据库id自增策略控制id生成

        NONE(1):不设置id生成策略

        INPUT(2):用户手工输入id

        ASSIGN_ID(3):雪花算法生成id(可兼容数值型与字符型)

        ASSIGN_UUID(4):以UUID生成算法作为id生成策略

@TableId(type= IdType.AUTO)
private Integer id;

方法二:全局配置

mybatis-plus:
  global-config:
    db-config:
      id-type: auto #id生成策略
      table-prefix: t_ble #前表缀

多数据操作(删除与查询)

删除

@Test
public void testGetByPage(){
  List<Integer> list = new ArrayList<>();
  list.add(25);
  list.add(26);
  userDao.deleteBatchIds(list);
}

查询

@Test
public void testGetByPage(){
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    List<Account> accounts = userDao.selectBatchIds(list);
    System.out.println(accounts);
}

逻辑删除

删除操作业务问题:业务数据从数据库中丢弃

逻辑删除:为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中        

         步骤一:注意这里的属性名和字段名不能命名为delete否则会报错

        value:代表没删的值,delval:表示删除的值

@TableLogic(value = "0",delval = "1")
private Integer deleted;

        步骤二:测试

@Test
public void testGetByPage(){
   userDao.deleteById(1);
}

全局配置逻辑删除:

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: deleted
      logic-delete-value: 1 #删除的值
      logic-not-delete-value: 0 #未删除的值

乐观锁

业务并发现象带来的问题:秒杀

步骤一:添加字段--->version

步骤二:设定当前字段

@Version
private Integer version;

步骤三:配置乐观锁拦截器机制对应的拼接

@Configuration
public class MpConfig {

    @Bean
    public MybatisPlusInterceptor mpInterceptor() {
        //1.定义MP拦截器
        MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
        //2.添加具体的拦截器----分页拦截
        mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        //3.添加乐观锁
        mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mpInterceptor;
    }
}

步骤四:使用乐观锁机制在修改前必须先获得对应数据的version方可正常进行

 @Test
 public void testGetByPage(){
    //先查询数据,获取到version数据
    Account account = userDao.selectById(2);
    //执行数据修改操作
    account.setName("jack");
    userDao.updateById(account);
 }

代码生成器

这个还是自己查文档吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/152761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第四十九讲:神州路由器IPv6 OSPFv3和RIPng路由的配置

神州路由器支持IPv6的内部网关路由协议常用的有OPSFv3和RIPng。 实验拓扑图如下所示 配置要求&#xff1a;在两台路由器上启用IPv6 routing&#xff0c; 在接口上配子ipv6协议后&#xff0c;通过配置RIPng和OSPFv3相关命令&#xff0c;观察学习到的路由。 配置步骤&#xff1…

产品试用记录

某产品试用记录 还可以选屏哦

【PWA学习】3. 让你的 WebApp 离线可用

引言 PWA 其中一个令人着迷的能力就是离线(offline)可用 即使在离线状态下&#xff0c;依然可以访问的 PWA离线只是它的一种功能表现而已&#xff0c;具体说来&#xff0c;它可以&#xff1a; 让我们的Web App在无网(offline)情况下可以访问&#xff0c;甚至使用部分功能&#…

Redis哨兵模式搭建

以下配置机器部署ip为 a、b、c&#xff0c;其中a为master节点 需提前创建 /app/user/oms/redis/data 目录 1.1上传 redis-5.0.5.zip 到对应目录&#xff0c;解压 unzip redis-5.0.5.zip # 生成 redis-5.0.5 目录 1.2 修改配置文件 maxclients 10000 #20000 &#xff0…

接口测试实战| GET/POST 请求区别详解

在日常的工作当中&#xff0c;HTTP 请求中使用最多的就是 GET 和 POST 这两种请求方式。深度掌握这两种请求方式的原理以及异同之处&#xff0c;也是之后做接口测试一个重要基础。GET、POST 的区别总结请求行的 method 不同&#xff1b;POST 可以附加 div&#xff0c;可以支持 …

概率论【离散型二维变量与连续性二维变量(下)】--猴博士爱讲课

6.连续型二维变量&#xff08;下&#xff09; 1/7 求边缘分布函数 边缘概率密度 边缘概率密度 2/7 求边缘密度函数 边缘概率密度 3/7 判断连续型二维变量的独立性 F(x,y) Fx(X) * Fy(Y)那么X、Y互相独立 f(x,y) fx(X) * fy(Y)那么X、Y互相独立 这种题目带入验证就可以了 先求…

百度举办首个人机共创大会,最强技术天团邀约全球开发者

1月10日&#xff0c;百度举办Create AI开发者大会&#xff08;下称“Create大会”&#xff09;。作为首个“人机共创大会”&#xff0c;AIGC&#xff08;利用AI技术自动生成内容的生产方式&#xff09;技术被深度应用&#xff0c;创造、搭建、连接了多个科技感爆棚的数字化演讲…

powershell ISE 多个选项卡,替换命令行黑窗口

安装powershell ISE设置权限解决方案1.管理员打开PowerShell2. 执行Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser运行脚本自定义函数&#xff0c;function start_service([string]$Name,$p,$r) {$NewTab $psISE.PowerShellTabs.Add()$NewTab.Displa…

ES之module

模块&#xff1a;一个一个的局部作用域的代码块 模块系统需要解决的主要问题 模块化的问题消除全局变量管理加载顺序 Module的基本用法 模块里面都是局部无法访问 切换幻灯片示例 Base.js // 默认参数 const DEFAULTS {// 初始索引initialIndex: 0,// 切换时是否有动画a…

Repvgg推理时融合BN

Batch Normalization是谷歌研究员于2015年提出的一种归一化方法&#xff0c;其思想非常简单&#xff0c;一句话概括就是&#xff0c;对一个神经元&#xff08;或者一个卷积核&#xff09;的输出减去统计得到的均值&#xff0c;除以标准差&#xff0c;然后乘以一个可学习的系数&…

数字孪生|可视化图表之堆叠面积图

上一篇文章为大家介绍了分组条形图的相关内容&#xff0c;本文介绍的是堆叠面积图。 堆叠面积图是一种特殊的面积图&#xff0c;可以用来比较在一个区间内的多个变量。堆叠面积图和普通的面积图基本一样&#xff0c;唯一的区别就是堆叠面积图每个数据系列的起点都是基于前一个数…

再学C语言30:函数——ANSI C的函数原型

一、ANSI C关于函数原型的规则 ANSI C在函数声明中同事说明所使用的的参数类型&#xff0c;即在函数原型中声明返回值类型、参数、参数个数、参数类型 int function(int a, int b); // 形式一 int function(int, int); // 形式二// 以上两种形式的定义均满足规范要求 好…

基于无线通信物联网的水库安全监测系统

水库安全监测一直是我国防洪防汛工作的重点&#xff0c;库区的雨量、水位的实时监测&#xff0c;建立水库监测系统能够有效防止洪涝灾害的发生&#xff0c;确保水库和下游地区的安全。 物通博联推出的水库安全监测系统是基于无线通信物联网技术打造的系统平台&#xff0c;由雨…

路由器基础

交换机基本功能 1.基于源MAC地址学习2.基于目标MAC地址转发3.数据过滤4.防环 交换机基于MAC地址表进行转发&#xff0c;MAC地址表默认自动产生&#xff0c;MAC地址组成三元组&#xff1a;Mac地址、端口、VLAN。默认MAC条目信息存活时间为300s并且可以修改 泛洪&#xff08;洪…

局域网主机状态管理工具LanNeighborManager

有鉴于以下两种需求&#xff0c;做了一个小工具&#xff0c;查看局域网内的IP占用情况及联通状态&#xff1a;1&#xff09;在现场需要分配静态IP&#xff0c;但是不确定已经被占用的IP地址&#xff1b;2&#xff09;查看当前局域网内当前活跃的IP地址。该工具的主要功能有&…

华宏转债上市价格预测

华宏转债基本信息转债名称&#xff1a;华宏转债&#xff0c;评级&#xff1a;AA-&#xff0c;发行规模&#xff1a;5.15亿元。正股名称&#xff1a;华宏科技&#xff0c;今日收盘价&#xff1a;17.68&#xff0c;转股价格&#xff1a;15.65。当前转股价值 转债面值 / 转股价格…

2023.1.2-1.18 AI行业周刊(第131期):程序员的艰辛和感悟

转眼间&#xff0c;还有两周不到的时间&#xff0c;就要到除夕了。今年的春节和元旦离得很近&#xff0c;只有二十多天的时间。 班上部门的同事&#xff0c;一个个也都开始阳康&#xff0c;回到工作岗位&#xff0c;做春节前产品的最后一次版本迭代。 一晃从去年三月份进入新…

3-计算字符串的编辑距离(华为机试)

题目 Levenshtein 距离&#xff0c;又称编辑距离&#xff0c;指的是两个字符串之间&#xff0c;由一个转换成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符&#xff0c;插入一个字符&#xff0c;删除一个字符。编辑距离的算法是首先由俄国科学…

Bonitasoft认证绕过和RCE漏洞分析及复现(CVE-2022-25237)

一、漏洞原理 漏洞简述 Bonitasoft 是一个业务自动化平台&#xff0c;可以更轻松地在业务流程中构建、部署和管理自动化应用程序&#xff1b; Bonita 是一个用于业务流程自动化和优化的开源和可扩展平台。 Bonita Web 2021.2版本受到认证绕过影响&#xff0c;因为其API认证…

没有为请求的 URL 配置默认文档,并且没有在服务器上启用目录浏览

1、问题 使用asp.net mvc写了个网站&#xff0c;部署后出现&#xff1a; 没有为请求的 URL 配置默认文档&#xff0c;并且没有在服务器上启用目录浏览 这个问题 2、解决办法 网上搜了下&#xff0c;无非是两种方法&#xff1a; 1、在web.config中添加 <system.webServ…