Spring boot2

系统要求

Java 8 https://www.java.com/ & 兼容java14 .
Maven 3.3+
idea 2019.1.2

Maven配置

 <mirrors> 
 		<mirror> 
 			 <id>nexus-aliyun</id> 
 			 <mirrorOf>central</mirrorOf>
 			 <name>Nexus aliyun</name>  
 			 <url>http://maven.aliyun.com/nexus/content/groups/public</url>
 	    </mirror> 
 </mirrors> 
 <profiles>
 	 <profile> 
 	 	<id>jdk-1.8</id>
 	 	 <activation> 
 	 	 	<activeByDefault>true</activeByDefault>
 	 	 	<jdk>1.8</jdk>
 	 	 </activation>
 	 	 <properties>
 	 	 	<maven.compiler.source>1.8</maven.compiler.source> 
 	 	 	<maven.compiler.target>1.8</maven.compiler.target> 
 	 	 	<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
 	 	 </properties>
 	 </profile>
</profiles>

简单的 Hello 实例

  1. Controller Hello类
@RestController
public class Hello {

    @RequestMapping("/hello")
    public String handle(){
        return "您好";
    }
}
  1. 和Controller同级的主程序类
@SpringBootApplication
public class DemoApplication {

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

}

3、POM文件

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

springboot --springmvc

1、自动配好SpringMvc
2、自动配好Web常见功能:如字符编码问题
3、默认包结构

主程序所在包及其下面的包都是默认扫描,无需配置扫描器
想要改变扫描路径:
@SpringBootApplication(scanBasePackages=“com.atguigu”)

开发小技巧

  1. Lombox
添加插件
<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

1.1、lombox的注解

@AllArgsConstructor // 全参构造器
@NoArgsConstructor  // 无参构造器
@ToString  // toString
@Data      // get()  set()方法组

2、springboot的热部署Ctrl+F9 更改代码实时生效

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

3、Spring Initailizr

file + new + project +Spring Initailizr+next + next
在Dependenies 页面下,选择spring boot开发的依赖,实现简化创建spring boot项目

4、项目打包jar

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

打包过程

yaml的用法

语法

1、字面量:单个的、不可再分的值。date、boolean、string、number、null
	k: v
2、对象:键值对的集合。map、hash、set、object
 k: 
  k1: v1 
  k2: v2 
  k3: v3
或者
k: {k1:v1,k2:v2,k3:v3}

3、数组:一组按次序排列的值。array、list、queue
行内写法: k: [v1,v2,v3]
或者
k: 
 - v1 
 - v2 
 - v3

1、bean包
1.1 Person类

@ConfigurationProperties(prefix = "person")  // person和yaml文件person一致,引用
@Component
@ToString
@Data
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;
}

1.2 Pet 类

@Data
@ToString
public class Pet {
    private String name;
    private Double weight;
}

2 contriller包
2.1 测试类

@RestController
public class test {

    @Autowired
    Person person;

    @RequestMapping("/person")
    public Person person(){
        return person;
    }
}

3 .resources下application.yaml文件

person:
  userName: "李双 \n 李丹"
#  双引号换行,单引号输出 \n
  boss: true
  birth: 2019/12/9
  age: 18
  interests: [篮球,足球]
  animal: [,]
  score: {s: 80,d: 20}
  salarys: [3999,4999.98,5999.99]
  pet:
    name: "榴莲"
    weight: 18.99
  allPets:
    sick:
      - {name: "小白",weight: 99.99}
      - name: "小花"
        weight: 88.88
      - name: "小黑"
        weight: 77.77
    health:
      - {name: "小胖",weight: 199.99}
      - {name: "小壮",weight: 299.99}

结果:http://localhost:8080/person

{"userName":"李双 \n 李丹","boss":true,"birth":"2019-12-08T16:00:00.000+00:00","age":18,"pet":{"name":"榴莲","weight":18.99},"interests":["篮球","足球"],"animal":["猫","狗"],"score":{"s":80,"d":20},"salarys":[3999.0,4999.98,5999.99],"allPets":{"sick":[{"name":"小白","weight":99.99},{"name":"小花","weight":88.88},{"name":"小黑","weight":77.77}],"health":[{"name":"小胖","weight":199.99},{"name":"小壮","weight":299.99}]}}

静态资源

1、 静态资源路径

