框架学习(华清远见)

框架简介

framework:框架 ,根据一些编程思想, 把一些功能封装起来,帮助更好的,更快的做软件开发, 发布为jar包, 供其他程序员使用,这样的一些软件,被称为框架, 比如spring , spring mvc , mybatis, hibernate , spring boot 等。

1、spring

spring简介
Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。

  • spring框架的的主要特点:
    • Inversion of Control (IoC) : 控制反转 , spring框架创建对象,管理对象,以及管理对象之间的依赖关系。
    • dependency injection (DI) :依赖注入 , 通过构造函数,或set方法, 给对象的属性赋值。IoC是通过DI来实现的。
    • bean: java类型 , 由spring框架创建的对象,就被称为bean . (pojo: 纯java类(私有的属
      性,公开的get/set方法这种类。))
      Aspect-Oriented Programming (AOP): 面向切面编程 , 对比OOP(面向对象编程)
  • The IoC Container: IoC容器
    在这里插入图片描述
  • 容器
    • Interface BeanFactory
    • Interface ApplicationContext 实现 BeanFactory
    • Class ClassPathXmlApplicationContext 实现ApplicationContext
1.1、spring的xml文件配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--   ** id : 唯一标志
    ** class : 类型
    init-method: 初始化方法的执行
    destroy-method: 销毁方法的执行
    scope: 设置bean是否为单例, 默认就是单例
    lazy-init: 设置bean的创建时机,默认是false.
         * true: 表示当需要第一次使用这个对象的时候,才创建这个对象
         * false: 表示创建spring的容器的时候,就创建对象。
-->
<!--先定义一个类(如:Phone),配置id="a1"的bean对象-->
  <bean id="a1" class="com.hqyj.entity.Phone">
        <!--<constructor-arg name="pinPai":类的属性名
                             index="0":类的属性第一个
                             ref="":引用容器中存在的对象
                             value="":值
                             type="":类型
            ></constructor-arg>-->
            <!--constructor 构造器-->
        <constructor-arg name="pinPai" value="三星"></constructor-arg>
        <!--    set注入: 调用set方法,给属性赋值
        property : 属性, 表示给对象的属性赋值。 name是属性名, value/ref是对应的属性值
-->
        <property name="price" value="1000.0"></property>
        <constructor-arg index="2" value="64"></constructor-arg>
        <!--
        <constructor-arg name="pinPai" value="1"/>也可以改成<constructor-arg index="0" value="1"/>方式;
                boolean的值既可以用0/1填充,也可以用true/false填充。
        -->
    </bean>
</beans>
1.2、spring中创建bean对象的3种 配置

java中创建对象的方式,对应为在spring中bean的配置:

<!--  创建对象方式:1. 调用构造函数-->
  <bean id="date" class="java.util.Date"></bean>
  <!--  创建对象方式:2. 调用自己的静态方法:
  factory-method="getInstance" ,factory-method属性,用于指定需要调用的静态方法的名字
  -->
  <bean id="cal" class="java.util.Calendar" factory-method="getInstance">
</bean>
  <!--  创建对象方式:3. 调用容器中的其他bean的方法,创建对象:
  factory-bean="cal" , factory-bean指定调用的容器中的其他bean的名字。
  factory-method="getTime" ,factory-method属性,用于指定需要调用的bean的方法的名字
  -->
  <bean id="date1" class="java.util.Date" factory-bean="cal" factory-
method="getTime"></bean>
1.3、bean的autowire属性

autowire:自动装配, 为了减少构造器函数初始化对象和set注入初始化对象, 可以使用autowire ,让spring框架的容器对象,自动匹配容器中的其他bean对象,然后给bean进行初始化

  • autowire: 自动装配, 根据spring容器中的对象的id 或对象的类型 ,按照自动装配的规则,给对象的属性初始化。
    • constructor :按构造器函数进行匹配
    • byType : set注入 ,调用无参构造函数,然后根据容器中的对象的类型和类的属性的类型,调用set方法 ,如果有多个符号条件的类型,则抛出异常
    • byName : set注入 ,调用无参构造函数,然后根据容器中的对象的id和类的属性的属性名 ,调用set方法, 如果id匹配成功,但是类型不正确,则抛出异
      常。
    • byType , byName使用的时候,对于容器中的jdk提供的类型不能自动装配

