SpringBoot的web开发

1 SpringBoot的web开发

2 静态资源映射

项目中有许多的静态资源,比如css,js等文件, Spring Boot 项目是以 JAR 包的形式进行部署的,不存在 webapp 目录,那么SpringBoot怎么处理呢?

Spring Boot 默认为我们提供了 3 种静态资源映射规则

  • WebJars 映射
  • 默认资源映射
  • 静态首页(欢迎页)映射

Webjars 映射

Webjars本质就是以jar包的方式引入我们的静态资源 , 我们以前要导入一个静态资源文件,直接导入即可。

要使用jQuery,我们只要要引入jQuery对应版本的pom依赖即可!(https://www.webjars.org

<dependency>    
    <groupId>org.webjars</groupId>   
    <artifactId>jquery</artifactId> 
    <version>3.4.1</version>
</dependency>

所有通过 WebJars 引入的前端资源都存放在当前项目类路径(classpath)下的“/META-INF/resources/webjars/” 目录中。

默认静态资源映射

项目中使用自己的静态资源该怎么导入呢?

以下四个目录存放的静态资源可以被我们识别:

"classpath:/META-INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"

我们可以在resources根目录下新建对应的文件夹,都可以存放我们的静态文件;

比如我们访问 http://localhost:8080/1.js , 他就会去这些文件夹中寻找对应的静态资源文件;

自定义静态资源路径

在application.properties中配置。一旦自己定义了静态文件夹的路径,原来的自动配置就都会失效了!

3 Thymeleaf模板引擎

SpringBoot项目首先是以jar的方式,不是war,用的还是嵌入式的Tomcat,所以他现在默认是不支持jsp的。

模板引擎的作用就是我们来写一个页面模板,比如有些值呢,是动态的,我们写一些表达式。而这些值,从哪来呢,就是我们在后台封装一些数据。
然后把这个模板和这个数据交给我们模板引擎,模板引擎按照我们这个数据帮你把这表达式解析、填充到我们指定的位置,然后把这个数据最终生成一个我们想要的内容给我们写出去,这就是我们这个模板引擎,不管是jsp还是其他模板引擎,都是这个思想。

4 SpringMVC自动配置

Spring Boot 抛弃了传统 xml 配置文件,通过配置类(标注 @Configuration 的类,相当于一个 xml 配置文件)以 JavaBean 形式进行相关配置。

Spring Boot 对 Spring MVC 的自动配置可以满足我们的大部分需求,但是我们也可以通过自定义配置类(标注 @Configuration 的类)并实现 WebMvcConfigurer 接口来定制 Spring MVC 配置,例如拦截器、格式化程序、视图控制器等等。

http://c.biancheng.net/spring_boot/spring-mvc.html

5 WebMvcConfigurer接口详解

1 什么是WebMvcConfigurer

WebMvcConfigurer配置类其实是Spring内部的一种配置方式,采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制,可以自定义一些Handler,Interceptor,ViewResolver,MessageConverter。

基于java-based方式的spring mvc配置,需要创建一个配置类(@Configuration)并实现WebMvcConfigurer 接口;

举例:

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    /* 视图跳转控制器 */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
    }
}

2 WebMvcConfigurer接口常用的方法

 /* 拦截器配置 */
void addInterceptors(InterceptorRegistry var1);
/* 视图跳转控制器 */
void addViewControllers(ViewControllerRegistry registry);
/**
  *静态资源处理
**/
void addResourceHandlers(ResourceHandlerRegistry registry);
/* 默认静态资源处理器 */
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
/**
  *这里配置视图解析器
 **/
void configureViewResolvers(ViewResolverRegistry registry);
/* 配置内容裁决的一些选项*/
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
/** 解决跨域问题 **/
public void addCorsMappings(CorsRegistry registry) ;

详解(作者:xiari1991):https://www.jianshu.com/p/23afaf36cfa1

3 addViewControllers视图跳转控制器

以前写SpringMVC的时候,如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面,感觉好麻烦。
其实重写WebMvcConfigurer中的addViewControllers方法即可达到效果

4 addInterceptors拦截器

addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例
addPathPatterns:用于设置拦截器的过滤路径规则;addPathPatterns("/**")对所有请求都拦截
excludePathPatterns:用于设置不需要拦截的过滤规则