只要静态资源放在类路径下: /static (or /public or /resources or /META-INF/resources
访问 : 当前项目根路径/ + 静态资源名

2、欢迎页

静态资源路径下 index.html 可以配置静态资源路径 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问

请求处理

1、 rest请求处理

1、在application.yaml文件开启

# rest风格的请求
spring:
  mvc:
    hiddenmethod:
      filter:
        enabled: true

2、

/user
GET-获取 DELETE-删除 PUT-修改 POST-保存

@RestController
public class Hello {

    @RequestMapping("/hello")
    public String hello(){
        return "财源广进";
    }

//    @RequestMapping(value = "/user",method = RequestMethod.GET)
    @GetMapping("/user")
    public String getUser(){

        return "获取user";
    }
//    @RequestMapping(value = "/user",method = RequestMethod.POST)
    @PostMapping("/user")
    public String postUser(){

        return "保存user";
    }
//    @RequestMapping(value = "/user",method = RequestMethod.PUT)
    @PutMapping("/user")
    public String putUser(){

        return "修改user";
    }
//    @RequestMapping(value = "/user",method = RequestMethod.DELETE)
    @DeleteMapping("/user")
    public String delUser(){

        return "删除user";
    }

3、前端的表单:

因为有get和post请求方式,但是没有delete和put方式,
所以form表单的method =post 下表明 vuale=“delelte(put)”

测试REST风格
<form action="/user" method="get">
    <input value="REST-GET 提交" type="submit">
</form>
<form action="/user" method="post">
    <input value="REST-POST 提交" type="submit">
</form>
<form action="/user" method="post">
    <input name="_method" type="hidden" value="DELETE">
    <input value="REST-DELETE 提交" type="submit">
</form>
<form action="/user" method="post">
    <input name="_method" type="hidden" value="PUT">
    <input value="REST-PUT 提交" type="submit">
</form>

测试注解


    <li>@PathVariable(路径变量)</li>
    <li>@RequestHeader(获取请求头)</li>
    <li>@RequestParam(获取请求参数)</li>
    <li>@CookieValue(获取cookie)</li>
    <li>@RequestAttribute(获取request域属性)</li>
    <li>@RequestBody(获取请求体)</li>
    <li>@MatrixVariable(矩形变量)</li>

1、@PathVariable 路径变量

路径:http://localhost:8080/car/3/owner/lisi

<a href="/car/3/owner/lisi">car/{id}/owner/{username}</a>

测试

@RestController
public class ParameterTest {

    // car 2 owner zhangsan
    @GetMapping("/car/{id}/owner/{username}")
    public Map<String,Object> getCar(@PathVariable("id") Integer id,
                                     @PathVariable("username") String name,
                                     @PathVariable Map<String,String> pv
    ){
        Map<String,Object> map = new HashMap<>();
        map.put("id",id);
        map.put("name",name);
        map.put("pv",pv);
        return map;
    }
}

结果

{“pv”:{“id”:“3”,“username”:“lisi”},“name”:“lisi”,“id”:3}

2、RequestHeader 获取请求头

<a href="/car/3/owner/lisi">car/{id}/owner/{username}</a>
 @GetMapping("/car/{id}/owner/{username}")
    public Map<String,Object> getCar(
                                     @RequestHeader("User-Agent") String userAgent,
                                     @RequestHeader Map<String,String> header
    ){


        Map<String,Object> map = new HashMap<>();
        map.put("userAgent",userAgent);
        map.put("header",header);
        return map;
    }

结果打印出json格式的请求头内容

"header":{"host":"localhost:8080","connection":"keep-alive","sec-ch-ua":"\" Not;A Brand\";v=\"99\", \"Microsoft Edge\";v=\"91\", \"Chromium\";v=\"91\"","sec-ch-ua-mobile":"?0","upgrade-insecure-requests":"1","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.41","accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9","sec-fetch-site":"same-origin","sec-fetch-mode":"navigate","sec-fetch-user":"?1","sec-fetch-dest":"document","referer":"http://localhost:8080/","accept-encoding":"gzip, deflate, br","accept-language":"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"},"userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.41","id":3}

3、@RequestParam 请求参数

<a href="/car/3/owner/lisi?age=18&inters=lianqiu&inters=zuqiu">car/{id}/owner/{username}</a>
 // car 2 owner zhangsan
    @GetMapping("/car/{id}/owner/{username}")
    public Map<String,Object> getCar(
                                     @RequestParam("age") Integer age,
                                     @RequestParam("inters") List<String> inters

    ){
        Map<String,Object> map = new HashMap<>();
        map.put("inters",inters);
        map.put("age",age);
        return map;
    }

结果

{“inters”:[“lianqiu”,“zuqiu”],“age”:18}

4、@RequestBody获取请求体

表单

<form action="/save" method="post">
    测试@RequestBody获取数据<br/>
    用户名:<input name="userName" /><br/>
    邮箱: <input name="email"/>
    <input type="submit" value="提交"/>
</form>
    /// 获取请求体@RequestBody  POST请求
    @PostMapping("/save")
    public Map postMethod(@RequestBody String content){
        Map<String,Object> map = new HashMap<>();
        map.put("content",content);
        return map;
    }

结果

{“content”:“userName=lishuang&email=1111”}

5、@RequestAttribute获取request域属性

@Controller
public class RequestAttribute {

    @GetMapping ("/goto") //http://localhost:8080/goto
    public String goToPage(HttpServletRequest request){

        request.setAttribute("msg","OK");
        request.setAttribute("code","200");

        return "forward:/success"; // 转发到 /success请求
    }

    @ResponseBody
    @GetMapping("/success")
    public Map success(@org.springframework.web.bind.annotation.RequestAttribute("msg") String msg,
                       @org.springframework.web.bind.annotation.RequestAttribute("code") Integer code){

        Map<String,Object> map = new HashMap<>();
        map.put("msg",msg);
        map.put("code",code);
        return map; 
    }
}

结果

//{“msg”:“OK”,“code”:200}

6、@MatrixVariable矩形变量

开启矩形变量

@Configuration(proxyBeanMethods = false)
public class WebConfig {


    // 开启矩阵变量
    @Bean
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer() {
            @Override
            public void configurePathMatch(PathMatchConfigurer configurer) {
                UrlPathHelper urlPathHelper = new UrlPathHelper();
                urlPathHelper.setRemoveSemicolonContent(false);
                configurer.setUrlPathHelper(urlPathHelper);
            }
        };
    }

矩阵变量需要在spring boot中手动开启
根据RFC3986的规范,矩阵变量应当绑定在路径变量中
若有多个矩阵变量,应使用英文;进行分隔
若一个矩阵变量有多个值,应使用英文,分隔,或者命名多个重复的key即可
如:/cars/sell;low=34;brand=byd,audi,yd

链接

<a href="/cars/sell;low=34;brand=byd,audi,yd">@MatrixVariable(矩阵变量)</a>
<a href="/cars/sell;low=34;brand=byd;brand=audi;brand=yd">@MatrixVariable(矩阵变量)</a>
<a href="/boss/1;age=20/2;age=10">@MatrixVariable(矩阵变量)/boss/{bossId}/{empId}</a>
// /cars/sell;low=34;brand=byd,audi,yd  默认禁用矩形变量功能  WebConfi文件配置开启
    @ResponseBody
    @GetMapping("/cars/{path}")
    public Map carsSell(@MatrixVariable("low") Integer low,
                        @MatrixVariable("brand") List<String> brand,
                        @PathVariable String path){
        Map<String,Object> map = new HashMap<>();
        map.put("low",low);
        map.put("brand",brand);
        map.put("path",path);
        return map;

    }

结果

http://localhost:8080/cars/sell;low=34;brand=byd,audi,yd
{“path”:“sell”,“low”:34,“brand”:[“byd”,“audi”,“yd”]}

   //  /boss/1;age=20/2;age=10
    @ResponseBody
    @GetMapping("/boss/{bossId}/{empId}")
    public Map boss(@MatrixVariable(value = "age",pathVar = "bossId") Integer bossAge,
                    @MatrixVariable(value = "age",pathVar = "empId") Integer empAge){
        Map<String,Object> map = new HashMap<>();
        map.put("bossAge",bossAge);
        map.put("empAge",empAge);
        return map;

    }

结果

http://localhost:8080/boss/1;age=20/2;age=10
{“bossAge”:20,“empAge”:10}

Servlet

一般方式

**创建servlet**
@WebServlet(name = "MyServlet", value = "/MyServlet")
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.getWriter().write("999");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

主程序类中必须配置扫描路径

// servlet必须配置扫描路径
@ServletComponentScan(basePackages = "com.example.springboot_admin")
@SpringBootApplication
public class SpringbootAdminApplication {

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

}

servlet拦截器

/**
 * servlet拦截器
 * @author 86130
 */
@Slf4j
@WebFilter(urlPatterns = {"/MyServlet","/login"}) // 指定拦截的路径
public class MyFilter implements Filter {


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("MyFilter初始化完成");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("MyFilter工作");
        // 放行
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        log.info("MyFilter销毁");

    }
}

