昆明市网站制作公司,wordpress mx主题VIP,云南通耀建设工程有限公司网站,有高并发,高访问量网站开发写在前面
推荐将本文与Spring Boot 相关知识和工具类一文结合起来看#xff0c;本文为主#xff0c;上面那篇文章为辅#xff0c;一起食用#xff0c;以达到最佳效果#xff0c;当然#xff0c;大佬随意。
IDEA创建Spring Boot工程
关于Spring Boot框架项目#xff0…写在前面
推荐将本文与Spring Boot 相关知识和工具类一文结合起来看本文为主上面那篇文章为辅一起食用以达到最佳效果当然大佬随意。
IDEA创建Spring Boot工程
关于Spring Boot框架项目IDEA为我们提供了比较快捷的创建方式如下:
点击右上角的file,选择Project Structure,如下图: 选择左侧的Modules,点击上面的加号,如下图: 选择New Module 左边一栏选择Spring Initializr,右边一栏配置项目相关属性如下图: 项目工程名项目工程存储地址自定义项目工程类型Type选择Maven,语言Language选择Java,后面三项建议不要改直接默认即可项目工程的软件开发工具包project SDK选择你自己安装的java JDK版本(我安装的是JDK 17)字段java 选择你自己安装的java JDK版本号我这里选择的是17,包类型 Packaging选择Jar。 5.点击Next后选择该工程需要的依赖这里我因为需要来开发Web应用因此添加了Spring Web的依赖又因为我选择了MySQL数据库来存储数据因此我又添加了MySQL的依赖。 选好依赖后点击Finish,整个Spring Boot项目创建就完成了。
Spring Boot整合Mybatis
在SpringBoot的配置文件pom.xml中引入Mybatis的起步依赖 引入好配置后就可以正常使用Mybatis了。
Mybatis 前后端交互详解 如上图所示:
controller层是故意暴露出来的里面是一些接口用来与前端页面进行交互。service层全是各种方法的接口用来保护后端方法逻辑的具体实现防止其源码泄露该层作用类似于反向代理每个接口都对应着一个具体方法的实现。service层后面是implement逻辑层它是整个系统的核心部分用来与数据库进行交互实现对应的所有后端逻辑与前面的service层中的接口一一对应保证程序的正常进行。再往后面走就是dao层即数据库该层用于存放所有可以与数据库进行交互的方法接口是十分重要的地方。mapper层是dao层中数据库方法接口的具体实现,与dao层方法接口一一对应。
前后端交互代码具体实现
项目的具体结构图: OneSpringbootApplication 是启动类运行该文件整个项目就启动了。
连接数据库: 打开resource目录下的application.properties文件,在里面配置数据库相关信息如上图红框所示。 spring.datasource.driver-class-name作用:设置JDBC驱动类的完全限定名。com.mysql.cj.jdbc.Driver 是MySQL Connector/J 8.0的JDBC驱动类它告诉Spring Boot应用程序要使用哪个类来加载和连接MySQL数据库。 spring.datasource.url作用:设置数据库连接的URL(即数据库所在路径),jdbc:mysql://localhost:3306/test233 表示数据库服务器运行在本地主机localhost使用3306端口并且想要连接名为test233的数据库。 spring.datasource.username和spring.datasource.password作用是用来记录数据库的用户名和密码。 mybatis.configuration.map-underscore-to-camel-casetrue 作用是开启驼峰名与下划线命名之间的转换(驼峰命名eatFood,下划线命名eat_food) 使用上述数据库配置前提是你已经将数据库驱动依赖添加到了项目的配置文件中(Maven的pom.xml)
controller 层: //注解RestController用于标记一个类表明该类是一个
//控制器并且其下的方法都将前端页面的返回数据作为响应
//(即处理前端页面的http请求)RestController
public class HelloController {//注解RequestMapping用于将http请求和处理请求的控制器方法(类方法)//关联起来建立映射关系// 该注解有一个参数value其作用就是设置请求路径设置当客户端发送何种请求时//下面的方法才会处理该请求//该注解的参数value是一个String类型的数组也就是其中可以存放多个数据//当前端向/hello发出请求时,下面的函数就会接收到请求//并自动调用来处理该请求RequestMapping(/hello)public String hello() {return hello world!;}//Autowired 注解用于将下面的对象(已经通过组件扫描注册到了IOC容器中)通过
//依赖注入 从IOC容器中注入到字段(这里字段是“userService”)中以供使用
// 该对象必须被IOC容器视为一个BeanAutowiredprivate UserService userService;RequestMapping(/findById)public book findById(Integer ID){return userService.findById(ID);}
}
service 层的项目结构: service层的接口: //该接口只是一个普通的接口因此需要一个专门的类来实现这个接口中的方法
public interface UserService {public book findById(Integer ID);
}
service层的接口的具体实现(impl层):
//Service注解用于标识一个类作为服务层组件
Service
public class UserServiceImpl implements UserService {//IOC容器通俗解释就是一个负责管理对象生命周期和对象间关系的“大管家”,//具体来说当我们需要某个对象时我们不再直接在代码中创建它而是告诉//IOC容器我们需要这个对象,容器会根据我们的请求和配置信息自动创建对象//并处理对象之间的依赖关系,以及一切与项目本身业务逻辑无关的东西//(这个对象在项目开始运行时就已经提前创建好了)// 我们想要使用直接从容器的取出即可并且容器中已创建的对象可以被本项目其他//地方共享和使用这种对象就是统称为Bean//一般被Spring框架提供的注解标注了的类它们的对象都会被Spring容器视为Bean//(Spring容器就是IOC容器)//类本身不是Bean,类对应的实例才是Bean//Autowired 注解用于将下面的对象(已经通过组件扫描注册到了IOC容器中)//通过依赖注入 从IOC容器中注入到字段(这里字段是“userMapper”)中以供使用// 该对象必须被IOC容器视为一个BeanAutowiredprivate UserMapper userMapper;//当子类继承父类并重写父类的方法时Override注解可以帮助编译器检查该方法//是否确实重写了父类中的方法// 如果子类的方法名、参数列表和返回类型与父类中的方法不一致那么编译器会//报错提示重写失败,这有助于开发者及时发现并修正重写错误避免运行时错误//的发生//简单来说该注解作用就是表明其下面的方法为重写的方法Overridepublic book findById(Integer ID) { //对UserService接口中的方法进行重写(即接口方法的具体实现)return userMapper.findById(ID);}
}
dao层与mapper层:
//Mapper注解用于标识一个接口为MyBatis的Mapper接口
// 这样MyBatis就能知道这个接口是专门用于操作数据库的进而能够自动为这个
//接口创建一个代理实现类
// 这意味着你可以直接在应用程序中注入这个接口的实例并调用它的方法来执行SQL语句
//而不需要自己手动实现这个接口
// 即直接拿来使用不需要再手动的去定义一个类来专门实现这个接口
Mapper
public interface UserMapper {//Select注解在MyBatis框架中用于直接在Mapper接口的方法上编写SQL查询语句// 从而取代了传统的在XML映射文件中编写SQL语句的方式//Select注解内部可以编写具体的SQL查询语句用于从数据库中查询数据,//Select注解下方的对应方法函数与上面SQL语句成映射关系//调用方法函数就会自动执行上面的SQL语句并将SQL语句的结果作为该方法函数的//返回值进行return//在Select注解的SQL语句中可以使用占位符如#{param}来绑定//下面方法中的参数Select(select * from test233.book where ID#{ID})public book findById(Integer ID);
}
通过上面注解Select和Mapper来将传统的Dao层和Mapper层合在了一起。
实体类层—entity层: public class book {private Integer ID;private String name;public book() {}public book(Integer ID,String name){this.IDID;this.namename;}public Integer getID(){return this.ID;}public void setID(Integer ID){this.IDID;}public String getname(){return this.name;}public void setname(){this.namename;}
}
该层的作用是用于存放一些实体类这些实体类将会被用来接收数据库中对应表的数据一个类对应一张表表的字段就是类的成员变量在前后端数据交互的过程中这些实体类对象接收的数据会被系统自动转换成JSON数据格式。
常用注解
注解Component是一个通用注解可以将标记的类实例作为Bean注入IOC容器中。注解ComponentScan(包路径)用于组件扫描扫描对应路径下的包当没有包路径时默认扫描启动类同级的包和各自下面的子包。 组件扫描:如果遇见被Spring Boot提供的注解标记了的类那么这些类的对象会被视为BeanSpringBoot会自动将这些类实例化并注入IOC容器之中供应用程序在运行时使用若存在组件未被扫描到则系统不会创建组件当中的Bean实例也不会创建该组件与之相关联的其他Bean将会注入失败与之相关联的功能组件将缺失。 注解Bean作用:将标记的方法的返回值交给IOC容器成为IOC容器的bean对象(当Spring容器启动时它会查找Configuration注解的类并调用这些类中的Bean注解的方法将返回的实例注册为Bean,注入到IOC容器当中)。注解RestController用于标记一个类表明该类是一个控制器并且其下的方法都将前端页面的返回数据作为响应(即处理前端页面的http请求)。注解RequestMapping和注解PostMapping都是用于将http请求和处理请求的控制器方法(类方法)关联起来建立映射关系这两个注解都有一个参数value其作用就是设置请求路径设置当客户端发送何种请求时下面的方法才会处理该请求,该注解的参数value是一个String类型的数组也就是其中可以存放多个数据。注解 Post 与 Requst 的区别: Post 它要求被请求服务器要对它所提交的请求进行确认或者处理后才能给予响应相对更加安全效率也相对低点Requst 它是更广泛地用于发送和接收数据,会将参数暴露在Url中相对不安全效率相对高点 注解Autowired 用于将其标记的对象(已经通过组件扫描注册到了IOC容器中)通过依赖注入 从IOC容器中注入到字段(这里字段是“userService”)中以供使用。该对象必须被IOC容器视为一个Bean因为只有这样才能保证IOC容器中拥有该对象。注解Service用于标识一个类作为服务层组件。注解Override可以帮助编译器检查该方法是否确实重写了父类中的方法。注解Mapper用于标识一个接口为Mapper接口,这样MyBatis就能知道这个接口是专门用于操作数据库的进而能够自动为这个接口创建一个代理实现类,这意味着你可以直接在应用程序中注入这个接口的实例并调用它的方法来执行SQL语句而不需要自己手动实现这个接口;即直接拿来使用不需要再手动的去定义一个类来专门实现这个接口。注解RestControllerAdvice 主要用于标注一个类来进行全局异常处理和全局数据绑定,该类中的方法会被同项目的其他程序自动调用,可以用于定义全局响应结果处理程序确保应用程序返回给客户端的响应具有统一的格式和结构,总之该注解作用就是标记其下面的类为一个全局的异常处理和所有数据预处理的中央处理器。注解ExceptionHandler(异常类类名.class) 用来标注处理 异常类 的方法,此处的异常类可以是自定义的异常类,使用该注解可以捕获指定的异常并按照自定义的方法处理该异常,一般与上面的注解配合使用。注解RequestBody用于将 HTTP 请求体中的数据绑定到对应的方法参数上。 PostMapping(/create) public String create(RequestBody MyObject myObject) { // 在这里myObject 已经被自动填充了请求体中的数据 // 你可以直接操作这个对象而不需要手动解析请求体 // ... 处理 myObject 的逻辑 ... return Object created successfully; } 注解ResponseBody:用于标记一个方法的返回值应该被绑定到响应体。然而注解RestController已经默认组合了注解ResponseBody也就是说注解RestController标记的类下面的所有方法的返回值都会自动绑定到了响应体中。 在HTTP通信中请求体Request Body和响应体Response Body是两个重要的概念它们分别代表了HTTP请求和响应中携带的数据部分,里面可以携带的数据类型主要是JSON格式和表单数据。 表单数据当发送一个包含表单字段的HTTP POST请求时请求体可能包含application/x-www-form-urlencoded类型的数据。这种格式将表单字段和值编码为键值对并使用符号分隔,将这些数据放在请求体当中,一同发送给服务器。 queryString格式数据就像是我们给网站地址“附加”一些额外的信息。比如我们想在搜索引擎里搜索“苹果”我们可能会输入http://search.com/?q苹果。这里的?q苹果就是queryString它告诉我们搜索引擎要搜索的关键字是“苹果”。这种方式很适合传递少量、简单的信息。 注解CookieValue:用于绑定cookie值到方法参数。
GetMapping(/cookie)
public String cookie(
CookieValue(JSESSIONID) String sessionId) {
// ...
}
//将cookie中的键JSESSIONID对应的值赋给sessionId注解RequestHeader:用于绑定请求头到方法参数。
GetMapping(/header)
public String header(
RequestHeader(User-Agent) String userAgent) {
// ...
}
//将请求头中的键User-Agent对应的值赋给userAgent注解Validated 主要用于触发方法参数的校验,将它标记在类上告诉系统该类中有方法需要进行参数校验。注解Pattern 用于验证一个字符串是否符合指定的正则表达式(参数regexp存放指定的正则表达式),通常应用于类的字段、属性或方法的参数上以确保输入的数据满足特定的格式要求。 注解NotNull该注解标记的变量的值不能为null。注解NotEmpty该注解标记的变量的值不能为null,且如果是字符串的话,不能为空字符串。注解Email该注解标记的变量必须满足邮箱格式 上面这三个注解是放在实体类中的,当实体类作为方法参数时外部有注解Validated标记且参数本身又是请求体的映射(RequestBody)时其内部的注解才会生效(这只对实体类内部Validation依赖相关的注解有效)。 注解URL 用来判断其标记的参数是否是一个合法的url地址。 注解Test 用于标记一个方法是测试方法这样测试框架就能自动识别并运行它。注解JsonIgnore,该注解标记的成员变量当系统将数据转换成JSON格式时,将会忽略掉该成员变量的值(保护密码不被泄露)注解JsonFormat(pattern yyyy-MM-dd HH-mm-ss) 用来指定存放时间的字段的时间输出的格式(年-月-日 时-分-秒) 数据库相关注解在MyBatis框架中用于直接在Mapper接口的方法上编写SQL语句从而取代了传统的在XML映射文件中编写SQL语句的方式这些数据库相关注解其内部可以编写具体的SQL查询语句用于从数据库中增删查改数据,数据库相关注解下方的对应方法函数与上面SQL语句成映射关系,调用方法函数就会自动执行上面的SQL语句并将SQL语句的结果作为该方法函数的返回值进行return,在数据库相关注解的SQL语句中可以使用占位符如#{param}来绑定标记的方法中的参数。 数据库相关注解有:
注解Select用于标注查询语句注解Insert用于标注插入语句注解Update用于标注更新语句注解Delete用于标注删除语句
传统xml文件映射(配置动态的SQL语句)
在Mapper接口层,可以直接使用注解来将SQL语句映射绑定到对应方法上如下: Mapper
public interface CategoryMapper {//新增文章分类Insert(insert into big_event.category(category_name, category_alias, create_user, create_time, update_time) value(#{category.categoryName},#{category.categoryAlias},#{category.createUser},now(),now()))public void addCategory(Category category);//通过文章的分类名查找分类Select(select * from big_event.category where category_name#{categoryName})public Category findByCategoryName(String categoryName);//通过文章的分类ID查找分类Select(select * from big_event.category where id#{id})public Category findById(Integer id);//通过用户ID获得其创建的所有分类Select(select * from big_event.category where create_user#{userId})public ListCategory findByCreateUser(Integer userId);}但是上面却无法映射绑定动态的SQL语句到对应方法上要想映射动态的sql语句就只要采用传统的数据库映射方式----xml文件映射。
xml映射文件要求
xml配置文件必须放在resources 目录下,在该目录下它的路径必须与Mapper层接口所在路径一致。 例如Mapper层接口路径:com.example.two_project.mapper,那么对应的xml文件路径就必须是resources/com/example/two_project/mapper xml文件配置动态SQL语句
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.two_project.mapper.ArticleMapper
!-- namespace 必须是对应的Mapper层接口的全类名 --select idlist resultTypecom.example.two_project.entity.Articleselect * from big_event.articlewhereif teststate!nullstate#{state}/ifif testcategoryIdand category_id#{categoryId}/ifand create_user#{id}/where/select/mapperselect 标签就表示Select语句,属性id为该条SQL语句对应的函数的函数名, 属性resultType为数据库查询结果的每一条数据的返回类型(即该表对应的实体类的全类名) where 标签就是SQL语句中的where,与一般的where相比它的区别是它可以通过if的判断来动态地改变查询条件 if 标签中的test参数为判断条件如果条件满足则将标签内的语句加入where当中且若这是where中的第一个条件 那么该条件前面的and将会被省略,若不满足则不将标签内的语句加入. 文件对应的映射方法中的参数可以直接在标签中使用
xml映射文件的配置
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespaceSpring Boot 配置文件
配置文件的格式
Spring Boot的配置文件有两种格式分别是.properties和.yaml/yml,两种配置文件的作用并没有什么区别只是写法上有所不同: 在企业级开发中更加常用的是.yml格式的文件 书写配置信息
不只是.yml格式的配置文件.properties格式也是一样的它们都可以用来书写第三方技术配置信息也可以来书写自定义的配置信息当书写自定义配置信息时如下图: 将程序中的一些静态属性放在一起写成一个配置文件这样当属性发生变化时就不用改代码只需要修改配置文件然后重启服务器即可。 如上图所示是书写.yml配置文件的一些要求。 如上图中的属性hobbies,表示该属性是一个数组类型格式: - 数组中的元素
获取配置信息
当属性写入属性文件后在代码中我们该如何获取这些属性呢? 如上图所示通过注解Value({键名})来获得对应的属性该注解下面的变量就是用来接收对应属性(键)的值的。但是如果属性过多又不想给每一个变量都写注解则可以采用下面这种方法: 如上图在对应的类上面加注解ConfigurationProperties(prefix前缀)(这里的前缀也是在配置文件中由用户自定义的),当使用了该注解后其类下面对应的成员变量名必须与配置文件中同一前缀的属性名相同且一一对应。
Bean 注册
第三方若想注册为Bean(即被SpringBoot自动创建实例并注入IOC容器)只靠在对应类上添加一般的注解是不行的这里就需要特殊的注解了。
第三方注册为Bean方式一
方式一在启动类中添加方法并在该方法上面添加注解Bean,如下图: Bean注解作用:将标记的方法的返回值交给IOC容器成为IOC容器的bean对象(当Spring容器启动时它会查找Configuration注解的类并调用这些类中的Bean注解的方法将返回的实例注册为Bean) 也可以单独开一个配置类(注解configuration标记的类)的文件将所有想注册为Bean的第三方集中处理如下图: 如果在注解Bean标记的方法中想使用在IOC容器中已经注册的Bean对象那么只需要在方法上声明即可spring会自动的注入如下图(country是已经在IOC容器中注册好的Bean对象)。 第三方注册为Bean方式二
方式二, 通过注解Import将对应的第三方类引入Spring容器会自动将其类的对象注册为Bean注入IOC容器中。
引入格式:Import(xxx.class)引入位置:整个项目的启动文件当中。 Import(类名.class)其中引入的这个类可以普通类也可以是配置类(configuration标记了的类),或者是ImportSelector接口实现类。
ImportSelector接口实现类: 如上图所示我们首先要实现ImportSelector这个接口重写其中的 selectImports()方法(该方法是自动调用的)返回值返回一个字符串类型的数组该数组中的每一个字符串都是用户需要注册为Bean对象的类的地址(全类名)。然后注解Import只需要引入这个接口实现类的类名即可这样就避免了因引入的类太多导致代码不美观的问题。
在一般开发中ImportSelector接口实现类的方法的返回值的这个字符串数组一般不是写死的而是从配置文件中读出来的。
在Resources/META-INF/spring/ 目录下创建后缀名为.imports的配置文件里面书写上所有自定义的需要注册为Bean的类的地址(全类名)一个类占一行。
读取配置文件中的信息示例如下图: 如图imports是设置的一个字符串列表用于存放配置文件中的各个类的全类名;is 是获取到的输入流后面的 “common.imports” 是配置文件名,整行代码的作用就是将配置文件中的数据转换成输入流存入变量is中下面的变量br是对输入流的一个封装将其封装成一个缓冲字符流。while循环是用来按照每一行来读取缓冲字符流当中的数据并用字符串变量line来接收将每一行数据添加至字符串列表imports当中所有数据读取完毕后要关闭缓冲字符流br最后将字符串列表转换成字符串数组返回回去。
自定义组合注解 如上图所示选择Annotation,创建自定义的组合注解。 如上图所示上面两个注解都是必不可少的。第一个是表明该自定义注解可以在类上使用第二个表明该自定义注解在系统运行期间一直存在。除了这两个注解其他的均可以自定义。若要使用这个注解就像普通注解一样直接使用即可注解名为创建的组合注解的文件名。常用于实现下图第三条: Bean 的注册条件
用户可以通过注解Conditional的衍生注解来设置对象注册为Bean的条件常用的注解如下图所示。 在配置类中注解Bean所标记的方法其返回值会被注册为Bean我当然可以提前为要注册为Bean的对象赋值如下图在方法的参数上通过注解Value(${键名})来确保每个参数被传入指定的值。注解ConditionalOnProperty(prefix前缀,name{键名1,键名2}) 来判断配置文件中是否存在对应属性若不存在则其下面整个方法的返回值将不再被注册为Bean。 注解ConditionalOnMissingBean(类名.class),如下图所示,如果IOC容器中不存在Country类的Bean对象则执行下面的方法注入Province,否则不注入。 注解ConditionalOnClass(name类的完整路径名),如下图所示如果当前配置环境存在指定的类则执行下面的方法注入Province,否则不注入。
自动配置的原理
自动配置就是在SpringBoot程序启动后起步依赖中的一些Bean对象会自动注入到IOC容器之中。 原理:在jar包内定义了一些类目的是想要这些类的实例作为Bean注入到IOC容器中即自动注入;首先定义一个配置类配置类中用注解Bean来标记方法通过这些方法SpringBoot会将它们返回的实例作为Bean注入到IOC容器中再定义一个自动配置类加上两个注解import(配置类类名.class)和AutoConfiguration;前者引入了配置类,保证其在不同级目录下也可以使用后者标识这是一个自动配置类。最后在项目的resources目录下的META-INF目录下的spring目录下再定义一个后缀名为.imports的文件在文件中加入该自动配置类的全类名;当系统启动时系统会在该目录下(“/resources/META-INF/spring/xxx.imports”)的配置文件中找是否有自动配置类(注解AutoConfiguration标记的类)有就自动调用实例化该类。实例化该类会导致系统通过import访问到配置类配置类中的方法会被自动调用这样就自动配置就搞定了。 Configuration与AutoConfiguration注解的区别:
1. Configuration 必须通过组件扫描才能自动配置Bean若不在启动类的同级目录或子目录下则需要ComponentScan(路径)来专门指定扫描。
AutoConfiguration 会被加载执行两次一次是由ComponentScan如果配置了的话另一次是由自动配置机制也就是说只要该类在该项目下且配置文件.imports 里有该类的全类名,该类就会被系统自动调用自动配置Bean。Configuration与AutoConfiguration注解一般配合使用。