拦截器,mybatis
- 拦截器
- 执行Handel处理器之前运行的代码;
- 可以对请求进行拦截,处理、检查、操作
- 返回true就放行,会正确处理hander
- 返回false,就不会在执行hander,直接回应
- SpringMVC处理异常(服务降级)
@Controller @ControllerAdvice //变成全局处理 public class EasyCController { @RequestMapping("easyC") @ResponseBody public String easyc() { int a=12/0; return "easyC"; } @RequestMapping("demopage") public String demo() { // return "/WEB-INF/page/demo.jsp"; return "demo"; } @ExceptionHandler(Exception.class) @ResponseBody public String easyException() { return "exception"; } }
- 视图解析器的配置
- 指定扫描包
//字符串形式的包名,自己指定的扫描的包,一般不需要自己指定 @ComponentScan(basePackages = {"com","com.demo"})
- Springbean的作用域
- singleton:SpringIOC容器只会创建该Bean的唯一实例。这是默认的作用域,即在创建容器时就同时自动创建了一个Bean对象。作用域范围是ApplicationContext中。
- prototype:每次请求都会创建一个新的Bean实例。即每次从容器中调用Bean时,都会返回一个新的实例,相当于执行new Bean()。
- request:每次HTTP请求都会创建一个新的Bean,作用域范围是每次发起http请求直至拿到相应结果。该作用域仅适用于WebApplicationContext环境。
- session:同一个HTTPSession共享一个Bean,不同Session使用不同的Bean。首次http请求创建一个实例,作用域是浏览器首次访问直至浏览器关闭。该作用域也仅适用于WebApplicationContext环境。
- global session:在全局的HttpSession中,容器会返回该Bean的同一个实例。这个作用域一般用于Portlet应用环境,同样也只适用于WebApplicationContext环境。
- 动态代理&静态代理
- 动态代理
- 接口
public interface Handler { void action(); }
- 真实角色
public class Easy implements Handler{ public void action() { System.out.println("----主要业务"); } }
- 代理角色
public class EasyProxyHandler implements InvocationHandler{ //定义代理要做的事情 private Object obj; public EasyProxyHandler(Object obj) { this.obj=obj; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("1-----------前缀代码"); Object result=method.invoke(obj,args);//执行真实的业务逻辑 System.out.println("2-----------后缀代码"); return result; } }
- 客户端访问代理角色
public static void main(String[] args) { //创建一个动态代理 Object obj=Proxy.newProxyInstance(Test.class.getClassLoader(), Easy.class.getInterfaces(), new EasyProxyHandler(new Easy())); if(obj instanceof Handler) { Handler h=(Handler)obj; h.action(); } }
- 接口
- 静态代理
- AOP
- 基于动态代理的切面
- APO 通知类型
- 前置通知(@Before):设置当前通知方法与切入点之间绑定关系,当前通知方法在原始切入点方法前运行。
- 后置通知(@After):设置当前通知方法与切入点之间绑定关系,当前通知方法在原始切入点方法后运行。
- 环绕通知(@Around):设置当前通知方法与切入点之间绑定关系,当前通知方法在原始切入点方法前后运行。
- 返回后通知(@AfterReturning):设置当前通知方法与切入点之间绑定关系,当前通知方法在原始切入点方法正常执行完毕后运行。
- 抛出异常后通知(@AfterThrowing):设置当前通知方法与切入点之间绑定关系,当前通知方法在原始切入点方法抛出异常后执行。
- 重要注解
- Joinpoint (连接点):指哪些被拦截到的点,在Spring中,指可以被动态代理拦截目标类的方法
- Pointcut (切入点):指要对哪些joinpoint进行拦截,即被拦截的连接点;
- Advice(通知):指拦截到Joinpoint之后要做的事情,即对切入点增强的内容;
- Target (目标) :指代理的目标对象;
- Weaving(植入):指把增强代码应用到目标上,生成代理对象的过程。
- Proxy (代理) :指生成的代理对象;
- Aspect (切面) :切入点和通知的结合;
- maybatis
- 动态sql
- 同一个namespace下id是不能重复的;
- 常见标签 where、 set、 choose 、 when 、 otherwize 、foreach、 trim;
- id值必须等于接应接口中对应的方法名 ;
- # 是预编译表示占位符,$是字符串拼接
- 选择
<mapper namespace="com.easy.dao.IStaffDao"> <!-- 同一个namespace下id是不能重复的--> <!-- id值必须等于接应接口中的对应的方法名--> <select id="searchList" resultType="com.easy.bean.Staff" parameterType="com.easy.bean.Staff"> select * from t_staff <!-- 根据参数的值不同,生成不同的sql语句--> <trim prefix="where"> <if test="name!=null"> <bind name="nametext" value="'%'+name+'%'" /> name like #{nametext} </if> </trim> </select>
- 修改
<update id="edit"> update t_staff <set> <if test="name!=null"> name =#{name}, </if> <if test="tel!=null"> tel =#{tel}, </if> </set> </update>
- 插入(普通)
<insert id="addstaff"> insert into t_staff (name) values <foreach separator="," collection="items" item="temp"> <trim prefix="(" suffix=")"> #{temp.name} </trim> </foreach> </insert>
- 插入(自增长主键)
<insert id="add" useGeneratedKeys="true" keyColumn="id" keyProperty="id"> insert into t_staff (name,age,height,tel) values (#{name},#{age},#{height},#{tel}) </insert>
- 一对多
- 例:在goods类中有type类的字段 goods对type是一对多,在goods的实体类中建立Type类型的属性
<mapper namespace="com.easy.dao.IGoodsDao"> <resultMap id="goodsMap" type="goods"> <result column="type_id" property="type_id"></result> <association property="type" column="type_id" select="goodstype"></association> </resultMap> <select id="goodsList" resultMap="goodsMap"> select * from goods </select> <select id="goodstype" resultType="type"> select * from type where id=#{type_id} </select> </mapper>
- 例:在goods类中有type类的字段 goods对type是一对多,在goods的实体类中建立Type类型的属性
- 一对一
- 使用联表查询连接goods和type类,
<resultMap id="goodsJoinMap" type="com.easy.bean.Goods"> <result column="id" property="id"/> <result column="name" property="name"/> <result column="type_id" property="type_id"/> <association property="type" javaType="com.easy.bean.Type"> <result column="typeid" property="id"/> <result column="typename" property="name"/> </association> </resultMap> <select id="goodsJoinList" resultMap="goodsJoinMap"> select a.* ,b.id as typeid ,b.name as typename from goods as a left join type as b on a.type_id=b.id </select>
- 使用联表查询连接goods和type类,
- resultMap的作用
- ResultMap是MyBatis框架中的一个重要元素,主要用于将查询结果映射到Java对象。其作用主要包括:
- 映射结果集:ResultMap可以将数据库查询的结果集映射为Java对象。通常情况下,数据库的每一行结果集对应一个Java对象。
- 关联关系映射:ResultMap可以处理一对一、一对多、多对一以及多对多的关联关系。通过在ResultMap中使用collection和association标签,可以将数据库中的外键关联映射为Java对象的关联关系。
- 结果集映射策略:ResultMap提供了多种结果集的映射策略,包括单值映射、集合映射等。单值映射将查询结果映射为一个Java对象,而集合映射则将查询结果映射为一个Java集合。
- 自定义结果映射:通过ResultMap,可以自定义查询结果的映射方式。例如,可以指定将某个字段映射为Java对象的某个属性,或者将多个字段组合为一个Java对象。
- Mapper文件的语法
- 在Mapper XML文件中定义SQL语句和结果映射规则。该文件需要与Mapper接口在同一个包下,并且文件名必须以接口名命名;
- resultType的作用
- resultType在MyBatis中主要用来将查询结果按照sql列名和pojo属性名一致性映射到pojo中。
- 知识点
- @Param("goods") 后面xml属性用goods.属性;
- 加密 (见TypeController,GoodsControll);
- @RestController //前后端分离,这个类中的所有请求都默认添加了@Responsebody注解
- 前后端分离增删改查
@GetMapping("goods/{id}") public Goods getGoods(@PathVariable int id) { System.out.println(id); //查询数据库,返回goods return goodsdao.getGoodsById(id); } @PostMapping("goods") public Goods saveGoods(@RequestBody Goods goods) { System.out.println(goods); goodsdao.saveGoods(goods); return goods; } @PutMapping("goods") public Goods editGoods(@RequestBody Goods goods) { System.out.println(goods); goodsdao.editGoods(goods); return goods; } @DeleteMapping("goods/{id}") public Goods delGoods(@PathVariable int id) { Goods goods=goodsdao.getGoodsById(id); goodsdao.deleteGoods(id); return goods; }
- mybatis的一二级缓存
- 缓存查询一次SQL语句之后,将查询的结果存储起来,当进行相同的查询时,直接回应上一次查询的结果,不需要在执行一次SQL语句·;
- 默认开启一级缓存,一级缓存SQL Session级别,确保是同一个过程(一次压栈),使用相同的连接对象,执行相同的SQL语句就可以使用到一级缓存;
- 缓存失效
- 缓存超时;
- 执行增删改任意一个操作,缓存都会消失;
- 使用随机数;
- 不使用缓存的方法:
- 使用随机数拼接SQL语句,确保每次执行的SQL语句都是不相同的;
- 二级缓存:
- 开启:在Mapper.xml文件中添加<cache></cache>标签,就对这个mapper开启了二级缓存;
- 级别: Mapper;
- 二级缓存对对象必须是可序列化的;