监听器

@Slf4j
@WebListener
public class MyServletListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("监听到项目初始化完成");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("监听到项目销毁");
    }
}

RegistrationBean方式 将上面的@WebListener@WebFilter和@WebServlet注释掉

@Configuration
public class MyRegistConfig {

    // 将servlet放入容器
    @Bean
    public ServletRegistrationBean myServlet() {
        MyServlet myServlet = new MyServlet();
        // 设置servlet的访问路径 一个servlet可以设置多个路径
        return new ServletRegistrationBean(myServlet,"/my","/my2");
    }
    // 拦截器
    @Bean
    public FilterRegistrationBean myFilter(){
        MyFilter myFilter = new MyFilter();
        // 拦截myServlet中的路径
//        return new FilterRegistrationBean(myFilter,myServlet());
        // 设置拦截的路径
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/login"));
        return filterRegistrationBean;
    }

    // 监听器
    @Bean
    public ServletListenerRegistrationBean myListener(){
        MyServletListener myServletListener = new MyServletListener();
        return new ServletListenerRegistrationBean(myServletListener);
    }
}

数据访问

JDBC连接mysql数据库

1、加载依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

2、在yaml文件中配置MySQL

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver

    # 3秒没查出来超时
  jdbc:
    template:
      query-timeout: 3

