
/*
1.只有一个属性值时默认是value的值,可以省略 value=
2.如果不指定value,默认为匈牙利命名的类名或大驼峰命名的类名的小驼峰。
3.此处的value值即xml配置文件中bean的id
*/
@Component(value="student") //同@Component("student"),同@Component
public class Student {
@Autowired //byType
private Class class;
@Autowired
@Qualifier(value="group") //byName
private Group group;
@Resource(name="time") //byName、byType
private Time time;
@Value(value="wang") //普通数据类型注入
private String name;
public Student() {
}
}
连接点:程序执行期间的某个点,类里面可以被增强的方法。
切入点:一个匹配连接点(Join point)的谓词表达式,指定实际真正被增强的方法。
通知:指一个切面在特定的连接点要做的事情。
切面:它是通知和切点合起来的抽象。
织入:把通知应用到切入点的过程。
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-expressionartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.8.13version>
dependency>
<dependency>
<groupId>commons-logginggroupId>
<artifactId>commons-loggingartifactId>
<version>1.2version>
dependency>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring.xmlparam-value>
context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
listener-class>
listener>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.st.service" />
<context:component-scan base-package="com.st.dao" />
<context:component-scan base-package="com.st.model" />
<bean name="aopUtil" class="com.st.util.AopUtil">bean>
<aop:config>
<aop:aspect id="myAspect" ref="aopUtil">
<aop:pointcut id="myPointCut" expression="execution(* com.st.service.*.get*(..))"/>
<aop:before pointcut-ref="myPointCut" method="speakBefore" />
aop:aspect>
aop:config>
beans>
package com.st.util;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
public class AopUtil {
/*
环绕通知 around
1 作用:在目标方法执行之前和之后都可以执行额外代码的通知
2 用法:
环绕通知需要有返回值,否则真正调用者将拿不到返回值,只能得到一个null;
在环绕通知中必须显式的调用目标方法,目标方法才会执行,这个显式调用是通过ProceedingJoinPoint来实现的;
环绕通知有控制目标方法是否执行、有控制是否返回值、有改变返回值的能力。
3 应用场景:控制事务 权限控制
*/
public String speakAround(ProceedingJoinPoint joinPoint) {
System.out.println("aop-----around-----before");
//开启事务
try {
//执行目标方法
Object obj = joinPoint.proceed();
System.out.println(obj);
//提交事务
} catch (Throwable e) {
e.printStackTrace();
//回滚事务
}
System.out.println("aop-----around-----after");
return "@@@@@aop@@@@@";
}
/*
前置通知 before
1 作用:在目标方法执行之前执行的通知
2 用法:
前置通知方法,可以没有参数;
也可以额外接收一个JoinPoint类型参数,通过该对象可以获取目标对象 和 目标方法相关的信息;
如果接收JoinPoint,必须保证其为方法的第一个参数,否则报错
3 应用场景:日志
*/
public void speakBefore(){
System.out.println("aop-----before");
}
/*
后置通知 after-returning
1 作用:在目标方法执行成功(即不报异常)之后执行的通知。
2 用法:
后置通知方法,可以没有参数;
也可以接收一个JoinPoint参数,通过该对象可以获取目标对象 和 目标方法相关的信息;
如果接收JoinPoint,必须保证其为方法的第一个参数,否则报错
3 应用场景:日志
*/
public void speakAfterReturn(JoinPoint jp){
//获取对象Class类
Class clz = jp.getTarget().getClass();
System.out.println(clz.getName());
//获取切入点对象信息
Signature signature = jp.getSignature();
//获取切入点名称
String name = signature.getName();
System.out.println(name);
System.out.println("aop-----after-returning");
}
/*
最终通知 after
1 作用:在目标方法执行之后(无论执行成功还是异常)执行的通知
2 应用场景:日志
*/
public void speakAfter(){
System.out.println("aop-----after");
}
/*
异常通知 after-throwing
1 作用:在目标方法抛出异常时执行的通知
2 用法:
可以配置传入JoinPoint获取目标对象和目标方法相关信息,但必须处在参数列表第一位
还可以配置参数,让异常通知可以接收到目标方法抛出的异常对象。
3 应用场景:异常处理、控制事务
*/
public void speakException(JoinPoint jp,Throwable e){
Class clz = jp.getTarget().getClass();
String name = jp.getSignature().getName();
System.out.println("aop-----after-throwing..["+clz+"]..["+name+"].."+e.getMessage());
}
}


