SpringBoot学习记录:2

SpringBoot2的核心功能

配置文件

文件类型

  • properties
  • yaml
    非常适合用来做以数据为中心的配置文件
    • key:value 【kv之间有空格】
    • 大小写敏感
    • 使用缩进表示层级关系
      • 缩进不允许使用tab,只允许空格
      • 缩进的格数不重要,但是要左对齐
    • ‘#’表示注释
    • ‘’和“”表示字符串内容, 会被转义/不转义

区别一下两种不同文件类型,编写配置文件的差异

首先一个Person类

public class Person {
    private String userName;
    private Boolean boss;
    private Date birth;
    private Integer age;
    private Pet pet;
    private String[] interests;
    private List<String> animal;
    private Map<String,Object> score;
    private Set<Double> salarys;
    private Map<String,List<Pet>> allPets;
}

对于properties文件类型的绑定

在这个类的头上就要绑定其咋写这个配置文件

@ConfigurationProperties(prefix = "person")

然后在application.properties下就可以自定义这个类的属性值了

person.userName=lee
person.age=18

对于yaml文件类型的绑定

在resource下创建一个文件类型为application.yaml 或者application.yml

然后在需要的类型的头上写

@ConfigurationProperties(prefix = "person")
@Component

那么在yml文件下定义属性值

person:
  userName: zhangsan
  boss: true
  birth: 2019/12/9
  age: 18
  interests:
    - 篮球
    - 足球
    - 18
  animal: [阿猫,阿狗]
  score: {english:80,math:90}
  salarys:
    - 9999
    - 9999.9
    - 9999.9
  pet:
    name: 阿狗
    weight: 99.99
  allPets:
    sick:
      - {name: 阿狗,weight: 10}
      - name: 阿猫
        weight: 12
    health:
      - {name: 阿虫,weight: 10}

在这里插入图片描述
小结:一定要注意左对齐空格的问题!

而且存在配置文件优先级

properties>yml>yaml

因此,在yaml写的东西如果在properties中重名了,这个属性值会被properties的属性值覆盖

配置文件属性提示依赖

添加这个依赖

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

以后配置文件中就会有提示
在这里插入图片描述

但是这个一般都在Spring initial 的时候就可以直接配置好

web场景开发

1.静态资源访问

访问方式:http://localhost:8080/资源名

那么资源存放在哪里?这四个目录都是默认的静态资源存放位置
在这里
原理:

为什么存放在这里的静态资源局能够直接被访问到呢?

测试,如果在controller里加入一个requestMapping动态请求

@RestController
public class HelloController {
    @RequestMapping("/bug.png")
    public String hello(){
        return "aaaa";
    }
}

发现请求走的是aaaa
在这里插入图片描述
那么这个资源的执行流程就是:

url请求进来,先去找controller能不能去处理,不能处理的所有请求又都交给静态资源处理器,如果都不能找到的话几句404

2.静态资源访问前缀

默认是无前缀的
那么如果需要自定义资源文件夹res的话,就需要在配置文件中配置,配置如下