3、在Test文件夹下的测试文件测试

@Slf4j
@SpringBootTest
class SpringbootAdminApplicationTests {
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Test
    void contextLoads() {
        Long along = jdbcTemplate.queryForObject("select count(*) from student",long.class);
        log.info("总数{}",along);
    }

}

druid 连接数据源,注意druid和mysql的版本问题(or 404)
https://github.com/alibaba/druid

1、添加依赖

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>

2、写配置类

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver

  druid:
    aop-patterns: com.example.springboot_admin.*
    filters: stat,wall

    stat-view-servlet:
      enabled: true
      login-password: admin
      login-username: admin
      resetEnable: false

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

    filter:
      stat:
        slow-sql-millis: 1000
        log-slow-sql: true
        enable: true
      wall:
        enable: ture
        config:
          drop-table-allow: false

#      3秒没查出来超时
  jdbc:
    template:
      query-timeout: 3

3、测试
localhost:8080/druid/ 进入druid监控页面

整合Mybatis

Mybatis文档:https://mybatis.org/mybatis-3/zh/index.html
在这里插入图片描述

配置版

1、 导入mybatis依赖

 <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>

2、mybatis-config.xml全局配置文件

<?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>

</configuration>

3、AccountMapper.xml SQL文件

<?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.example.springboot_admin.mapper.AccountMapper">

<!--public Account getAcct(Long id);-->
    <select id="getAcct" resultType="com.example.springboot_admin.bean.Account">
        select * from account_tbl where id=#{id}
    </select>


</mapper>

4、mapper AccountMapper接口

@Mapper
public interface AccountMapper {
    public Account getAcct(Long id);
}

5、数据表的实体类Account

注意:变量名和表的字段一致(可驼峰命名)


@Data
public class Account {
    private Long id;
    private String userId;
    private Integer money;

}

6、service下服务类AccountService

@Service
public class AccountService {
    @Autowired
    AccountMapper accountMapper;

    public Account getAcctByid(Long id){
        return accountMapper.getAcct(id);
    }

}

7、控制层MyMybatisTest类

@Controller
public class MyMybatisTest {

    @Autowired
    AccountService accountService;

    @ResponseBody
    @GetMapping("/acct")
    public Account getById(@RequestParam("id") Long id){

        return accountService.getAcctByid(id);
    }


}

8、yaml配置文件

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
#      3秒没查出来超时
  jdbc:
    template:
      query-timeout: 3
mybatis:
#  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml
  configuration: #指定mybatis全局配置文件中二点想换配置项
    map-underscore-to-camel-case: true #开启驼峰

9、结果
http://localhost:8080/acct?id=1

{“id”:1,“userId”:“1001”,“money”:1000}