1、每个资源都使用 URI (Universal Resource Identifier) 得到一个唯一的地址。资源的例子有:应用程序对象、数据库记录、算法等等。
2、客户端使用GET、POST、PUT、DELETE 4个标准的HTTP方法对服务端资源进行操作,其中GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;
3、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。
4、资源的表现形式有XML、HTML,客户端通过操作资源的表现形式来操作资源;
数据的安全保障:
url链接一般都采用https协议进行传输 注:采用https协议,可以提高数据交互过程中的安全性
接口特征表现,一看就知道是个api接口
- 用api关键字标识接口url:
- https://api.baidu.com
- https://www.baidu.com/api
注:看到api字眼,就代表该请求url链接是完成前后台数据交互的
-路飞的接口:https://api.luffycity.com/api/v1/course/free/
多数据版本共存
- 在url链接中标识数据版本
- https://api.baidu.com/v1
- https://api.baidu.com/v2
注:url链接中的v1、v2就是不同数据版本的体现(只有在一种数据资源有多版本情况下:例如在原有版本上增加接口,类似改版,也需要保证老版本可以使用)
数据即资源(均使用名词)
接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
https://api.baidu.com/users
https://api.baidu.com/books
https://api.baidu.com/book
注:一般提倡用资源的复数形式,在url链接中、不要出现操作资源的动词,错误示范:https://api.baidu.com/delete-user
特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义
https://api.baidu.com/place/search
https://api.baidu.com/login
资源操作由请求方式决定(method)
- 操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作
- https://api.baidu.com/books - get请求:获取所有书
- https://api.baidu.com/books/1 - get请求:获取主键为1的书
- https://api.baidu.com/books - post请求:新增一本书书
- https://api.baidu.com/books/1 - put请求:整体修改主键为1的书
- https://api.baidu.com/books/1 - patch请求:局部修改主键为1的书
- https://api.baidu.com/books/1 - delete请求:删除主键为1的书
过滤,通过在url上传参的形式传递搜索条件
响应状态码
7.1 正常响应
- 响应状态码2xx
- 200:常规请求
- 201:创建成功
7.2 重定向响应
- 响应状态码3xx
- 301:永久重定向
- 302:暂时重定向
7.3 客户端异常
- 响应状态码4xx
- 403:请求无权限
- 404:请求路径不存在
- 405:请求方法不存在
7.4 服务器异常
- 响应状态码5xx
- 500:服务器异常
错误处理,应返回错误信息,error当做key
{
error: “无权限操作”
}
返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
需要url请求的资源:需要访问资源的请求链接
// Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么
{
"status": 0,
"msg": "ok",
"results":[
{
"name":"肯德基(罗餐厅)",
"img": "https://image.baidu.com/kfc/001.png"
}
...
]
}
1)pre-clean:执行清理前需要完成的工作
2)clean:清理上一次构建生成的文件
3)post-clean:执行清理后需要完成的工作
1)validate:验证工程是否正确,所有需要的资源是否可用。
2)compile:编译项目的源代码。
3)test:使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。
4)Package:把已编译的代码打包成可发布的格式,比如jar。
5)integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。
6)verify:运行所有检查,验证包是否有效且达到质量标准。
7)install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。
8)Deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。
1)pre-site:生成项目站点之前需要完成的工作
2)site:生成项目站点文档
3)post-site:生成项目站点之后需要完成的工作
4)site-deploy:将项目站点发布到服务器
用于定义配置类,指出该类是 Bean 配置的信息源,相当于传统的xml配置文件,一般加在主类上。如果有些第三方库需要用到xml文件,建议仍然通过@Configuration类作为项目的配置主类——可以使用@ImportResource注解加载xml配置文件。
组件扫描。让spring Boot扫描到Configuration类并把它加入到程序上下文。
@ComponentScan注解会默认装配标识了@Controller、@Service、@Repository、@Component注解的类到spring容器中。
表示该方法的返回结果直接写入HTTP response body中
一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,添加@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据。
放在方法的上面,意思是产生一个id为方法名的bean,并交给spring管理。
byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
当加上(required=false)时,就算找不到bean也不报错。
当有多个同一类型的Bean时,可以用@Qualifier(“name”)来指定。与@Autowired配合使用
没有括号内内容的话,默认byName。与@Autowired干类似的事。
RequestMapping是一个用来处理请求地址映射的注解;提供路由信息,负责URL到Controller中的具体函数的映射,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
用在方法的参数前面。例如:
public void function(@RequestParam String a =request.getParameter("a")){
//do something;
}
@RequestMapping("show5/{id}/{name}")
public ModelAndView test5(@PathVariable("id") Long ids ,@PathVariable("name") String names){
ModelAndView mv = new ModelAndView();
mv.addObject("msg","占位符映射:id:"+ids+";name:"+names);
mv.setViewName("hello2");
return mv;
}
@Repository
public interface StudentRespository {
StudentPo selectByStudentNo(@Param("stuNo") Long stuId);
}