spring:
  mvc:
    static-path-pattern: /res/**

那么现在配置后应该咋访问到静态资源呢?

静态资源 = 当前项目 + static-path-pattern + 静态资源名

  • 网页首页放在static目录下
  • 网页小图标 favicon.ico
    在这里插入图片描述

3.静态资源配置原理,没看懂

配置这个类的条件分析

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
// 如果没有这个support下面的才生效
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
//要等后面三个配完之后才能配当前这个类
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})

public class WebMvcAutoConfiguration {}

那么在这个类配置了哪些内容呢?

HandlerMapping: 处理器映射,保存了每一个Handler能够处理哪些请求

4.请求参数处理

表单提交rest原理

#开启页面表单的Rest功能
spring:
  mvc:
    hiddenmethod:
      filter:
        enabled: true

在这里插入图片描述
在表单提交的时候带_method的参数 = PUT

发送请求后,会被filter拦截

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest requestToUse = request;
        // 1.先要判断表单提交的方式是不是POST,然后看当前请求是否有什么错误
        if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
            String paramValue = request.getParameter(this.methodParam);
            if (StringUtils.hasLength(paramValue)) {
            //2.将请求的参数值转换成大写
                String method = paramValue.toUpperCase(Locale.ENGLISH);
                //3.转换为大写后,看是不是系统允许的请求
                if (ALLOWED_METHODS.contains(method)) {
                	//4.经过一个wrapper,然后将原生的请求包装成了rest的请求
                    requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
                }
            }
        }

        filterChain.doFilter((ServletRequest)requestToUse, response);
    }

这里就是第3步兼容的请求

static {
        ALLOWED_METHODS = Collections.unmodifiableList(Arrays.asList(
         HttpMethod.PUT.name(),
         HttpMethod.DELETE.name(), 
         HttpMethod.PATCH.name()));
    }

第4的Wrapper, 将一个请求,和一个新的请求方式(put,delete,patch)作为参数放到了HttpMethodRequestWrapper方法中,方法的作用就是重新包装了这个method

private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
        private final String method;

        public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
            super(request);
            this.method = method;
        }

        public String getMethod() {
            return this.method;
        }
    }

而且也能看到包装类HttpMethodRequestWrapper最本质都是实现了ServletR equest接口

然后过滤器在放行的时候用wrapper
在这里插入图片描述
而且为了避免这些麻烦,都提供了更为直接的注释,直接使用即可在这里插入图片描述

5.使用

在这里插入图片描述
访问后得到的值
在这里插入图片描述

6.请求转发

@Controller
public class RequestController {

    @GetMapping("/goto")
    public String goToPage(HttpServletRequest request){
        request.setAttribute("msg","123133");
        request.setAttribute("code",200);
        return "forward:/success";
    }


    @ResponseBody
    @GetMapping("/success")
    public Map success(@RequestAttribute("msg") String msg,
                       @RequestAttribute("code")Integer code,
                       HttpServletRequest request){

        Object msg1 = request.getAttribute("msg");
        Map<String,Object> map = new HashMap<>();
        map.put("RequestAttribute_msg",msg);
        map.put("getAttribute_msg",msg1);
        return map;
    }
}

走的goto,但是请求转发到了success

@requestbody的作用是在当前对象获取整个http请求的body里面的所有数据

@ResponseBody的作用其实是将java对象转为json格式的数据,返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用【也就是AJAX】

因此在这里将goto中的对象转换成了json数据,然后success再获取到responseBody中的信息
在这里插入图片描述

7.矩阵变量

面试题:如果页面被禁用了cookie,session里的内容怎么使用?

因为浏览器访问过程是,每次请求携带cookie,而cookie中有jsession,这个jsession能够使得获取session中的内容。

那么禁用了的话,通过url重写,把cookie的值使用矩阵变量的方式传递

而矩阵变量需要手动开启组件 false

矩阵变量必须有url路径变量才能被解析

视图解析

thymeleaf

1.引入thmeleaf-starter

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

web应用开发

1.可能开发使用的网页添加到静态资源static
2.要用的模版放到template里

为啥要放到template里,是因为thymeleaf配置的时候,默认找到文件的前缀就在template下
在这里插入图片描述

有可能在上一个项目8080端口还在被用没有terminate

解决方法:

  • 要么改变当前项目的端口
  • 要么kill掉进程
lsof -i:8080

在这里插入图片描述

kill 47454

构建一个main主页,和一个login登陆页

表单如果转发的话,刷新后又会重复提交页面,出现类似信息
在这里插入图片描述

因此可以通过用一个中间商main来重定向,这样就能够避免post的表单重复提交

@Controller
public class IndexController {
    @GetMapping({"/","/login"})
    public String loginPage(){

        return "login";
    }

    @PostMapping("/login")
    public String main(String name,String password){
        return "redirect:/main.html";
    }

    @GetMapping("/main.html")
    public String mainPage(){
        return "main";
    }
}

那么还有个问题 如何给一个用户,创建一个session呢?

@Controller
public class IndexController {

    /**
     * 来登陆页面
     * @return
     */
    @GetMapping({"/","/login"})
    public String loginPage(){

        return "login";
    }

    @PostMapping("/login")
    public String main(User user, HttpSession session, Model model){
        if(StringUtils.hasLength(user.getUserName()) && ("123456").equals(user.getPassword())){
            session.setAttribute("loginUser",user);
            return "redirect:/main.html";
        }else {
            model.addAttribute("msg","账号密码错误");
            return "login";
        }
    }

    @GetMapping("/main.html")
    public String mainPage(HttpSession session,Model model){
        //是否判断
        Object loginUser = session.getAttribute("loginUser");
        if(loginUser!=null){
            return "main";
        }else {
            model.addAttribute("msg","请重新登陆");
            return "login";
        }

    }
}

这个msg就是通过model传到视图解析上的,也就是html页面上的内容,因此在login.html下添加一个提示框

<label style="color: red" th:text="${msg}"></label>

如实现
在这里插入图片描述
或者session过期了
在这里插入图片描述

在html中获取存到session中的值

[[${session.loginUser.user}]]

然后继续对于主页中的表格进行处理
一定要添加这个,静态资源才能在模版文件夹中去找,否则页面找不到。

<html lang="en" xmlns:th="http://www.thymeleaf.org">

如果用id的形式

<div id="commonscript">
    <script th:src="@{/js/jquery-1.10.2.min.js}"></script>
    <script th:src="@{/js/jquery-ui-1.9.2.custom.min.js}"></script>
    <script th:src="@{/js/jquery-migrate-1.2.1.min.js}"></script>
    <script th:src="@{/js/bootstrap.min.js}"></script>
    <script th:src="@{/js/modernizr.min.js}"></script>
    <script th:src="@{/js/jquery.nicescroll.js}"></script>
</div>

那么在用模版引擎引入公共部分的话,就用#选择器

<div th:include="common::#commonscript"></div>

如果用th:fragment的形式

<div id="leftmenu" class="left-side sticky-left-side">
...
</div>

那么就引入方式就如下

<link th:include="common::commonheader">

拦截器HandlerInterceptor

使用该接口需要实现三个方法

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

那么对于当前网页管理系统,用户应该完成了登陆界面才可以访问主页

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //登陆检查逻辑
        HttpSession session = request.getSession();
        Object loginUser = session.getAttribute("loginUser");
        if(loginUser!=null){
            return true;
        }
        return false;
    }

该拦截器就判断了是否登陆了,那么判断完是否登陆了就需要交给config进行设置,成功了干啥,不成功干啥,这下面这段就代表着,向registry加入了一个拦截器,下面为放行的规定,当拦截器返回值为假的时候(代表没有session存在):拦截所有,除了login /

@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //代表除了/ /login 这些登陆页的访问方式可以放行,其他的都不行
        //只要当登陆的情况下,session!= null的时候拦截器才放行
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**") //静态资源所有请求都会被拦截
                .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); //放行的请求

    }
}

配置连接数据库

  • 使用Hikari

步骤:只需要添加关于数据库的配置即可

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT
    username: root
    password: 
#    type: com.zaxxer.hikari.HikariDataSource

  jdbc:
    template:
      query-timeout: 3

测试使用:

@Slf4j
@SpringBootTest
class Boot03ApplicationTests {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Test
    void contextLoads() {
        Long aLong = jdbcTemplate.queryForObject("select count(*) from user", Long.class);
        log.info("记录总数" + aLong);
    }
}
  • 使用druid

添加依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.6</version>
</dependency>

在以前用Spring配置数据源的原生办法

给容器中放一个dataSource,而这些信息都在这个配置中配好

在这里插入图片描述
但是在SpringBoot中,由于DataSourceAutoConfiguration这个类

默认的自动配置是:判断没有hikari才会配置默认数据源

@ConditionalOnMissingBean({DataSource.class, XADataSource.class})

那么现在如果想自己配置自定义的数据源,就可以创建一个配置类,这个配置类里面的内容就是自定义数据源的配置信息

public class MyDateSourceConfig {
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        return druidDataSource;
    }
}

引入官方配置

  1. 配置类
  2. 系统中存在数据源才进行配置
  3. 该类配置在DataSourceAutoConfiguration之前
    • 而这个数据源自动配置默认是hikari数据源
    • 因此以自定义数据源优先,这样就把官方的取缔掉了
  4. 使配置文件生效
    • 在DruidStatProperties是和prefix="spring.datasource.druid"的配置文件绑定
    • 在DataSourceProperties是和prefix = "spring.datasource"绑定的
  5. 引入这些类
    • DruidSpringAopConfiguration.class ,监控springbean的
    • DruidStatViewServletConfiguration.class 监控页的配置spring.datasource.druid.stat-view-servlet.enabled = true
    • DruidWebStatFilterConfiguration.class web监控配置spring.datasource.druid.stat-view-servlet.enabled= true
    • DruidFilterConfiguration.class spring.datasource.druid.stat-view-servlet.enabled = true,里面还包括了很多组件比如编码,log4j
@Configuration
@ConditionalOnClass({DruidDataSource.class})
@AutoConfigureBefore({DataSourceAutoConfiguration.class})
@EnableConfigurationProperties({DruidStatProperties.class, DataSourceProperties.class})
@Import({DruidSpringAopConfiguration.class, DruidStatViewServletConfiguration.class, DruidWebStatFilterConfiguration.class, DruidFilterConfiguration.class})
public class DruidDataSourceAutoConfigure {
    private static final Logger LOGGER = LoggerFactory.getLogger(DruidDataSourceAutoConfigure.class);

    public DruidDataSourceAutoConfigure() {
    }

    @Bean(
        initMethod = "init"
    )
    @ConditionalOnMissingBean
    public DataSource dataSource() {
        LOGGER.info("Init DruidDataSource");
        return new DruidDataSourceWrapper();
    }
}

通过配置文件进行druid数据源的配置,根据官方文档就可以进行配置

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT
    username: root
    password: 19971231

    druid:
      aop-patterns: com.lee.boo3.*  #监控SpringBean
      filters: stat,wall     # 底层开启功能,stat(sql监控),wall(防火墙)

      stat-view-servlet:   # 配置监控页功能
        enabled: true
        login-username: admin
        login-password: admin
        resetEnable: false

      web-stat-filter:  # 监控web
        enabled: true
        urlPattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'


      filter:
        stat:    # 对上面filters里面的stat的详细配置
          slow-sql-millis: 1000
          logSlowSql: true
          enabled: true
        wall:
          enabled: true
          config:
            drop-table-allow: false


整合Mybatis,配置文件版

添加依赖

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>

如果使用之前的配置文件方式

  1. SqlSessionFactoryBuilder
  2. SqlSessionFactory
  3. SqlSession
  4. Mapper
  5. sql语句

使用starter配置

  1. 配置类
  2. 要保证配置mybatis的时候有SqlSessionFactory和SqlSessionFactoryBean这两个类
  3. 当前容器中只有一个数据源
  4. MyBatis的配置绑定类,其中包含了需要配置的信息
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})

public MybatisAutoConfiguration{}

配置项就和mybatis开头的所有信息绑定

MybatisProperties

@ConfigurationProperties(
    prefix = "mybatis"
)
public class MybatisProperties {
    public static final String MYBATIS_PREFIX = "mybatis";
    private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
    private String configLocation;
    private String[] mapperLocations;
    private String typeAliasesPackage;
    private Class<?> typeAliasesSuperType;
    private String typeHandlersPackage;
    private boolean checkConfigLocation = false;
    private ExecutorType executorType;
    private Class<? extends LanguageDriver> defaultScriptingLanguageDriver;
    private Properties configurationProperties;
    @NestedConfigurationProperty
    private Configuration configuration;
    ...
    
	@Bean
    @ConditionalOnMissingBean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);
    } 
    
     @Bean
    @ConditionalOnMissingBean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        ExecutorType executorType = this.properties.getExecutorType();
        return executorType != null ? new SqlSessionTemplate(sqlSessionFactory, executorType) : new SqlSessionTemplate(sqlSessionFactory);
    }

配置流程

  1. 创建mybatis-config配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	
    <!-- 由于Spring Boot自动配置缘故,此处不必配置,只用来做做样。-->
</configuration>
  1. 在配置信息中加入mybatis配置文件的位置,以及mapper的位置
mybatis:
  config-location: classpath:mybatis/mybatis-config.xml 
  # 全局配置文件位置,其实可以不写,因为如果后面要写关于mybatis的一些其他配置信息,会报错,因为configuration和config- location不能同时存在,所有配置信息都会放在configuration下
  mapper-locations: classpath:mybatis/mapper/*.xml #sql映射文件的位置
  1. 声明Mapper接口
@Mapper
public interface UserMapper {
    public User getUser(int id);
}
  1. 绑定映射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.lee.boot03.mapper.UserMapper">

    <select id="getUser" resultType="com.lee.boot03.bean.User">
        select * from user where id=#{id}
    </select>
</mapper>

5.数据库提取的对象pojo

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;
}

6.service层提供一个操作数据库相关方法

@Service
public class UserService {

    @Autowired
    UserMapper userMapper;

    public User c(int id){
        return userMapper.getUser(id);
    }
}

7.controller层再通过service去调用方法

@Autowired
UserService userService;

@GetMapping("/user")
public User getById(@RequestParam("id") int id){
    return userService.getUserById(id);
}

总结

  • 导入mybatis官方的starter
  • 编写mapper接口(标注@mapper)
  • 编写sqlmapper文件,并绑定mapper接口
  • application.yaml中指定mapper文件的位置,以及全局配置文件信息

整合mybatis,注解版

创建表

use mybatis;
CREATE TABLE city(
id int(11) primary key AUTO_INCREMENT,
name varchar(30),
state varchar(30),
country varchar(30)
);
  1. pojo city
  2. dao接口
@Mapper
public interface CityMapper {
    @Select("select * from city where id=#{id}")
    public City getById(int id);
}
  1. service
@Service
public class CityService {

    @Autowired
    CityMapper cityMapper;

    public City getCityById(int id){
        return cityMapper.getById(id);
    }
}
  1. controller使用
 @Autowired
    CityService cityService;

    @ResponseBody
    @GetMapping("/city")
    public City getCityById(@RequestParam("id") int id){
        return cityService.getCityById(id);
    }

因为有的时候 对于处理复杂的数据库关系,比如一对多多对一 还是用xml的方式比较好,因此需要结合在一起使用

所以可以在cityMapper接口写一些简单的数据库逻辑,例如上述的

同时在citymapper.xml配置文件中写一些复杂的逻辑时,简单的写在注解上,复杂的用xml来写

使用@MapperScan(“com.lun.boot.mapper”) 简化,Mapper接口就可以不用标注@Mapper注解。


mybatis plus 整合

use mybatis;

create table user(
	id bigint(20) not null comment'主键ID',
    name varchar(30) null default null comment '姓名',
    age int(11) null default null comment'年龄',
    email varchar(50) null default null comment '邮箱',
    primary key(id)
);
insert into user(id,name,age,email) values
(1,'Jone',18,'test1@baomiidou.com'),
(2,'Jack',20,'test2@baomiidou.com'),
(3,'Tom',28,'test3@baomiidou.com'),
(4,'Sandy',21,'test4@baomiidou.com'),
(5,'Billie',24,'test5@baomiidou.com');

在这里插入图片描述

添加依赖

<dependency>
     <groupId>com.baomidou</groupId>
       <artifactId>mybatis-plus-boot-starter</artifactId>
       <version>3.4.1</version>
</dependency>

自动配置原理

  1. 配置类
  2. 存在这些类吗?
  3. 是唯一的数据源吗?
  4. 绑定的配置信息的配置类,前缀为mybatis-plus
  5. 在数据源和 driver配好了的环境下才开始mybatisplus的自动配置
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisPlusProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisPlusLanguageDriverAutoConfiguration.class})
public class MybatisPlusAutoConfiguration implements InitializingBean {}

自动配置类中

  • sqlSessionFactory 自动配置好
  • mapperLocations 自动配置好 classpath*:/mapper/**/*.xml,也就是任意包的类路径下的所有mapper文件夹下的所有xml都是映射文件,因此建议sql的映射文件都放在mapper文件夹下
  • sqlSessionTemplate 自动配置好
  • @Mapper 标注的接口也会被自动扫描

mybatis plus的优点就是,继承basemapper就自带了数据库的一些简单方法

public interface UserMapper extends BaseMapper<User> {
}

service接口

public interface UserService extends IService<User> {
}

serviceimpl实现

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

都是为了减轻对于数据库操作的实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值