注解版

1、 导入mybatis依赖

 <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>

2、写表的实体类bean.City

注意:变量名和表的字段一致(可驼峰命名)

@Data
public class City {
    private Long id;
    private String name;
    private String state;
    private String country;
}

3、写接口mapper.CityMapper

@Select(“select * from city where id = #{id}”) 代替资源文件mapper下的xml文件

@Mapper
public interface CityMapper {
    @Select("select * from city where id = #{id}")
    public City getById(Long id);
}

4、服务类service.CityService

@Service
public class CityService {
    @Autowired
    CityMapper cityMapper;

    public City getById(Long id){
        return cityMapper.getById(id);
    }
}

5、Controller 类controller.MyMybatisTest

@Controller
public class MyMybatisTest {
    @Autowired
    CityService cityService;
    
    @ResponseBody
    @GetMapping("/city")
    public City getCityById(@RequestParam("id") Long id){
        return cityService.getById(id);
    }
}

6、yaml文件和配置版一致
7、结果
http://localhost:8080/city?id=1

{“id”:1,“name”:“南京”,“state”:“江苏”,“country”:“中国”}

混合版(以City表为例) Sql复杂用配置文件 简单用注解

1、写接口mapper.CityMapper

@Mapper
public interface CityMapper {
    // 混合版
    public void insert(City city);
}

2、resource下的mapper下的CityMapper.xml文件

useGeneratedKeys=“true” keyProperty=“id” 显示自增字段的值,不加这个 值为null

<?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.example.springboot_admin.mapper.CityMapper">

<!-- public void insert(City city);
useGeneratedKeys="true" keyProperty="id" 显示自增字段的值,不加这个 值为null
-->
    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into city(name,state,country) values (#{name},#{state},#{country})
    </insert>

</mapper>

或者注解

@Mapper
public interface CityMapper {
    // 混合版
    @Insert("insert into city(name,state,country) values (#{name},#{state},#{country}")
    @Options(useGeneratedKeys = true,keyProperty = "id")
    public void insert(City city);
}

3、service.CityServiice

@Service
public class CityService {
    @Autowired
    CityMapper cityMapper;
    public void saveCity(City city) {
        cityMapper.insert(city);
    }
}

4、控制层controller.MyMybatisTest

@Controller
public class MyMybatisTest {

    @Autowired
    CityService cityService;

    // 混合版   插入
    @ResponseBody
    @PostMapping("/insertCity")
    public City saveCity(City city){
        cityService.saveCity(city);
        return city;
    }
}

5、yaml文件不变
6、测试
在这里插入图片描述

简化

Mapper下的文件,每一个类上都加了@mapper注解
可以在主程序类上加@MapperScan(“com.example_admin.mapper”)代替

整合mybatis-plus

mybatis plus 官网 https://baomidou.com/

1、添加依赖

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

2、user表的实体类

@TableField(exist = false) 在对应的变量上,表示该变量在数据库中不存在
若表的名字为user_tbl 和实体类的类名不一致,则需要 在类上@TableName(“user_tbl”)

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

3、mapper接口

public interface UserMapper extends BaseMapper<User> {


}

4、主程序

@MapperScan("com.example.springboot_admin.mapper")
@SpringBootApplication
public class SpringbootAdminApplication {

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

}

5、测试类

@Slf4j
@SpringBootTest
class SpringbootAdminApplicationTests {

    @Autowired
    UserMapper userMapper;

    @Test
    void testSelect() {
       User user = userMapper.selectById(1L);
        log.info("msg:{}",user);
    }

}

CRUD演示

以User表为例

1、UserService接口


public interface UserService {
}

2、UserServiceImpl实现类

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

}

不用写具体的方法Ctrl+F12中有很多方法

3、User表的实体类

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

4、UserMapper

public interface UserMapper extends BaseMapper<User> {


}

5、Controller

@Controller
public class MyMybatisTest {

    @Autowired
    UserServiceImpl userService;
    @ResponseBody
    @GetMapping ("/getAllUser")
    public List<User> getAllUser(){
     // list()查询所有
       List<User> list =  userService.list();

        return list;
    }

}

// 分页查询
    @ResponseBody
    @GetMapping ("/getPageUser")
    public Page<User> getPageInfo(@RequestParam(value = "pn",defaultValue = "1") Integer pn){
       // 分页查询数据
        Page<User> userPage = new Page<>(pn,2);
        // 查询条件 为null
        Page<User>  page = userService.page(userPage,null);
   // 当前页数
       Long Current = page.getCurrent();
         // 总页数
        Long Pages =  page.getPages();
        // 总记录数
        Long Total =  page.getTotal();
        // 数据库的数据
        List<User> record = page.getRecords();
        return page;



    }
     // 删除功能
    @ResponseBody
    @GetMapping("/delUser")
    public String delUser(@RequestParam(value = "id") int id){
        userService.removeById(id);
            return "OK";
    }

6、分页插件

@Configuration
public class MyBatisConfig {
    // 最新版
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }
}