拦截器主要用途:进行用户登录状态的拦截,日志的拦截等。

用户登录状态的拦截

//登录拦截
public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //用request.getSession().getAttribute(key)获取的session值
        Object loginUser = request.getSession().getAttribute("loginUser");

        if(loginUser == null){  //未登录
            request.setAttribute("msg","没有权限");
            //getRequestDispatcher()包含两个重要方法,分别是请求转发和请求包含
            request.getRequestDispatcher("/index.html").forward(request,response);
            return false;
        }else
            return true;
    }
}
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    /* 登录拦截器配置 */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginHandlerInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/index.html", "/", "/user/login", "/asserts/**");
    }
}

6 JDBC访问数据库

对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。

1 导入 JDBC 场景启动器、数据库驱动

在 pom.xml 中导入 JDBC 场景启动器:spring-boot-starter-data-jdbc、 MySQL 的数据库驱动:mysql-connector-java

2 编写yaml配置文件连接数据库

spring:
  thymeleaf:
    cache: false
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 12345
    url: jdbc:mysql://localhost:3306/springbootweb?useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=UTC

3 测试能否连接成功

@SpringBootTest
class Springboot04DataApplicationTests {
    @Resource
    DataSource dataSource;
    @Test
    public void contextLoads() throws SQLException {
        System.out.println(dataSource.getClass());
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        //关闭
        connection.close();
    }
    ////////////////////////
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Test
    public void getAll(){
        String sql = "select * from department";
        /没有实体类,怎么获取数据库的数据?万能的map
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
        System.out.println(maps);
    }

}

运行结果:可以看到默认配置的数据源为 : class com.zaxxer.hikari.HikariDataSource , 我们并没有手动配置。HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀;

JDBCTemplate

1、有了数据源(com.zaxxer.hikari.HikariDataSource),然后可以拿到数据库连接(java.sql.Connection),有了连接,就可以使用原生的 JDBC 语句来操作数据库;

2、即使不使用第三方第数据库操作框架,如 MyBatis等,Spring 本身也对原生的JDBC 做了轻量级的封装,即JdbcTemplate。

3、数据库操作的所有 CRUD 方法都在 JdbcTemplate 中。

4、Spring Boot 不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,程序员只需自己注入即可使用

5、JdbcTemplate 的自动配置是依赖org.springframework.boot.autoconfigure.jdbc包下的 JdbcTemplateConfiguration

JdbcTemplate主要提供以下几类方法:

  • execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
  • update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
  • query方法及queryForXXX方法:用于执行查询相关语句;
  • call方法:用于执行存储过程、函数相关语句。
/**
 * @Controller 将当前修饰的类注入SpringBoot IOC容器,
 * 使得从该类所在的项目跑起来的过程中, 这个类就被实例化。
 *
 * @ResponseBody 它的作用简短截说就是指该类中所有的API接口返回的数据,
 * 甭管你对应的方法返回Map或是其他Object,它会以Json字符串的形式返回给客户端,
 * 本人尝试了一下,如果返回的是String类型,则仍然是String。
 */
@RestController
public class JDBCController {
    @Autowired
    JdbcTemplate jdbcTemplate;

    //没有实体类,怎么获取数据库的数据?万能map
    //查询
    @GetMapping("/list")
    public List<Map<String,Object>> userList(){
        String sql = "select * from department";
        List<Map<String, Object>> list_maps = jdbcTemplate.queryForList(sql);
        //System.out.println(list_maps);
        return list_maps;
    }

    //增加
    @GetMapping("/add")
    public String addUser(){
        String sql = "insert into department(id,dname) values(106,'垃圾部')";
        jdbcTemplate.update(sql); //自动提交事务
        return "add_okok";
    }

    //修改
    @GetMapping("/update/{id}")
    public String update(@PathVariable("id")int id){
        String sql = "update department set dname=? where id="+id;
        //封装
        Object o = new Object();
        o = "超级垃圾部";
        jdbcTemplate.update(sql,o);
        return "update_ok";
    }

    //删除
    @GetMapping("/delete/{id}")
    public String delete(@PathVariable("id")int id){
        String sql = "delete from department where id=?";
        jdbcTemplate.update(sql,id);
        return "delete_okok";
    }

}

7 整合Druid数据源

http://c.biancheng.net/spring_boot/druid.html

8 整合MyBatis

1、导入 MyBatis 所需要的依赖

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

2、配置数据库连接信息

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 12345
    url: jdbc:mysql://localhost:3306/springbootweb?useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=UTC

#整合mybatis,重要重要
mybatis:
  # 配置XML映射文件中指定的实体类别名路径
  type-aliases-package: com.yu.pojo
  # 配置MyBatis的xml配置文件路径
  mapper-locations: classpath:mybatis/mapper/*.xml  #映射路径
  # 开启驼峰uName自动映射到u_name
  # map-underscore-to-camel-case: true

3、测试数据库是否连接成功

@Autowired
DataSource dataSource;
@Autowired
JdbcTemplate jdbcTemplate;

@Test
void contextLoads() throws SQLException {
    System.out.println(dataSource.getClass());
    System.out.println(dataSource.getConnection());
    
    String sql = "select * from department";
    List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
    System.out.println(maps);
}

4、创建实体类(实体类的属性名和数据库列名不一致时)

{"id":105,"departmentName":null} //字段名不对应时为null

解决办法:使用resultMap

<mapper namespace="com.yu.DeptDao">
    <resultMap id="deptResultMap" type="User">
    	<!-- 
    		主键字段  
    		    property: 实体类属性名.
    		    column: 库中表的列名
    		    javaType: 数据类型.
    	--> 
        <id property="userId" column="id" javaType="int"></id>
        
        <!-- 非主键字段  --> 
        <result property="userSex" column="sex" javaType="string"></result>
        <result property="userAddress" column="address" javaType="string"></result>
        <result property="userBirthday" column="birthday" javaType="date"></result>
        <result property="username" column="username" javaType="string"></result>
    </resultMap>

    <select id="queryAll"  resultMap="deptResultMap">
        select * from user
    </select>
</mapper>

5、创建mapper目录以及对应的 Mapper 接口

com.yu.mapper.DepartmentMapper.java 接口

//把mapper这个dao==mapper交給Spring管理 ,不用再写mapper映射xml文件,
//自动根据这个添加@Mapper注解的接口生成一个实现类
@Mapper
@Repository
public interface DeptMapper {
    //查询所有
    List<Department> queryDeptList();
    //查一个
    Department queryDeptById(int id);
    //增改删
    int addDept(Department department);
    int updateDept(int id);
    int deleteDept(int id);
}

补充:某些实体类之间肯定有关键关系,比如一对一,一对多等。在mybatis 中用associationcollection
association: 一对一关联(has one)
collection: 一对多关联(has many)

只有在做select查询时才会用到这两个标签,都有三种用法,且用法类似。

<resultMap id="EmployeeMap" type="Employee">
    <!-- 主键 -->
    <id property="id" column="eid"/>
    <!-- 非主键 -->
    <result property="lastName" column="last_name"/>
    <result property="email" column="email"/>
    <result property="gender" column="gender"/>
    <result property="birth" column="birth"/>
    
    <association property="eDepartment"  javaType="Department">
    <id property="id" column="did"/>
    <result property="departmentName" column="dname"/>
    </association>
</resultMap>

6、对应的Mapper映射文件

resourses/mybatis/mapper/DepartmentMapper.xml

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
<mapper namespace="com.yu.mapper.DeptMapper">

    <select id="queryDeptList" resultType="Department">
        select * from department
    </select>
    <select id="queryDeptById" resultType="Department">
        select * from department where id=#{id}
    </select>
    <insert id="addDept" parameterType="Department">
        insert into department(id,dname) values (#{id},#{dname})
    </insert>
    <update id="updateDept" parameterType="Department">
        update department set id=#{id},dname=#{dname} where id=#{id}
    </update>
    <delete id="deleteDept" parameterType="int">
        delete from department where id=#{id}
    </delete>
</mapper>

7、maven配置资源过滤问题

8、测试

@RestController
public class DeptController {
    @Autowired
    private DeptMapper deptMapper;
    
    @GetMapping("/list")
    public List<Department> queryDeptList(){
        List<Department> departments = deptMapper.queryDeptList();
        //System.out.println(departments);
        return departments;
    }
}
posted @ 2022-03-26 20:22  yu10001  阅读(149)  评论(0编辑  收藏  举报