java后端第六阶段:SpringMVC

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);
 }

代码生成器

这个还是自己查文档吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值