NoSql数据库

1、redis自动配置

官网:http://www.redis.cn/
安装教程:https://blog.csdn.net/HBliucheng/article/details/112467680

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
**

1、加入依赖

 <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <version>2.4.0</version>
    </dependency>

2、yaml配置

spring:
	redis:
	    host: 127.0.0.1
	    port: 6379

3、测试类

  // redis
    @Autowired
    StringRedisTemplate redisTemplate;

    @Test
    void testReids(){
        ValueOperations<String,String> operations = redisTemplate.opsForValue();
        operations.set("hello","world");
       String msg = operations.get("hello");
        System.out.println(msg);
    }

redis访问url计数器

1、配置类

@Configuration
public class RedisConfig implements WebMvcConfigurer {

    @Autowired
    RedisUrlCountInterceptor redisUrlCountInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(redisUrlCountInterceptor)
                .addPathPatterns("/**")// 所有请求都被拦截 包括静态资源
                .excludePathPatterns("/"); // 放行的资源
    }

}

2、拦截计数器

// 拦截 计数器
@Component
public class RedisUrlCountInterceptor implements HandlerInterceptor {

    @Autowired
    StringRedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      String uri = request.getRequestURI();

      // 默认每次访问当前uri就会计数+1
        redisTemplate.opsForValue().increment(uri);
        return true;
    }
}

3、运行
http://localhost:8080/getAllUser 运行一次
在这里插入图片描述

单元测试

Junit5

依赖

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

springboot测试类

@SpringBootTest
class SpringbootAdminApplicationTests {

    @Test
    void testSelect() {
     
    }


}

SpringBoot整合Junit以后。
编写测试方法:@Test标注(注意需要使用junit5版本的注解)
Junit类具有Spring的功能,@Autowired、比如 @Transactional 标注测试方法,测试完成后自动回滚

Junit5常用注解

https://junit.org/junit5/docs/current/user-guide/#writing-tests-annotations <https://junit.org/junit5/docs/current/user-guide/#writing-tests- annotations>

@RepeatedTest :表示方法可重复执行,下方会有详细介绍
@DisplayName :为测试类或者测试方法设置展示名称
@BeforeEach :表示在每个单元测试之前执行
@AfterEach :表示在每个单元测试之后执行
@BeforeAll :表示在所有单元测试之前执行
@AfterAll :表示在所有单元测试之后执行
@Tag :表示单元测试类别,类似于JUnit4中的@Categories
@Disabled :表示测试类或测试方法不执行,类似于JUnit4中的@Ignore
@Timeout :表示测试方法运行如果超过了指定时间将会返回错误
@ExtendWith :为测试类或测试方法提供扩展类引用

@DisplayName

@DisplayName("Junit5注解的测试")
public class Junit5Test {

    @DisplayName("测试DisplayName")
    @Test
    void testDisplayName(){
        System.out.println(11);
    }
}

结果

在这里插入图片描述

profile生产/开发环境的切换

1、application-test.yaml开发环境

person:
  name: test-张三

2、application-prod.yaml 生产环境

person:
  name: prod-张三

3、Controller

@RestController
public class ProfileController {


    // person.name值取不到,就用李四
    @Value("${person.name}:李四")
    public String name;


    @GetMapping("/test")
    public String testPro(){
        return "你好:"+name;
    }
}

4、切换环境 application.properties

#spring.profiles.active=prod
spring.profiles.active=test

若将项目打jar包后,想改变环境:
jar包目录下cmd:java -jar xxx.jar --spring.profiles.active=prod --person.name=haha
修改配置文件的任意值,命令行优先

5、想让一个类或者方法在生产/开发环境下执行

在类或者方法上加入:
@Profile(“prod”)
/或者

@Profile(“test”)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值