xml:

<!--  <bean id="p1" class="com.hqyj.entity.Phone" autowire="constructor">
</bean>-->
<!--  <bean id="p1" class="com.hqyj.entity.Phone"-->
<!--    autowire="byType"></bean>-->
  <bean id="p1" class="com.hqyj.entity.Phone" autowire="byName"></bean>
    <bean id="phoneShell" class="com.hqyj.entity.PhoneShell">
    	<!--set注入 -->
      <property name="color" value="绿色"></property>
      <property name="size" value="10"></property>
    </bean>
  </beans>
  
  <bean id="mem" class="java.lang.Integer">
  		<!--构造器注入 -->
      <constructor-arg index="0" value="256"></constructor-arg>
    </bean>
    
  <!-- p1:  autowire="byType": 根据(com.hqyj.entity.PhoneShell)
  			autowire="byName": 根据类的属性名(phoneShell)
  			autowire="constructor": 根据构造器-->
1.4、aop面向切面编程

jar包:

<!--  导入aop相关的jar包-->
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjtools</artifactId>
   <version>1.9.4</version>
  </dependency>

aop详解,博主讲的详细:https://blog.csdn.net/q982151756/article/details/80513340
概念定义:

  • Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
  • Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
  • Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
  • Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
  • Target(目标对象):织入 Advice 的目标对象.。
    Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程

例子:

  • 目标类
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
import  java.util.List;
// 要求: ① dao中的每个方法执行之前,记录执行的信息: updateEmp方法开始执行:2022-9-16 14:08:39
//    ② dao中的每个方法,执行时间的统计。
// 解决方式1 : 在每个方法内部,添加这一段功能相关的代码
// 解决方式2 : 把公共的功能,封装成方法, 然后在需要这个公共功能的地方,就调用这个方法。
// aop的思想: 面向切面编程 , 抽取项目中的公共的功能,单独封装。然后使用aop的配置 ,
//       通过动态代理的方式,实现封装的功能的调用。
@Component
public class EmpDao {
  public  Integer  addEmp(){
    System.out.println("addEmp ...... ");
    return 1;
 }
  public  Integer  updateEmp(){
    System.out.println("updateEmp ...... ");
    return 1;
 }
  public  Integer  deleteEmp(){
    System.out.println("deleteEmp ...... ");
    return 1;
 }
  public  List<String>  queryEmp(){
    System.out.println("queryEmp ...... ");
    return null;
 }
}
  • logging
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class Logging {
  // *** 公共功能: 希望在方法执行之前,显示方法执行的时间。
  // -- Joinpoint 连接点 (可以理解为正在调用showTime的方法相关的对象)
  public void  showTime(JoinPoint joinpoint){
    String methodName = joinpoint.getSignature().getName();// 正在被执行的方法的
名字
    Date time = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String info = sdf.format(time);
    System.out.println( methodName +  "方法开始执行:" + info);
 }
  // ** 公共功能: 统计出每个方法执行消耗的时长。
  public Object exeTime(ProceedingJoinPoint joinPoint) throws Throwable {
    long begin = System.currentTimeMillis();
    // 调用正在执行的方法
    Object proceed = joinPoint.proceed();
    long end = System.currentTimeMillis();
    long cha = end - begin;
    System.out.println(joinPoint.getSignature().getName() + ":执行消耗时间" +
cha + "毫秒");
    //return proceed;
    return  proceed;
 }
  // 练习: 方法执行结束之后,输出方法的返回值
  public void  returnVal(JoinPoint joinPoint , Object obj){
    // obj表示方法的返回值
    System.out.println(joinPoint.getSignature().getName()
    + "返回值:" + obj);
 }
}
  • aop的xml文件配置
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
   http://www.springframework.org/schema/context
   https://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/aop
   https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--  开启组件扫描功能: 指定扫描的包-->
  <context:component-scan base-package="com.hqyj"></context:component-scan>
  <context:annotation-config/>
  <aop:config>
    <!--aspect: 切面 , 配置的是封装公共功能的对象。-->
    <aop:aspect ref="logging">
      <!-- pointcut: 切入点 , 通过一个表达式配置需要调用公共方法的类的方法。
        execution(public * com.hqyj.dao.*.*(..)) : 通过这个表达式,找到要
调用的方法
             第一个* :表示方法的返回值
             com.hqyj.dao.* : 这个星号表示所有类。
             com.hqyj.dao.*.*: 第二个星号表示所有方法。
             (..) :表示任意参数
      -->
      <aop:pointcut id="all"
             expression="execution(public * com.hqyj.dao.*.*
(..))"/>
      <!-- pointcut-ref="all" : 表示切入点引用all.
      before: 表示前置通知,当方法执行之前,先执行这个前置通知对应的method.
       -->
      <aop:before method="showTime" pointcut-ref="all"></aop:before>
      <aop:around method="exeTime" pointcut-ref="all"></aop:around>
      <aop:after-returning method="returnVal"
                pointcut-ref="all"
                returning="obj"/>
    </aop:aspect>
  </aop:config>
</beans>
  • aop的注解
package com.hqyj.dao;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
@Aspect // 切面的设置
@EnableAspectJAutoProxy // 开启aop的自动代理功能
public class Logging1 {
  // *** 公共功能: 希望在方法执行之前,显示方法执行的时间。
  // public * com.hqyj..*.*(..) --- com.hqyj包
  // public * com.hqyj.dao.*.*(..) --- com.hqyj.dao包
  @Before("execution(public * com.hqyj.dao.*.*(..))")
  public void  showTime(JoinPoint joinpoint){
    String methodName = joinpoint.getSignature().getName();// 正在被执行的方法的
名字
    Date time = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String info = sdf.format(time);
    System.out.println( methodName +  "方法开始执行:" + info);
 }
  @Around("execution(public * com.hqyj.dao.*.*(..))") // ** 公共功能: 统计出每个
方法执行消耗的时长。
  public Object exeTime(ProceedingJoinPoint joinPoint) throws Throwable {
    long begin = System.currentTimeMillis();
    Object proceed = joinPoint.proceed();  // 调用正在执行的方法
    long end = System.currentTimeMillis();
    long cha = end - begin;
    System.out.println(joinPoint.getSignature().getName() + ":执行消耗时间" +
cha + "毫秒");
    return proceed;
 }
  @AfterReturning(value = "execution(public * com.hqyj.dao.*.*(..))"
,returning = "obj")
  public void  returnVal(JoinPoint joinPoint , Object obj){
    // obj表示方法的返回值
    System.out.println(joinPoint.getSignature().getName() + ":" + obj);
 }
}

2、springmvc

SpringMVC是一种基于Java,实现了Web MVC设计模式,请求驱动类型的轻量级Web框架,即使用了MVC(Model-View-Controller)架构模式的思想,将Web层进行职责解耦。基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,SpringMVC也是要简化我们日常Web开发。
SpringMVC就是一个Spring内置的MVC框架。采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性,解决页面代码和后台代码的分离。
具体流程:

(1)首先浏览器发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;

(2)DispatcherServlet——>HandlerMapping,处理器映射器将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器对象、多个HandlerInterceptor拦截器)对象;

(3)DispatcherServlet——>HandlerAdapter,处理器适配器将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;

(4)HandlerAdapter——>调用处理器相应功能处理方法,并返回一个ModelAndView对象(包含模型数据、逻辑视图名);

(5)ModelAndView对象(Model部分是业务对象返回的模型数据,View部分为逻辑视图名)——> ViewResolver, 视图解析器将把逻辑视图名解析为具体的View;

(6)View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构;

(7)返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。

3、mybatis

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

mybatis是一个数据库相关的框架,主要为了简化jdbc的操作

mybatis使用了ORM, ORM是对象关系映射的英文缩写,ORM是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换 。
例子:
实体类:
entity:

@Data
@ToString
public class Hero {
  private Integer id;
  private String name;
  private String sex;
  private String position;
  private Integer price;
  private Date shelf_date;
}

repository

// 定义数据库操作的方法
public interface HeroDao {
  public abstract int addHero(Hero hero);
  public abstract int deleteHero(Integer id);
  public abstract int updateHero(Hero hero);
  public abstract  List<Hero>  queryAll();
}

resources文件下的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>
<!--   设置控制台日志输出-->
<!--  配置数据库连接的环境 : 默认使用id为"development"的环境-->
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url"
value="jdbc:mysql://localhost:3306/gamedb?serverTimezone=Asia/Shanghai"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
      </dataSource>
    </environment>
  </environments>
  
<!--  引用存在的mapper.xml文件-->
  <mappers>
   <!--<mapper resource="mapper/HeroMapper.xml"/>-->
  </mappers>

</configuration>

resources/mapper文件下,HeroMapper.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">
<!-- namespace: 命名空间   , 设置mapper.xml文件中的sql 对应的 interface。   -->
<mapper namespace="com.hqyj.dao.HeroDao">

    <!-- insert:表示这是一个插入的sql语句
         id: 对应dao(interface)中方法的名字
         parameterType: 设置的dao(interface)中方法的参数
         insert标签的内部: sql语句
         sql语句中的#{属性名} , 就是在获取参数对象的属性的值 -->
    <insert id="addHero" parameterType="com.hqyj.entity.Hero">
            insert into hero values(null, #{name} , #{sex}
            , #{position} , #{price} , #{shelf_date})
    </insert>
<!--       方法的参数是一个,并且属于8种类型 ,就可以省略。
       也可以设置parameterType="int"  ,这里的int就是简写
       #{id} ,这里的id和方法参数名完全一致, deleteHero(Integer id)-->
    <delete id="deleteHero">
            delete from hero where id = #{id}
    </delete>
<!--   price=#{price}  , price是列名(table的列名),
        #{price}(实体类的属性) ,这里是属性值的获取。-->
    <update id="updateHero" parameterType="com.hqyj.entity.Hero">
            update hero set `name` = #{name} , sex=#{sex},
            `position` =#{position } , price=#{price} ,
            shelf_date=#{shelf_date} where id=#{id}
    </update>
    <!-- resultType="com.hqyj.entity.Hero":返回值是一个实体,或者泛型为实体的集合,
     设置的返回值类型都是这个实体类。-->
    <select id="queryAll" resultType="com.hqyj.entity.Hero">
            select * from hero
    </select>
</mapper>

在mybatis-config.xml文件中引用HeroMapper.xml

  <mappers>
   <mapper resource="mapper/HeroMapper.xml"/>
  </mappers>

4、mybatis-plus

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 -Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、Service 、 Controller 层代码,支持模板引擎
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

MyBatis:作用是操作数据库的框架,提供一种Mapper类,支持让你用java代码进行增删改查的数据库操作,省去了每次都要手写sql语句的麻烦。但是需要先在mapper文件中对应的xml写好sql语句。所以有了Mybatis Generator,自动为Mybatis生成简单的增删改查sql语句的工具。

Mybatis-Plus是一个Mybatis的增强工具,它在Mybatis的基础上做了增强,却不做改变。我们在使用Mybatis-Plus之后既可以使用Mybatis-Plus的特有功能,又能够正常使用Mybatis的原生功能。Mybatis-Plus(以下简称MP)是为简化开发、提高开发效率而生,但它也提供了一些很有意思的插件,比如SQL性能监控、乐观锁、执行分析等。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值