获取路径变量。参数与大括号里的名字一样要相同。例如:
@RequestMapping("user/get/mac/{macAddress}")
public String getByMacAddress(@PathVariable String macAddress){
//do something;
}
Spring Profiles提供了一种隔离应用程序配置的方式,并让这些配置只能在特定的环境下生效。
任何@Component或@Configuration都能被@Profile标记,从而限制加载它的时机。
@Configuration
@Profile("prod")
public class ProductionConfiguration {
// ...
}
Spring Boot可使用注解的方式将自定义的properties文件映射到实体bean中。
@Data
@Configuration
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {
private String hostName;
private int port;
private String from;
}
springboot将会读取properties文件中所有以mail开头的属性,并和bean中的字段进行匹配
# A simple .properties file
mail.hostname=host@mail.com
mail.port=9000
mail.from=mailer@mail.com

logging:
level:
root: debug
logging:
level:
com.hand: trace
logging:
level:
root: debug
com.hand: trace
file:
name: myLog.log
Slf4J和Logback一个负责充当日志API接口,一个负责实现日志底层
依赖导入
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-classicartifactId>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-coreartifactId>
dependency>
@RestController
public class UserController {
private final Logger logger = LoggerFactory.getLogger(UserController.class);
@RequestMapping("/getName")
public String getName(){
logger.debug("||| debug log test =================");
logger.trace("||| trace log test =================");
logger.info("||| info log test =================");
return "李四";
}
}



<resultMap type="com.hand.demo01.domain.entity.po.StudentPo" id="studentMap">
<result property="studentNo" column="student_no"/>
<result property="studentName" column="student_name"/>
<result property="studentAge" column="student_age"/>
<result property="studentGender" column="student_gender"/>
resultMap>
<select id="selectByStudentNo" resultMap="studentMap">
select student_no, student_name, student_age, student_gender
from hand_student
<if test="stuNo != null">
where student_no = #{stuNo}
if>
select>
一对一结果映射需要association标签的支持






<include refid="all_columns" />
<sql id="all_columns"> sql... <sql>


相关标签:
-- test中使用接口的参数来判断
<if test="stuNo != null">
where student_no = #{stuNo}
if>
<choose>
<when test=" name != null and name != '' ">
AND C_NAME LIKE #{name,jdbcType=VARCHAR}
when>
<when test=" sex != null and sex != '' ">
AND C_SEX != #{sex,jdbcType=VARCHAR}
when>
<otherwise>
AND B_FACE IS NULL
otherwise>
choose>
SELECT u.user_id,
u.username,
u.sex,
u.birthday
FROM User u
<where>
<if test="username !=null ">
u.username LIKE CONCAT(CONCAT('%', #{username, jdbcType=VARCHAR}),'%')
if>
<if test="sex != null and sex != '' ">
AND u.sex = #{sex, jdbcType=INTEGER}
if>
<if test="birthday != null ">
AND u.birthday = #{birthday, jdbcType=DATE}
if>
where>
UPDATE user
<set>
<if test="username!= null and username != '' ">
username = #{username},
if>
<if test="sex!= null and sex!= '' ">
sex = #{sex},
if>
<if test="birthday != null ">
birthday = #{birthday},
if>
set>
WHERE user_id = #{userid};
trim 元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是 prefix 和 suffix;可以把包含内容的首部某些内容忽略,也可以把尾部的某些内容忽略,对应的属性是 prefixOverrides 和 suffixOverrides.
trim 是更灵活用来去处多余关键字的标签,它可以用来实现 where 和 set 的效果。
<select id="getUsertList_if_trim" resultMap="resultMap_User">
SELECT *
FROM user u
<trim prefix="WHERE" prefixOverrides="AND|OR">
<if test="username !=null ">
u.username LIKE CONCAT(CONCAT('%', #{username, jdbcType=VARCHAR}),'%')
if>
<if test="sex != null and sex != '' ">
AND u.sex = #{sex, jdbcType=INTEGER}
if>
<if test="birthday != null ">
AND u.birthday = #{birthday, jdbcType=DATE}
if>
trim>
select>
<update id="updateUser_if_trim" parameterType="com.yiibai.pojo.User">
UPDATE user
<trim prefix="SET" suffixOverrides=",">
<if test="username != null and username != '' ">
username = #{username},
if>
<if test="sex != null and sex != '' ">
sex = #{sex},
if>
<if test="birthday != null ">
birthday = #{birthday},
if>
trim>
WHERE user_id = #{user_id}
update>
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
foreach>
select>
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl