精华内容
下载资源
问答
  • 正则匹配引号内的指定字符串

    千次阅读 2019-02-13 16:08:56
    $str = "cchuahua213a,< img alt='ccchuahua22'/> < a href='cchuahua22'></ a>"; $preg1 = "/('.*?)huahua(.*?')/"; $preg2 = "/huahua/";...只匹配引号外面的hauhua,替换成hehe 原理:使用正则的模式单元.
    <?php  
        $str = "cchuahua213a,< img alt='ccchuahua22'/> < a href='cchuahua22'></ a>";
        $preg1 = "/('.*?)huahua(.*?')/";
        $preg2 = "/huahua/";
        $preg3 = "/'aaaa'/";
        $temp = "huahua";
        $str = preg_replace($preg1,'$1\'aaaa\'$2',$str);
        $str = preg_replace($preg2,'hehe',$str);
        $str = preg_replace($preg3,$temp,$str);
        echo $str;

    只匹配单引号外面的hauhua,替换成hehe

    原理:使用正则的模式单元.

    展开全文
  • 模式匹配

    2019-01-16 16:09:39
    Scala 中的模式匹配类似于java中的 switch 语法, 但是更加强大 模式匹配语法中, 使用 match关键字声明, 每个分支采用 case 关键字进行声明, 当需要匹配是,会在第一个case 分支开始,如果匹配成功,那么执行对应的逻辑...

    模式匹配

    Scala 中的模式匹配类似于java中的 switch 语法, 但是更加强大

    模式匹配语法中, 使用 match关键字声明, 每个分支采用 case 关键字进行声明, 当需要匹配是,会在第一个case 分支开始,如果匹配成功,那么执行对应的逻辑代码,如果匹配不成功,继续执行下一个分支进行判断.

    如果所有 case 都不匹配, 那么会执行 case _ 分支, 类似于 java 中的 default语句

    1.1基本应用

    ex1: 输入1,2,3 会打印对应的颜色

    object Color {
    
        def main(args: Array[String]): Unit = {
            //从键盘获取数字
            val i: Int = StdIn.readInt()
            i match {
                case 1 => println("red")
                case 2=> println("green")
                case 3=> println("yellow")
                case _=> println("您的输入有误")
            }
        }
    
    }
    

    说明:

    • 如果所有case都不匹配,那么会执行case _ 分支,类似于 Java 中default语句
    • 如果所有case都不匹配,又没有写case _ 分支,那么会抛出异常
    • 每个case中,不用break语句,自动中断case
    • 可以在match中使用其它类型(任意类型),而不仅仅是字符
    • => 等价于 java swtich:
    • =>后面的代码块到下一个 case, 是作为一个整体执行,可以使用{} 扩起来,也可以不括

    ex2 : 加减乘除

    object MatchDemo2 {
      def main(args: Array[String]): Unit = {
        var a1 = 10
        var a2 = 20
    
        var operChar = "*"
        val res = operChar match {
          case "+" => a1 + a2
          case "-" => a1 - a2
          case "*" => a1 * a2
          case "/" => a1 / a2
          case _ => "你的运算符负不正确"
        }
        println("res = " + res)
      }
    }
    

    1.2 守卫

    想要表达某个范围的数据, 就需要在匹配模式匹配中增加条件"守卫"

    object MatchDemo3 {
      def main(args: Array[String]): Unit = {
        for (ch <- "+-3&%") {
          var digit = 0
          val sign = ch match {
            case '+' => 1
            case '-' => -1
            case _ if Character.isDigit(ch) => digit = Character.digit(ch, 10)
            case _ => 0
          }
          println("ch = " + ch)
          println("sign = " + sign)
          println("digit = " + digit)
          println("---------")
        }
      }
    }
    

    1.3 变量和常量

    如果在case关键字后跟变量名,那么 match 前表达式的值会赋值给那个变量

    object MatchVar {
    
        def main(args: Array[String]): Unit = {
            var ch = 0
    
            'z' match {
                case 'a' => println("a...")
                case 'b' => println("b...")
                case 'c' => println("c...")
                case ch => println("ch=" + ch)
            }
        }
    }
    

    注意

    • 如果 case ch 匹配成功了, 后面即使跟上case _ 也没有用
    • 可以把case _ 看成 case 变量名 的特例 , 把_看成一个变量来对待

    但是:

    按照约定, Scala 期望模式变量名都以小写字母开头, 而常量名则是大写字母(只要首字母大写也可以)。

    如果你使用大写字母的名称,Scala 将会在作用域范围内查找常量。

    但是,如果使用的是非大写字母的名称,它将只假设其是一个模式变量—-在作用域范围内任何具有相同非大写字母的名称都将会被忽略。

    在下面的代码中,我们定义了一个和字段具有相同名称的模式变量, 但是这段代码将不会给出我们想要的结果—–模式变量隐藏了(Sample 类的)max 字段。

    object PatternTest {
        def main(args: Array[String]): Unit = {
            val sample = new Sample
            sample.process(1000)
        }
    }
    
    class Sample {
        val max = 10000
        def process(input: Int): Unit = {
    
            input match {
                case max => println(s"You matched max")
            }
        }
    }
    

    说明:

    • 你会发现 scala 把 max推断为模式变量, 而不是模式常量.

    • 解决办法:

      • 办法1: 明确指定作用域:this.max

      • 办法2: 使用反引号类给 scala 提示.

         case `max` => .....
        
      • 办法3: 把max变成大写: MAX

    1.4 模式匹配

    object MatchType {
    
        def main(args: Array[String]): Unit = {
    
            val list = List(1, 3.2, "sa",true)
    
            var result = list match {
                case a: List[Int] => println("...Int类型...")
                case b : List[String] => println("...string...")
                case c :List[Double] =>println("...double...")
                case d:List[Boolean] => println("...boolean...")
    
            }
            println(result)
        }
    }
    

    说明:

    • 在进行类型匹配时,编译器会预先检测是否有可能的匹配,如果没有则报错
    • 如果类型匹配成功之后会把s的值赋值给case后面跟着的变量, 而不需要做类型的转换.
    • 对数组来说提供数组元素中的类型是必要的,因为数组的底层类型确实是确定的.比如:Array[Int]这里的Int是必须的
    • 但是对集合类型比如 Map, 提供泛型类型是无用的. 因为 Java 的"泛型擦除". Map[Int, String]和Map[Int, Int] 在匹配的时候没有区别. 所以应该使用通用的泛型:Map[_, _]
    import scala.io.StdIn
    
    object MatchType {
      def main(args: Array[String]): Unit = {
        var s: Any = Map("a" -> 11, "b" -> 22)
    
        var result = s match {
          case d: Map[_, _] => "匹配到的是Map"
          case _ => "啥都没有匹配到"
    
        }
        println(result)
      }
    }
    

    1.5 匹配数组

    object PatternDemo5 {
        def main(args: Array[String]): Unit = {
            // Array(1,2,3) == Array(1,2,3)
            var arr1 = Array(1, 2, 3, 5, 6)
            
            arr1 match {
                //匹配三个元素,只能是三个元素,且为123
                //            case Array(1, 2, 3) => println("Array(1,2,3)")
                
                //匹配四个元素,且前两个元素为1,2
                //            case Array(1, 2, _, _) => println("Array(1,2,_,_)")
                
                //匹配四个元素,第三个元素用变量接收
                //            case Array(1, 2, a, _) => println("Array(1,2,_,_)  " + a)
                
                //匹配前两个元素为1,2,后面是什么都行
                //            case Array(1, 2, _*) => println("Array(1,2, _*)  ")
                
                //匹配前两个为1,2,  后面为一个数组
                // 在未来 @ 会变成 :
                //            case Array(1, 2, rest@_*) => println("Array(1,2, rest@_*)  " + rest.mkString(", "))
                case Array(_, _, rest@_*) => println("Array(_,_, rest@_*)  " + rest.mkString(", "))
                case _ => println("no ")
                
            }
            
        }
    }
    

    1.6 匹配列表

    def main(args: Array[String]): Unit = {
        val arr: List[Int] = List(1, 2, 3, 5, 6)
        val res = arr match {
          //case List(1, 2) => "List(1, 2)"
          //case List(1, _*) => "匹配以 1 开头的列表"
          //case 1 :: 2 :: 3 :: Nil => "匹配List(1,2,3)"
          case 1 :: abc => println(abc); "匹配以 1 开头的列表"
          case _ => "啥也可没有匹配到"
        }
        println(res)
      }
    

    1.7 匹配元组

    object MatchTouple {
    
        def main(args: Array[String]): Unit = {
    
    //        val tup1:(Int , String)= (1,"niefeng")
            val tup2:(Int , String , String)= (2,"bujingyun","chuchu")
    
            tup2 match {
                case (a,b,c) => println(s"a=$a,b=$b,c=$c")
            }
        }
    }
    

    1.8 对象匹配(提取器)

    对象匹配,什么才算是匹配呢?,规则如下:

    1. case中对象的unapply方法(提取器)返回some集合则为匹配成功
    2. 返回None集合则为匹配失败

    备注:

    1. SomeNone 都是Option的子类型
    2. 2.11.1 开始, scala 为了性能上的优势, 放松了对unapply返回的值的类型的限制(不必必须是 Option). 返回的类型只要具有以下方法就可以:
      • def isEmpty: Boolean
        返回值: true用来标记匹配成功, false匹配失败
      • def get: T 返回值: 表示提取到的值.
    3. 其实SomeNone 均包含上面的两个方法.
    4. 另外一种情况: 如果unapply返回一个Boolean值, 则只表示匹配成功或者失败. 如果是 true则表示匹配成功, 但是不会提取到任意的值.
    5. 不过, 大部分情况下, 我们还是把要提取的数据封装到Some中返回.

    1. 提取单个对象

    object MatchObj {
    
        def main(args: Array[String]): Unit = {
            val num = 100.0
    
            num match {
                case Square(z) => println("z =" +z)
            }
        }
    }
    object Square{
        def apply(a:Double): Double = a * a
    
        def unapply(arg: Double): Option[Double] = Some(math.sqrt(arg))
    }
    
    
    result: 10.0
    
    

    执行流程说明:

    1. case匹配的过程中, 如果碰到这种(伴生对象(参数))的形式的时, 就会调用这个伴生对象的unapply方法, 来提前对象.
    2. 调用unapply的时候, 会把前面的匹配表达式(本例中的num)传递给unapply
    3. 如果unapply返回的是Some, 则表示匹配成功. 并unapply的返回值赋值给伴生对象(参数)中的参数(本例中的z), z其实就是提取到的对象
    4. 如果unapply返回的None, 则表示匹配失败.
    5. 继续下一个case的匹配…

    2. 提取多个对象

    object MatchObjs {
    
        def main(args: Array[String]): Unit = {
            val s = "yangguo,xiaolongnv"
            val res = s match {
                case Names(one,two) => println(s"成功! one =$one,two =$two")
                case _ => println("匹配失败")
    
            }
        }
    }
    
    object  Names{
        def unapplySeq(str:String)={
            if (str.contains(","))
                Some(str.split(","))
            else
                None
        }
    }
    

    在这里插入图片描述

    执行过程说明:

    1. case Names(one, two), 这里有 32个需要提取的结果, 所以会调用伴生对象.unapplySeq方法.
    2. 如果这个方法返回的是Some, 并且 Some中的序列有 2个值, 则匹配成功. 否则就匹配失败.

    1.9 变量声明中的模式

    在声明变量的时候,也可以使用模式匹配的方式. (在其他语言中叫做解构)

    object VarMatch {
      def main(args: Array[String]): Unit = {
        var (a: Int, b: Int) = (10, 20)
        println(s"a = $a, b=$b")
    
        val (aa, bb) = BigInt(10) /% 3
        println(s"aa = $aa, bb = $bb")
    
        val arr = Array(100, 200, 300, 400)
        val Array(c, _, d, _*) = arr  //
        println(s"c = $c, d = $d")
      }
    }
    

    在这里插入图片描述

    1.10 for表达式中的模式

    def main(args: Array[String]): Unit = {
        val map = Map("a" -> 1, "b" -> 2, "c" -> 3, "d" -> 2)
    
        // 直接将Map中的K-V遍历出来
        for ((k, v) <- map) {
          println(s"k = $k, v = $v")
        }
        println("--------------")
        // 只遍历 v = 2的 k-v
        for((k, 2) <- map) {
          println(s"k = $k")
        }
        println("--------------")
        // 也可以使用 守卫: 遍历v > 1的
        for ((k, v) <- map if v > 1){
          println(s"k = $k, v = $v")
        }
      }
    

    1.11 样例类

    案例1

    object CaseClassDemo1 {
      def main(args: Array[String]): Unit = {
        val arr = Array(Dollar(1000), Currency(10000, "RMB"))
    
        for (ele <- arr) {
          val res = ele match {
            case Dollar(v) => "$" + v
            case Currency(v, u) => v + u
            case _ => ""
          }
          println(res)
        }
      }
    }
    
    // 一个抽象类
    abstract class Amount {}
    
    // Dollar: 样例类 继承自 Amount
    case class Dollar(value: Double) extends Amount {}
    
    // Currency: 样例类
    case class Currency(value: Double, unit: String) {}
    

    在这里插入图片描述

    案例2

    copy会创建一个与现有对象值相同的新对象,并可以通过带名参数来修改某些属性。

    object CaseClassDemo2 {
      def main(args: Array[String]): Unit = {
        val amt1: Currency = Currency(122.2, "美元")
        // 复制一个与 amt1 完全相同的对象
        val amt2: Currency = amt1.copy()
        val amt3: Currency = amt1.copy(value = 222.2)
        val amt4: Currency = amt1.copy(unit = "英镑")
        println(amt1)
        println(amt2)
        println(amt3)
        println(amt4)
      }
    }
    

    在这里插入图片描述

    案例3

    在这里插入图片描述

    1.12 case语句中的中置表示法

    ![](W:\博客\博客图片\2019-01-16_153746.png)

    1.13 匹配嵌套结构

    object MatchNest {
      def main(args: Array[String]): Unit = {
        val book1 = Book("九阳真经", 100)
        val book2 = Book("葵花宝典", 120)
        val bundle1 = Bundle("书籍", 20, book1, book2)
    
        println(price2(book1))
        println(price2(book2))
        println(price2(bundle1))
    
      }
    
      /**
        * 计算打包的销售的书的价格
        *
        * 方式1:
        */
      def price(item: Item): Double = {
        val money = item match {
          case Book(_, price) => price
          case Bundle(_, discount, items@_*) => {
            var sum = -discount
            for (elem <- items) {
              sum += price(elem)
            }
            sum
          }
          case _ => 0
        }
        money
      }
      // 方式2
      def price2(item: Item): Double = {
        item match {
          case Book(_, price) => price
          case Bundle(_, discount, items@_*) => {
            // 不用循环
            // 把每本书的价格映射到新的序列中, 然后再求和
            items.map(price2).sum - discount
          }
          case _ => 0
        }
      }
    }
    
    // 抽象类
    abstract class Item
    
    // 样式类 Book
    case class Book(description: String, price: Double) extends Item
    
    // 捆绑的样式类
    case class Bundle(description: String, discount: Double, item: Item*) extends Item
    

    1.4 密封类

    package com.liuser.scala.note
    
    object MatchSeal {
    
        def main(args: Array[String]): Unit = {
            val amounts = Array(Dollar1(100),Dollar1(200), new Currency1(100,"rmb"))
    
            for (elem <- amounts) {
                elem match {
                    case Dollar1(v) => println("values=" + v)
                    case Currency1(v,u)=>println("v=" +v ,"u="+u)
                    case _ => println("匹配失败")
                }
            }
    
        }
    }
    //密封类
    sealed abstract class Amount1{}
    
    case class Dollar1(value:Double) extends Amount1{}
    
    case class Currency1(value:Double,unit : String) extends Amount1{}
    

    1.5 模拟枚举类

    object EnumDemo {
      def main(args: Array[String]): Unit = {
        val seasons = Array(Spring, Summer, Autumn, Winter)
        for (season <- seasons) {
          val msg = season match {
            case Spring => "春天"
            case Summer => "夏天"
            case Autumn => "秋天"
            case Winter => "冬天"
            case _ => "每在地球上"
          }
          println(msg)
        }
      }
    }
    
    sealed abstract class Season
    
    case object Spring extends Season
    
    case object Autumn extends Season
    
    case object Summer extends Season
    
    case object Winter extends Season
    
    展开全文
  • JAVA框架

    千次阅读 2019-10-15 10:42:43
    JAVA框架SpringSpringMVCSpringBootDubboMavenRedisMybatis Spring SpringMVC SpringBoot Dubbo Maven Redis Mybatis

    Spring

    Spring是一个基于IOC和AOP的结构J2EE系统的框架,对象的生命周期由Spring来管理
    IOC(Inversion Of Control):控制反转
    DI(Dependency Inject): 依赖注入
    AOP(Aspect Oriented Program):面向切面编程(实现周边功能,比如性能统计,日志,事务管理等)
    方法
    新建对象的set和get方法
    新建bean configuration … - applicationContext.xml、并在这个xml配置文件(SpringIOC容器)中使用Bean创建对象并且给对象及其属性赋值

        <bean id="id(唯一)" class="包名.类名">
            <property name="属性名" value="属性值" />
            <property name="属性名" ref="属性映射(对应对象的id值)" />
        </bean>
    

    然后通过主函数中 ApplicationContext取出对象

     public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            类 实例名 = (类名) context.getBean("id");
    

    三种依赖注入方式:set方法注入(同上)、构造方法注入( < constructor-arg value(ref)=“value” type=“type” index=“0” name=“属性名”>< /constructor-arg>)、p命名空间注入(引入p命名空间、简单类型:p:属性名=“属性值”、引用类型(除了String外):p:属性名-ref=“引用的id”)
    IOC容器赋值:如果是简单类型(8个基本+String),value; 如果是对象类型,ref=“需要引用的id值”,因此实现了对象与对象之间的依赖关系、赋值null< property name=“name” > < null/>< /property>、赋值空值< property name=“name” > < value>< /value> < /property>、集合类型赋值proprety中使用< set> < list> < array>等,可以混着用。注意< map> 中使用< entry> < key>< value>
    value与< value>注入方式的区别:value必须使用双引号,不能使用type属性,只能采用实体引用处理特殊符号,后者可以使用<![CDATA[ ]]>标记处理特殊符号
    自动装配:bean中的autowire只适用于ref类型,autowire=“byName|byType|constructor|no”、实现全局自动装配default-autowire=“byName|by…”、注解形式的自动装配@Autowired、默认是byType、 @Qualifier(“id”)、改为byName
    使用注解
    ApplicationContext中增加扫描包

    < context:component-scan base-package="包名">
    </ context:component-scan>
    

    对应包中加入注解:@Component(“id”)细化:(dao层注解:@Repository)(service层注解:@Service)(控制器层注解:@Controller)
    使用注解实现声明式事务:实现数据库的事务
    配置:配置数据库相关、配置事务管理器txManager、增加对事务的支持;使用:方法明前增加注解@Transactional并增加其属性和方法
    AOP:前置通知、后置通知、环绕通知、异常通知
    实现方式:实现类、实现接口、注解、配置
    接口形式AOP:实现接口并重写方法(前置MethodBeforeAdvice)(后置AfterReturningAdvice)(环绕MethodInterceptor)(异常ThrowsAdvice)、 ApplicationContext中加入业务类方法的对象和通知类方法的对象、增加配置:

    < aop:config>
    		<!-- 切入点(连接线的一端:业务类的具体方法) -->
    		< aop:pointcut expression="execution(public * 业务类名.方法名(参数类型))"   id="poioncut"/>
    		<!-- (连接线的另一端:通知类) -->
            < aop:advisor advice-ref="通知类名"  pointcut-ref="poioncut" />
    </aop:config>
    

    环绕通知:可以获取目标方法的全部控制权,目标方法的一切信息可以通过invocation参数获取到,底层是通过拦截器实现的、环绕通知类实现MethodInterceptor接口和invoke方法, result = invocation.proceed() ;中result获得返回值,invocation.proceed()实现业务类方法执行,try中实现前置通知和后置通知、catch中捕获异常并实现异常通知
    注解形式AOP:@Component引入注解识别@Aspect修饰类形成通知类 @Before(pointcut=“execution(public * 业务类名.方法名(参数类型))”)修饰方法形成通知前置方法、后置@AfterReturning(returning=“returningValue”)、异常@AfterThrowing(throwing=“e”)、环绕@Around、方法中的参数可以使用JoinPoint jp、返回值参数Object returningValue、返回异常参数NullPointerException e、环绕通知中参数使用ProceedingJoinPoint jp
    配置:增加扫描包、开启AOP注解代理< aop:aspectj-autoproxy>< /aop:aspectj-autoproxy>
    配置形式AOP:写通知类logSchema及其通知方法,并将通知类和业务类加入到IOC容器中,applicationContext配置:

    <aop:config>
    		<!-- 切入点(连接线的一端:业务类的具体方法) -->
    		<aop:pointcut expression=""   id="pcShema"/>
    		<!-- 原方法(连接线的另一端:通知类)<aop:advisor advice-ref="logSchea"  pointcut-ref="pcShema" />-->
    		 <!-- schema方式 -->
    		 <aop:aspect ref="logSchema">
    		 <!-- 连接线:连接业务和通知before -->
    		 <aop:before method="before" pointcut-ref="pcShema"/>
    		 <!-- 连接线:连接业务和通知afterReturning -->
    		 <aop:after-returning method="afterReturning" returning="returnValue" pointcut-ref="pcShema"/>
    		 <!-- 连接线:连接业务和通知Exception -->
    		 <aop:after-throwing method="Exception" pointcut-ref="pcShema" throwing="e"/>
    		 <!-- 环绕通知 -->
    		 <aop:around method="around" pointcut-ref="pcShema" />
             </aop:aspect>
    </aop:config>
    

    WEB项目整合Spring
    IOC初始化:当服务启动时(tomcat),通过监听器将SpringIOC容器初始化一次(该监听器 spring-web.jar已经提供)web.xml配置、推荐方法:

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
      			classpath:applicationContext.xml,
      			<!--.默认约定的位置:WEB-INF/applicationContext.xml-->
      			classpath:applicationContext-*.xml
      	</param-value>
    </context-param>
    

    将applicationContext分层:cotroller、service、dao并分别实例化和依赖注入
    实现Web容器和IOC容器的整合(手动方式):从IOC容器中求出实例对象、一般在servlet初始化中实现

    public void init() throws ServletException  {
    		//ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext-Service");
    		ApplicationContext context=WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
    		studentService=(IStudentService)context.getBean("studentService");
    		<!--类 实例名 = (类名) context.getBean("id");-->
    	}
    

    最后完善web项目

    Spring进阶

    注解形式存放bean
    (配置类)必须有@Configuration注解

    //存bean
    @bean
    //取bean
    ApplicationContext context  = new AnnotationConfigApplicationContext(配置类.class) ;
    

    三层组件:(@Controller、@Service、@Repository -> @Component)+配置文件或者注解扫描器@component-scan(只对三层组件负责)、扫描器指定规则(FilterType(ANNOTATION,ASSIGNABLE_TYPE,CUSTOM))
    非三层组件(转换器): @Bean+方法的返回值、@import(直接编写到@Import中且id值是全类名、——自定义ImportSelector接口的实现类,通过selectimports方法实现(方法的返回值就是要纳入IoC容器的Bean),并且告知程序自己编写的实现类@Import({Orange.class,MyImportSelector.class})、——编写ImportBeanDefinitionRegistrar接口的实现类,重写方法
    @Import({Orange.class,MyImportSelector.class,ImportBeanDefinitionRegistrar.class})并且告知程序自己编写的实现类)、FactoryBean(工厂Bean、准备bean实现类和重写方法,注册bean注册到@Bean中)
    bean的作用域:scope(singleton)单例默认值、@scope(prototype)多实例(singleton:容器在初始化时,就会创建对象(唯一的一个),支持延迟加载@Lazy、prototype:容器在初始化时,不创建对象;只是在每次使用时创建对象)
    条件注解:可以让某一个Bean在某些条件下加入Ioc容器,其他情况下不加入容器,通过实现condition接口
    Bean的生命周期:创建(new …)、初始化(赋初值)、 …、销毁
    @Bean+返回值方式

    @Bean(value="stu",initMethod = "myInit",destroyMethod = "myDestroy") 
    

    三层组件功能性注解方式:将响应组件加入@Component(value="")注解、 给初始化方法加@PostConstruct、给销毁方法加@PreDestroy
    三次组件接口方法:InitializingBean初始化、DisposableBean 销毁并实现其中的方法
    接口BeanPostProcessor:拦截了所有中容器的Bean,并且可以进行bean的初始化 、销毁
    BeanFactoryPostProcessor:bean被实例化之前
    BeanDefinitionRegistryPostProcessor:bean被加载之前
    具体顺序:BeanDefinitionRegistryPostProcessor(a) ->加载bean->BeanFactoryPostProcessor(b)->实例化bean->BeanPostProcessor
    自动装配
    @Autowired根据类型自动注入、结合@Qualifier("")根据名字注入、默认值@primary、@Autowired(required=false)修改未匹配为null
    三层组件:如果@Autowired在属性前标注则不调用set方式;如果标注在set前面则调用set方式;不能放在方法的参数前
    Bean+返回值:@Autowired可以在方法的参数前(也可以省略)、方法前(如果只有一个有参构造方法则@Autowired也可以省略)
    @Resource根据名字自动注入,没有名字然后根据类型
    @Inject默认根据类型匹配(引入jar包)
    底层组件:实现Aware的子接口,从而获取到开发的组件对象,对对象进行操作
    环境切换:bean前@Profile说明条件注入
    激活
    1.运行环境中设置参数-Dspring.profiles.active=@Profile环境名
    2.硬编码:IoC容器在使用时必须refresh(),需要设置保存点|配置类的编写处

    //注解方式
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext() ;
    ConfigurableEnvironment environment = (ConfigurableEnvironment)context.getEnvironment();
    environment.setActiveProfiles("@Profile环境名");
    //保存点
    context.register(配置类名.class);
    context.refresh();
    

    监听器:可以监听事件,监听的对象必须是ApplicationEvent自身或其子类/子接口
    1.监听类实现ApplicationEvent接口
    2.监听类注解形式申明是监听方法

    @Component
    public class MyListener {
    //本方法是一个监听方法
    @EventListener(classes = {ApplicationEvent.class})
    public void myListenerMethod(ApplicationEvent event){
    System.out.println("--0000000--------"+event);
        }
    }
    

    SpringMVC

    SpringMVC构建Web应用程序的全功能MVC模块
    配置与使用
    JSP发出请求
    将Servlet的访问通过web.xml配置文件拦截请求,交给SpringMVC处理、快速创建:alt+/ dispatcherServlet

    	<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
    	<servlet>
    		<servlet-name>springDispatcherServlet</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<!--默认路径/WEB-INF/springDispatcherServlet-servlet.xml-->
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>classpath:springmvc.xml</param-value>
    		</init-param>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<!-- Map all requests to the DispatcherServlet for handling -->
    	<servlet-mapping>
    		<servlet-name>springDispatcherServlet</servlet-name>
    		<url-pattern>/</url-pattern>
    	</servlet-mapping>
    

    springmvc.xml中配置扫描包和视图解析器(用于解析返回值地址并通过请求转发实现页面跳转)

    	<!--配置视图解析器(InternalResourceViewResolver)  -->
    	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<property name="prefix" value="/views/"></property>
    		<property name="suffix" value=".jsp"></property>
    	</bean>
    	<!--view-name会被视图解析器加上前缀和后缀  -->
    

    控制器中添加注解@controller(实现扫描包扫描)@RequestMapping(映射匹配类、类之前)、@RequestMapping(value,method,params)(映射匹配方法、方法之前)(可以增加个属性和约束条件对请求参数进行约束)、@PathVariable获取动态参数
    REST风格:GET :查、POST :增、DELETE :删、PUT :改
    springmvc实现给普通浏览器增加 put|delete请求方式 :put|post请求方式的步骤:
    1.web.xml增加HiddenHttpMethodFilte过滤器

    <filter>
    			<filter-name>HiddenHttpMethodFilte</filter-name>
    			<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
    			<filter-name>HiddenHttpMethodFilte</filter-name>
    			<url-pattern>/*</url-pattern>
    </filter-mapping>
    

    2.表单提交必须是post方法且通过隐藏域的value值设置实际的请求方式DELETE|PUT (< input type=“hidden” name="_method" value=“DELETE”/>)
    3.控制器实现提交方式约束匹配、参数获取和功能执行
    处理数据模型:跳转时需要带数据和页面(ModelAndView、ModelMap、Map、Model -数据放在了request作用域)
    ModelAndView:

    public ModelAndView testModelAndView() {
    ModelAndView mv = new ModelAndView("jsp");
    mv.addObject("属性名", 属性值或对象);
    return mv;}
    

    ModelMap:

    public String testModelMap(ModelMap mm) {
    mm.put("属性名", 属性值或对象);
    return "jsp";}
    

    Map:

    public String testMap(Map<String,Object> m) {
    m.put("属性名", 属性值或对象);
    return "jsp";}
    

    Model:

    public String testMode(Model model) {
    model.addAttribute("属性名", 属性值或对象);
    return "jsp";}
    

    @SessionAttributes(value\type):实现将数据放在request中的同时也将数据放在session中
    @ModelAttribute:通过@ModelAttribute修饰的方法,会在每次请求前先执行;并且该方法的参数map.put()可以将对象放入即将查询的参数中,可以进行属性值的修改
    视图的顶级接口:Views
    视图解析器的顶级接口:ViewsResolver
    国际化:针对不同地区、不同国家进行不同的显示 (创建资源文件、配置springmvc.xml并加载资源文件、通过jstl使用国际化)

    <!--加载国际化资源文件-->
    	<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    	<property name="basename" value="i18n"></property>
    	</bean>
    

    请求方法改变:return “redirect:/views/success.jsp”;
    直接跳转(不通过控制器):< mvc:view-controller path=“handle/a” view-name=“success” /> < mvc:annotation-driven></ mvc:annotation-driven>
    静态资源访问:(MVC交给Servlet处理)加入配置:

    <!--该注解会让springmvc:接收一个请求,并且该请求没有对应@requestmapping时,将该请求交给服务器默认的servlet去处理(直接访问)-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>
    <mvc:annotation-driven></mvc:annotation-driven>
    

    类型转换:Spring自带一些常见的类型转换器、自定义类型转换器MyConverter(编写自定义类型转换类并引入接口Converter、配置将MyConverter加入到springmvc中、测试转换器)@RequestParam(“name”)是触发转换器的桥梁
    格式化:springMVC配置数据格式化注解所依赖的bean+通过注解使用@DateTimeFormat(pattern=“yyyy-MM-dd”)@NumberFormat(parttern="###,#") 、错误消息处理(参数BindingResult result返回前面参数的错误信息,可以放在map里面传递到前端打印)、数据检验:JSR303和Hibernate Validator(jar包+配置(自动加载一个LocalValidatorFactoryBean类)+注解(给校验的对象前增加@Valid))
    JSON:@ResponseBod修饰的方法,会将该方法的返回值以一个json数组的形式返回给前台
    文件上传:配置MultipartResolver将其加入springIOC容器(可以设置属性)、处理方法中(参数@RequestParam(“file”) MultipartFile file获取前端传过来的文件数据)根据IO方法写输入输出流
    拦截器:原理和过滤器原理相同(编写拦截器实现HandlerInterceptor接口、处理请求响应和渲染过程+将自己写的拦截器配置到springmvc中(< mvc:interceptor>))
    异常处理:如果一个方法用于处理异常,并且只处理当前类中的异常:@ExceptionHandler({Exception.class});如果一个方法用于处理异常,并且处理所有类中的异常: 类前加@ControllerAdvice、 处理异常的方法前加@ExceptionHandler;自定义异常显示页面@ResponseStatus;
    通过配置实现的异常处理:SimpleMappingExceptionResolver

    <bean  class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    		<!-- 如果发生异常,异常对象会被保存在  exceptionAttribute的value值中;并且会放入request域中;异常变量的默认值是exception-->
    		<!--<property name="exceptionAttribute" value="exception"></property>-->
    			<property name="exceptionMappings">
    					<props>
    						<!-- 相当于catch(ArithmeticException exception){ 跳转:error页面 } -->
    						<prop key="java.lang.ArithmeticException">error</prop>
    						<prop key="java.lang.NullPointerException">error</prop>
    					</props>
    			</property>
    </bean>
    

    Mybatis

    Mybatis可以简化JDBC操作和实现数据的持久化
    ORM:Object Relational Mapping开发人员 像操作对象一样操作数据库表
    SqlSessionFactory -> SqlSession ->StudentMapper ->CRUD
    配置与使用
    引入mybatis-jar包和数据库jar包
    配置mybatis
    conf.xml:配置数据库信息和需要加载的映射文件(运行环境默认是development、可以通过build的第二参数指定数据库环境)

    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    <environments default="development">
    <environment id="development">
    <transactionManager type="JDBC"/>
    <!--如果使用的事务方式为jdbc,则需要手工commit提交,即session.commit()-->
    <dataSource type="POOLED">
    <property name="driver" value="${driver}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>
    </dataSource>
    </environment>
    </environments>
    <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
    </configuration>
    

    表 - 类
    映射文件xxMapper.xml :增删改查标签< select>

    <?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">
    <mapper namespace="org.mybatis.example.BlogMapper">
    <select id="selectBlog" resultType="Blog" parameterType="int>
    <!--parameterType:输入参数的类型,resultType:返回类型、输入参数parameterType 和输出参数resultType,在形式上都只能有一个、如果输入参数:是简单类型(8个基本类型+String)是可以使用任何占位符,#{xxxx}、如果是对象类型,则必须是对象的属性#{属性名}-->
    select * from Blog where id = #{id}
    </select>
    </mapper>
    

    测试类
    session.selectOne(“需要查询的SQL的namespace.id”,“SQL的参数值”)

    public static void main(String[] args) throws IOException {
    		//加载MyBatis配置文件(为了访问数据库)
    		Reader reader = Resources.getResourceAsReader("conf.xml") ;
    		SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader) ;
    		//session - connection
    		SqlSession session = sessionFactory.openSession() ;
    		String statement = "org.lanqiao.entity.personMapper.queryPersonById" ;
    		Student person = session.selectOne( statement,1 ) ;
    		System.out.println(person);
    		session.close(); 
    

    mapper动态代理方式CRUD:省略掉statement,即根据约定直接可以定位出SQL语句
    配置环境:mybatis.jar/ojdbc.jar、conf.xml、mapper.xml
    新建类和方法实现接口必须遵循以下约定:
    1.方法名和mapper.xml文件中标签的id值相同
    2.方法的输入参数和mapper.xml文件中标签的parameterType类型一致 (如果mapper.xml的标签中没有parameterType,则说明方法没有输入参数)
    3.方法的返回值和mapper.xml文件中标签的resultType类型一致(无论查询结果是一个还是多个(student、List< Student>),在mapper.xml标签中的resultType中只写 一个(Student);如果没有resultType,则说明方法的返回值为void)
    4.namespace的值就是接口的全类名( 接口 - mapper.xml 一 一对应)
    5.测试中使用

    T t = session.getMapper(接口.class) ;
    返回类 返回值 = t.接口中的方法(参数) ;//接口中的方法->SQL语句
    StudentMapper studentMapper = session.getMapper(StudentMapper.class) ;
    studentMapper.方法();
    

    6.优化:将配置信息单独放入db.properties文件中然后再动态引入、MyBatis全局参数在conf.xml中设置、设置别名
    类型转换器(自定义):实现java类型和jdbc类型的相互转化
    1.创建转换器:实现TypeHandler接口或者继承BaseTypeHandler
    2.配置conf.xml< typeHandlers>和mapper.xml与类对应(resultMap可以实现类型转换和属性-字段的映射关系)
    输入参数:parameterType(简单类型:8个基本类型+String、.对象类型)、取值方法(#{}、${}都可以获取对象值和嵌套类型对象)(不同之处:简单类型的标识符、#{}会给String类型加上单引号、#{}可以防止sql注入)、参数类型为HashMap(用map中key的值匹配占位符#{stuAge},如果匹配成功就用map的value替换占位符)、参数为多个数据(可以使用[arg3, arg2, arg1, arg0, param3, param4, param1, param2]、在接口中通过@Param(“sNo”) 指定sql中参数的名字)
    输出参数:resultType、resultMap(实体类的属性、数据表的字段: 类型、名字不同时、除此之外:实体类属性和数据字段不匹配时可以使用resultType+HashMap)、(输出类型为简单类型、对象类型、集合类型(resultType依然写集合的元素类型)、hashmap类型(本身是一个集合,可以存放多个元素))
    输出参数为Hashmap

    //根据@MapKey("stuNo")知道 Map的key是stuNo
        @MapKey("STUNO")  //oracle的元数据(字段名、表名 )都是大写
        HashMap<Integer,Student> queryStudentsByHashMap();
    //程序根据select的返回值 知道map的value就是 Student ,
        <select id="queryStudentsByHashMap" resultType="HashMap">
             select stuNo ,stuName ,stuAge  from student
        </select>
    

    储存过程:数据库新建储存过程、Mapper中使用CALL调用存储过程(通过statementType="CALLABLE"设置SQL的执行方式是存储过程、存储过程的输入参数需要通过HashMap来指定)、使用过程(通过hashmap的put方法传入输入参数的值、通过hashmap的Get方法获取输出参数的值。)
    动态sql语句:where-if(只能处理第一个有效的and)

    <select id="queryStuByNOrAWishSQLTag" 	 parameterType="student"	resultType="student" >
    		select stuno,stuname,stuage from student
    		<where>
    			<!-- <if test="student有stuname属性 且不为null"> -->
    			<if test="stuName !=null and stuName!=''  "> 
    				and stuname = #{stuName}
    			</if>
    			<if test="stuAge !=null and stuAge!=0  "> 
    				 and stuage = #{stuAge}
    			</if>
    		</where>
    	</select>
    

    foreach:< foreach>迭代的类型:数组、对象数组、集合、属性(包括属性类)、(简单类型的数组:在mapper.xml中必须用array代替该数组、集合类型的数组:必须用list代替该集合、对象数组:必须用object代替该集合、使用时用对象.属性)

    	<select id="queryStudentsWithNosInGrade"  parameterType="grade" resultType="student">
    	  	select * from student 
    	  	<where>
    	  		 <if test="stuNos!=null and stuNos.size>0">
    	  		 	<foreach collection="stuNos" open=" and  stuno in (" close=")" 
    	  		 		item="stuNo" separator=",">   
    	  		 		#{stuNo}
    	  		 		<!--此时stuNo为对象的属性,本身是一个集合-->
    	  		 	</foreach>
    	  		 </if>
    	  	</where>
    	</select>
    

    refid:(提取并引用sql语句)
    trim:增删改中有效使用

    //添加where并处理拼接sql中开头或结尾的第一个和最后一个and
    <trim prefix="where" prefixOverrides="and" suffixOverrides="and">
    

    关联查询:一对一(业务扩展类核心:用resultType指定类的属性包含多表查询的所有字段、resultMap:通过属性成员建立起对应关系,对象成员使用 association映射、javaType指定该属性的类型(一对一:association,一对多:collection))一对多:resultMap:通过属性成员建立起对应关系,对象成员使用 collection映射、ofType指定该属性中元素的类型
    日志:通过日志信息,详细的阅读mybatis执行情况
    log4j.jar包、开启日志conf.xml、编写配置日志输出文件log4j.properties

    <settings>
    <!-- 开启日志,并指定使用的具体日志 -->
    <setting name="logImpl" value="LOG4J"/>
    </settings>
    

    延迟加载:实现部分查找和懒加载
    开启延迟加载conf.xml、配置mapper.xml(查询对象的sql是通过select属性指定的关联mapper,并且通过column指定外键名)、如果增加了mapper.xml,要修改conf.xml配置文件(将新增的mapper.xml加载进去)

    <settings>
    <!-- 开启延迟加载 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 关闭立即加载 -->
    <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
    

    查询缓存
    一级缓存:MyBatis默认开启一级缓存,如果用同样SqlSession对象查询相同的数据,则只会在第一次查询时向数据库发送SQL语句,并将查询的结果 放入到SQLSESSION中(作为缓存在);后续再次查询该同样的对象时,则直接从缓存中查询该对象即可(即省略了数据库的访问)、commit语句会清理数据库缓存
    二级缓存:只要产生的Mapper对象来自于同一namespace,则这些对象共享二级缓存
    conf.xml中配置二级缓存< setting name=“cacheEnabled” value=“true”/>
    mapper.xml中声明开启 < cache/>
    Mapper的对应类、对应类的父类和级联属性都要需要实现序列化接口Serializable
    触发将对象写入二级缓存的时机为SqlSession对象的close()方法
    禁用二级缓存:select标签中 useCache=“false”
    清理二级缓存:select标签中 flushCache="true"或者 其他操作的commit(),不能用查询的commit();
    ehcache二级缓存整合:jar包、编写ehcache配置文件 Ehcache.xml、Mapper.xml中开启

    <cache  type="org.mybatis.caches.ehcache.EhcacheCache">
    <property name="maxElementsInMemory" value="2000"/>
    <property name="maxElementsOnDisk" value="3000"/>
    </cache>
    

    逆向工程:表、类、接口、mapper.xml四者密切相关,根据表生成其他三个
    jar包:mybatis-generator-core.jar、mybatis.jar、ojdbc.jar
    逆向工程的配置文件generator.xml
    执行

    public static void main(String[] args) throws IOException, XMLParserException, InvalidConfigurationException, SQLException, InterruptedException {
            //配置文件
    		File file = new File("src/generator.xml") ;
    		List<String> warnings = new ArrayList<>();
    		ConfigurationParser cp = new ConfigurationParser(warnings);
    		Configuration config = cp.parseConfiguration(file);
    		DefaultShellCallback callBack = new DefaultShellCallback(true);
    		//逆向工程的核心类
    		MyBatisGenerator generator = new MyBatisGenerator(config, callBack,warnings  );
    		generator.generate(null);
    	}
    

    增加conf.xml和db.properties文件
    使用query by CriteriaQBC

    Mybatis进阶

    数据库版本切换
    conf.xml切换environment并配置Provider别名

    <!-- 配置数据库支持类-->
    <databaseIdProvider type="DB_VENDOR">
            <property name="MySQL" value="mysql" />
            <property name="Oracle" value="oracle" />
    </databaseIdProvider>
    

    mapper.xml写不同数据SQL语句,配置databaseId=“Provider别名”

    <select id="queryStudentByNoWithONGL" parameterType="student" resultType="student" databaseId="oracle">
    

    注解方式
    将sql语句写在接口的方法上@Select("")
    将接口的全类名写入< mapper>,或者批量写入

    <mappers>
    	<!--以下可以将com.yanqun.mapper 包中的注解接口和xml全部一次性引入 -->
        <package name="com.yanqun.mapper" />
    </mappers>
    

    增删改返回值可以是void、Integer、Long、Boolean,都不需要在mapper.xml中设置返回值类型
    事务提交

    //手动提交:
      sessionFactory.openSession();
      session.commit();
    //自动提交:每个dml语句 自动提交
      sessionFactory.openSession(true);
    

    自增语句

    //mysql设置自增数据为Integer类型的null,设置返回的自增数据,实现回写
    useGeneratedKeys="true" keyProperty="number"
    //oracle通过序列模拟实现(before和after方式)
    

    鉴别器 : 对查询结果进行分支处理: 如果是a年级则真名,如果b年级显示昵称,由于字段不一致需要在resultMap中写

    <discriminator javaType="string"  column="gname">
        <case value="a" resultType="com.yanqun.entity.Student" >
             <result  column="sname" property="stuName"/>
        </case>
        <case value="b" resultType="student">
             <result  column="nickname" property="stuName"/>
        </case>
    </discriminator>
    

    架构分析
    接口层:广义接口(增删改查)
    数据处理层:参数处理,sql解析与执行,处理结果
    框架支撑层:事务管理,缓存机制,连接池管理
    引导层:XML配置,注解方式
    源码分析
    获取SqlSessionFactory对象
    (通过parseConfiguration()在configuration标签设置了properties、settings、environments等属性标签)(所有的配置信息放在Configuration对象中)(解析所有的Mapper.xml文件(分析其中的增删改查标签)成MappedStatement对象并放在Configuration中)(SqlSessionFactory对象 ->DefaultSqlSessionFactory ->Configuration ->包含了一切配置信息)
    获取SqlSession对象
    (根据不同的类型execType,产生不同的 Executorconfiguration.newExecutor(tx, execType) ->SimpleExecutor、通过装饰模式将刚才产生的executor包装成一个更加强大的executor:executor = (Executor) interceptorChain.pluginAll(executor)、返回DefaultSqlSession(configuration,executor,事务))
    (SqlSession ->openSession()->openSessionFromDataSource()->DefaultSqlSession对象->执行SQL)
    获取XxxMapper对象
    (代理接口中的方法、mapper.xml中的< select>等标签)(SqlSession(configuration,executor,事务)、代理接口的对象(MapperInterface)、methodCache(存放查询缓存,底层是CurrentHashMap))
    执行< select>等标签中定义的SQL语句
    (MyBatis底层在执行CRUD时 可能会涉及到四个处理器:处理对象ParameterHandler的处理器:StatementHandler、处理参数的处理器:ParameterHandler、类转化器处理器:TypeHandler、处理结果集的处理器:ResultSetHandler)(动态代理:MapperProxy对象、执行增删改查->MapperProxy/invoke()–>InvocationHandler :JDK动态代理接口)(实际调用增删改查的方法:mapperMethod.execute(sqlSession,args) )(处理增删改查方法的参数:method.convertArgsToSqlCommandParam(args))(boundSql :将我们写的SQL和参数值进行了拼接后的对象,即最终能被真正执行的SQL)(通过Executor执行sql语句、底层执行方法:PreparedStatement的execute())
    自定义插件
    四大核心对象:都涉及到了拦截器用于增强并且包含了该增强操作
    StatementHandler、ParameterHandler、ResultSetHandler、Executor
    步骤
    编写拦截器

    //目標方法target
            Object target = invocation.getTarget();
    //目标对象target的包装后的产物MetaObject
            MetaObject metaObject = SystemMetaObject.forObject(target);
    //metaObject.getValue获取参数
            Object value = metaObject.getValue("parameterHandler.parameterObject");
    //metaObject.setValue设置参数
            metaObject.setValue("parameterHandler.parameterObject",2);
    //放行
            Object proceed = invocation.proceed();
            return proceed;
    

    编写签名注解

    @Intercepts({
    //@Signature(type = StatementHandler.class , method ="query",args = {Statement.class, ResultHandler.class})
    @Signature(type = StatementHandler.class , method ="parameterize",args = {Statement.class})
    })
    

    conf.xml配置

    <plugins>
            <plugin interceptor="com.yanqun.my.interceptors.MyInterceptor">
                <property name="name" value="zs"/>
                <property name="age" value="23"/>
            </plugin>
    </plugins>
    

    批量操作:预编译一次sessionFactory.openSession(ExecutorType.BATCH)、不推荐拼接SQL方式
    分页插件:PageHelper
    引入jar(jsqlparser-0.9.5.jar、pagehelper-5.1.8.jar)
    配置conf.xml插件
    执行PageHelper.startPage(当前页, 每页数据)
    使用页面信息(PageInfo、Page对象)
    插件:Mybatis-Plus、通用Mapper

    Maven

    Maven是一个基于Java平台的自动化构建工具–将java、js、jsp等各个文件进行筛选、组装,变成一个可以直接发布的项目
    http://www.mvnrepository.com
    清理:删除编译的结果,为重新编译做准备
    编译:java->class
    测试:针对于项目中的关键点进行测试,亦可用项目中的测试代码去测试开发代码;
    报告:将测试的结果进行显示
    打包:将项目中包含的多个文件 压缩成一个文件, 用于安装或部署:(java项目-jar、web项目-war)
    安装:将打成的包放到本地仓库,供其他项目使用
    部署:将打成的包放到服务器上准备运行
    下载配置maven
    使用maven
    mvn compile 只编译main目录中的java文件
    mvn test 测试
    mvn package 打成jar/war
    mvn install 将开发的模块放入本地仓库供其他模块使用(放入的位置是通过gav决定)
    mvn clean 删除target目录(删除编译文件的目录)
    运行mvn命令必须在pom.xml文件所在目录
    目录结构

    -src				
    	--main		          程序功能代码
    		--java		      java代码  
    		--resources       资源代码、配置代码
    	--test			      测试代码
    		--java			
    		--resources	
    pom.xml                   项目对象模型
    

    POM(项目对象模型):Maven工程的基本工作单元XML文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖

    	<groupId>域名翻转.项目名</groupId>
    	<groupId>org.lanqiao.maven</groupId>
    
    	<artifactId>子模块名</artifactId>
    	<artifactId>HelloWorld</artifactId>
    
    	<version>版本号</version>
    	<version>0.0.1-SNAPSHOT</version>
    

    依赖
    在maven项目中如果要使用一个当时不存在的Jar或模块,则可以通过依赖实现(例如依赖测试类)

    <dependency>
    	<groupId>junit</groupId>
    	<artifactId>junit</artifactId>
    	<version>4.0</version>
    	<scope>test</scope>
    </dependency>
    

    依赖排除:

    <exclusions>
    <exclusion>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    </exclusion>
    </exclusions>
    

    依赖关联:
    A.jar->B.jar->C.jar
    要使 A.jar ->C.jar:当且仅当 B.jar依赖于C.jar的范围是compile
    依赖原则:路径最短原则(防止冲突)
    路径相同距离:同一个pom文件后覆盖前、不同pom文件前覆盖后
    统一编号和版本:

    <properties>  
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <xx>版本号</xx>
    </properties>  
     //使用动态版本
     <version>${xx} </version>
    

    生命周期
    clean lifecycle :清理 pre-clean、clean、post-clearn
    default lifecycle :默认(常用)
    site lifecycle:站点 pre-site、site、post-site site-deploy
    继承
    父->子工程,可以通过父工程 统一管理依赖的版本
    父工程pom方式打包
    在父工程pom中编写依赖

    <dependencyManagement>
      	<dependencies>
      		<dependency>
    

    给当前工程继承父工程

    <parent>
    <!-- 1加入父工程坐标gav -->
    <groupId>org.lanqiao.maven</groupId>
    <artifactId>B</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!-- 2当前工程的Pom.xml到父工程的Pom.xml之间的相对路径 --> 
    <relativePath>../B/pom.xml</relativePath>
    </parent>
    

    在子类中需要声明使用哪些父类的依赖

    <dependency>
    <!-- 声明:需要使用到父类的junit(只需要ga) -->
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    </dependency>
    

    聚和
    聚合可以将拆分的多个子工程合起来共同操作(前置关联工程的install操作)
    新建总工程中配置:只能配置在打包为pom方式的maven中

    <modules>
    <!--项目的根路径  -->
    <module>../Maven1</module>
    <module>../Maven2</module>
    </modules>
    

    配置完聚合之后,操作总工程会自动操作改聚合中配置过的工程
    部署Web
    新建Maven项目并打war包
    pom中配置servlet-api

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
    

    补全路径名:webapp->WEB-INF->web.xml
    实际开发中开发人员将自己的项目开发完毕后打成war包(package) 交给实施人员去部署

    SpringBoot

    springboot可以快速开发微服务模块,springboot将各个应用/三方框架设置成了一个个“场景”starthttps://spring.io可以自动生成SpringBoot的文件项目
    准备JAVA和MAVEN的环境、实现springboot开发工具、目录结构resources(static:静态资源(js css 图片 音频 视频)
    、templates:模板文件(模版引擎freemarker ,thymeleaf;默认不支持jsp)、application.properties: 配置文件对端口号等服务端信息进行配置)
    注解
    @SpringBootApplication:springboot的主配置类
    @Configuration:表示“配置类”:该类是一个配置类 、自动纳入Spring容器(@Component)
    @EnableAutoConfiguration:使spring boot可以自动配置:spring boot在启动时,就会将该包及所有的子包全部纳入spring容器,会根据META-INF/spring.factories找到相应的三方依赖,并将这些依赖引入本项目、Xxx_AutoConfiguration会实现自动装配并给予默认值
    @SpringBootConfiguration:自己代码的自动配置
    @ConditionalOnXxx:当这些条件都满足时此配置自动装配生效(手工修改改 自动装配:XxxProperties文件中的prefix.属性名=value
    配置文件
    application.properties : k=v,或行内写法(k: v,[Set/List/数组] {map,对象类型的属性},并且 []可省,{}不能省)
    application.yml:k:空格v、通过垂直对齐指定层次关系、默认可以不写引号 (双引号会将其中的转义符进行转义)
    @Component:将此类型加入Javabean
    @ConfigurationProperties(prefix=“student”):根据前缀名实现该类型自动装配,同yml文件相匹配
    @Autowired:自动装配从bean中取值
    @Value(""):实现单个值注入,可以和全局配置文件实现互补
    @Validated:开启jsr303数据校验的注解
    @Test:此类型为测试类
    @ImportResource(locations={“classpath:spring.xml”}):识别spring.xml配置文件
    @bean:通过实现注解配置将此类型加入到bean中

    @ConfigurationProperties@Value
    注值批量注入单个
    松散语法支持不支持
    SpEL不支持支持
    JSR303数据校验支持不支持
    注入复杂类型支持不支持

    多环境切换:配置环境切换和动态环境切换
    配置文件的位置:properties的优先级要大于yml
    外部文件和外部参数:Run configuration ,argumenets方式和命令控制行
    日志:spring boot默认选用slf4j和logback、日志级别、日志信息格式、日志输出路径
    Web静态资源:静态资源的存放路径通过WebMvcAutoConfiguration类-addResourceHandlers()指定:/webjars/成静态资源存放目录: {“classpath:/META-INF/resources/”,“classpath:/resources/”,“classpath:/static/”,“classpath:/public/”}以上目录存放资源文件后,访问时不需要加前缀、欢迎页(任意一个静态资源目录中的Index.html)、Logo(任意一个静态资源目录中的favicon.ico)、自定义静态资源存放路径(spring.resources.static-locations=…)
    Web动态资源:默认不支持jsp、html等,但是推荐使用模板引擎thymeleaf(网页=模板+数据)
    引入依赖

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
    </dependency>
    <dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
    </dependency>
    

    使用thymeleaf只需要将文件放入目录:“classpath:/templates/”; 文件的后缀: “.html”;
    thymeleaf的th指定方式和符号取值方式(usingthymeleaf文档)

    Dubbo

    RPC(Remote Procedure Call):远程过程调用
    SOA(Service-Oriented Architecture):面向服务架构
    Dubbo中控制器和服务端分离
    步骤:提供方服务器运行提供方提供的服务、注册中心发布服务、消费方订阅服务、注册中心推送服务、消费方向提供方调用服务
    开发dubbo程序:准备环境(linux环境中的jdk及其环境变量和zookeeper)、服务方(引入依赖:pom.xml、接口及实现类@Service、补全WEB-INF/web.xml、配置spring:applicationContext.xml)、消费方(引入依赖:pom.xml改端口号、补全WEB-INF/web.xml、配置springmvc、编写控制器代码@Reference:用于访问服务方提供的服务代码)、监听器(下载incubator-dubbo-ops、打包war、在linux中的tomcat中运行)

    Quartz

    quartz:定时执行、异步任务
    任务:Job、触发器:定义时间、调度器:将任务和触发器 一一对应
    步骤
    引入jar包
    新建类制定具体任务
    新建类任务调用的实现继承Job接口并执行具体任务

    public class PlanJob implements Job {
        MeetingService meetingService = new MeetingService();
        //jobExecutionContext可以获取设置的各种参数值
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            TriggerKey triggerkey =
                    jobExecutionContext.getTrigger().getKey();
            JobKey jobKey = jobExecutionContext.getJobDetail().getKey();
            System.out.println("----");
            System.out.println(triggerkey+"\n"+jobKey);
            JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
            List<String> infos = (List<String>)jobDataMap.get("infos");
            System.out.println(infos);
            //存放 计划执行的任务...
            meetingService.calClassMeeting();
        }
    }
    

    新建测试方法类(产生)

    public class TestQuartz {
    //XxxBuilder ->withIdentity()-->Xxx
    public static void main(String[] args) throws SchedulerException, InterruptedException, ParseException {
    //        PlanJob
            JobBuilder jobBuilder = JobBuilder.newJob(PlanJob.class);//PlanJob PlanJob PlanJob
            //产生实际使用的Job
            JobDetail jobDetail = jobBuilder.withIdentity("meeting Job", "group1").build();
    
            //向Job的execute()中传入一些参数。。。
    //        JobDatMap
            JobDataMap jobDataMap = jobDetail.getJobDataMap();
            List<String> names = Arrays.asList(new String[]{"zs","ls","ww"});
            jobDataMap.put("infos",names);
    
            // 触发器(Trigger):时间规则  ,依赖2个对象(TriggerBuilder ,Scheduel)
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            triggerBuilder = triggerBuilder.withIdentity("meeting trigger", "group1");
            triggerBuilder.startNow();//当满足条件时  立刻执行
            // 2019-03-13 09:46:30   --  // 2019-03-13 09:46:45
    
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date start = sdf.parse("2019-03-13 09:46:30");
            Date end = sdf.parse("2019-03-13 09:46:45");
    
    //        triggerBuilder.startAt(start);
    //        triggerBuilder.endAt(end);
    
            //scheduelBuilder:定执行的周期(时机)
    //        SimpleScheduleBuilder scheduelBuilder = SimpleScheduleBuilder.simpleSchedule();
    //        scheduelBuilder.withIntervalInSeconds(1) ;//每隔1秒执行一次
    //        scheduelBuilder.withRepeatCount(3) ;//重复执行3次
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("5,10,15,30,45 * * * * ? *");
            //产生触发器
            // SimpleTrigger trigger = triggerBuilder.withSchedule(ScheduleBuilder).build();
            CronTrigger trigger = triggerBuilder.withSchedule(cronScheduleBuilder).build();
    //        调度器(工厂产生调度器)
             SchedulerFactory secheduleFacotry = new StdSchedulerFactory();
            //产生调度器
            Scheduler scheduler = secheduleFacotry.getScheduler();
            //通过调度器 将 任务 和 触发器一一对应
            scheduler.scheduleJob(jobDetail,trigger) ;
            scheduler.start();
    //        scheduler.shutdown(true);
        }
    }
    

    框架整合

    Spring-MyBatis整合

    引入jar包
    配置类-表对应
    配置Spring配置文件(applicationContext.xml)

    <!-- 加载db.properties文件 -->
    <bean  id="config" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
    <property name="locations">
    <array><value>classpath:db.properties</value></array>
    </property>
    </bean>
    
    <!-- 引入service层的bean -->
    <bean id="studentService" class="org.lanqiao.service.impl.StudentServiceImpl">
    <property name="studentMapper" ref="studentMapper"></property>
    </bean>
    
    <!-- 配置配置数据库信息(替代mybatis的配置文件conf.xml) -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${driver}"></property>
    <property name="url" value="${url}"></property>
    <property name="username" value="${username}"></property>
    <property name="password" value="${password}"></property>
    </bean>
    
    <!-- 在SpringIoc容器中 创建MyBatis的核心类 SqlSesionFactory -->
    <bean id="sqlSessionFacotry" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <!-- 加载mapper.xml路径 -->
    <property name="mapperLocations" value="org/lanqiao/mapper/*.xml"></property>
    </bean>
    

    配置mapper中的sql语句
    使用Spring-MyBatis整合产物开发程序

    1. DAO层实现类继承SqlSessionDaoSupport类
    2. 直接MyBatis提供的 Mapper实现类:org.mybatis.spring.mapper.MapperFactoryBean
    <bean id="studentMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="mapperInterface" value="org.lanqiao.mapper.StudentMapper"></property>
    <property name="sqlSessionFactory" ref="sqlSessionFacotry"></property>
    </bean>
    
    1. 批量生成多个mapper
    <!--Mapper对在SpringIOC中的id默认就是首字母小写接口名,service在ref对象要首字母小写-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFacotry"></property>
    <!--指定批量产生 哪个包中的mapper对象-->
    <property name="basePackage" value="org.lanqiao.mapper"></property>
    </bean>
    

    使用:

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    context.getBean("bean") ;
    

    Spring-SpringMVC-MyBatis整合

    引入jar包
    配置类-表对应
    配置Spring配置文件(applicationContext.xml):使用Spring整合MyBatis
    编写springmvc配置文件:视图解析器、基础配置
    配置mapper中的sql语句
    配置Web配置文件

    <!-- Web项目中,引入Spring -->
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 整合SPringMVC -->
    <servlet>
    <servlet-name>springDispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext-controller.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>springDispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    Springboot-JSP整合

    新建boot项目war包
    建立基本的web项目所需要的目录结构
    webapps/WEB-INF(需要)
    webapps/WEB-INF/web.xml (不需要)
    webapps/index.jsp
    创建tomcat实例并部署项目:如果是一个war包的spring boot项目,在启动服务器tomcat时,会自动调用ServletInitializer类中的configure方法,configure方法会调用spring boot的主配置类从而启动spring boot

    Dubbo-SSM整合

    创建父工程(引入公共依赖、实体类POJO依赖、module子模块依赖、解决Maven内置tomcat打包不引入xml问题的代码)
    创建实体类(实体类需要implements Serializable接口)
    创建公共模块实现接口共用(引入实体类POJO依赖、提供公共接口)
    创建dao层(映射文件mapper、动态代理接口mapper、spring文件application(加载db文件、配置数据库信息、创建核心类sqlsessionfactory)、将核心类交给spring处理)
    创建service层(补全WEB-INF/web.xml并拦截交给spring处理、pom依赖父工程+dao层+公共接口+tomcat代码、编写spring的application文件并顺带启动dao层spring的application、service的具体实现类)
    创建显示web层(补全WEB-INF/web.xml并拦截交给springMVC处理、pom依赖父工程+公共接口+tomcat代码、编写控制器、配置sppringMVC)
    其他
    在maven中引入一个 mvn中央仓库中不存在的Jar:将jar自己安装到本地mvn仓库:cmd命令(ojdbc7.jar为例):mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc7 -Dversion=10.2.0.5.0 -Dpackaging=jar -Dfile=f:\ojdbc7.jar
    解决Maven内置tomcat打包不引入xml问题:

    # 在父工程pom.xml的<project>元素中加入
      <build>
        	<resources> 
    	  	<resource> 
    	  	<directory>src/main/java</directory> 
    	  	<includes> 
    	  	<include>**/*.xml</include> 
    	  	</includes> 
    	  	<filtering>false</filtering>
    		</resource> 
    		<resource>
    		<directory>src/main/resources</directory>
    		</resource>
    	</resources>
     </build>
    

    Spring-Redis整合

    建立java文件并引入jar包
    指定连接 Redis 服务器的相关信息redis.properties(实现分配连接池和线程)
    在spring的applicationContext配置文件中配置连接池、连接工厂和操作模板,并把RedisUtil加入bean中
    使用工具类和测试类进行Redis的访问和检测

    Spring-Quartz整合

    引入jar包
    创建实体类封装Job信息
    创建实体类调用的具体方法
    创建测试方法初始化容器和开始执行
    创建配置文件applicationContext.xml

     <!--配置任务信息-->
        <bean id="scheduleJobEntity" class="com.yanqun.entity.ScheduleJob"  >
                <property name="jobId" value="j001"></property>
                <property name="jobName" value="任务1"></property>
                <property name="jobGroup" value="任务组1"></property>
                <property name="jobStatus" value="1"></property>
                <property name="cronExpression" value="5,10,30,50 * * * * ? *"></property>
                <property name="desc" value="描述..."></property>
        </bean>
        
    <!--配置job类信息-->
        <bean  id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" >
                <property name="jobClass" value="com.yanqun.job.PlanJob"></property>
                <property name="jobDataAsMap">
                        <map>
                            <entry key="scheduleJob">
                                <ref bean="scheduleJobEntity"></ref>
                            </entry>
                        </map>
                </property>
        </bean>
    
    <!-- cronTrigger触发器:定义时间规则
        <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    
                <property name="jobDetail" ref="jobDetail" >
                </property>
                <property name="cronExpression" value="#{scheduleJobEntity.cronExpression}">
                </property>
        </bean>-->
        
    <!--SimpleTrigger触发器-->
        <bean  id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"  >
                <property name="repeatInterval" value="2000"></property>
                <property name="repeatCount" value="10"></property>
                <property name="startDelay" value="3"></property>
                <property name="jobDetail" ref="jobDetail" ></property>
        </bean>
    <!--配置调度器-->
          <bean id="schedulerFactoryBean"  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
                <property name="triggers">
                    <list>
                            <ref bean="simpleTrigger" />
                    </list>
                </property>
          </bean>
    
    展开全文
  • 提取img src 属性 src="xx" | src='xx'   src=[\'\"]([^\"]+)[\'\"...]匹配引号或双引号,放入子模式1,中间是非\1的,不能用[^\1],后面是再次出现的\1     ...

    提取img  src 属性     src="xx"   |   src='xx'

     

    src=[\'\"]([^\"]+)[\'\"]

     

    alt=(['"])(?:(?!\1).)*?\1
    前边是['"]匹配单引号或双引号,放入子模式1,中间是非\1的,不能用[^\1],后面是再次出现的\1

     

     

    展开全文
  • 目录java14新特性instanceof模式匹配Switch表达式记录类型(Record Type)的引入文本块作为预览特性保留NullPointerException总结 java14新特性 在JDK14中新增了以下16个新特性: 305: instanceof的模式匹配 (预览....
  • 模式匹配 简单匹配 守卫 匹配类型 匹配集合 变量声明中的模式匹配 匹配样例类 - 常用 Option类型 - 重点掌握经常用 偏函数 - 理解 正则表达式 - 了解 模式匹配 scala中有一个非常强大的模式匹配机制,...
  • http://www.java3z.com/cwbwebhome/article/article8/Regex/Java.Regex.Tutorial.html 引言 记得几年前在做网页爬虫后的信息抽取时,针对网页源码中隐藏的要提取的信息,比如评论、用户信息等属性信息,直接利用...
  •   零个字符的串称为空串(null string),它的长度为零,可以直接用两双引号一表示,也可以用希腊Φ字母来表示。   所谓的序列,说明串的相邻字符之间具有前驱和后继的关系。下面是串的一些概念性东西:  ...
  • 正则表达式的模式匹配

    千次阅读 2019-01-08 22:11:45
    就像通过引号包裹字符的方式来定义字符串直接量一样,正则表达式直接量定义为包含在一对斜杠(/)之间的字符,例如: var pattern=/s$/; 运行这段代码创建一个新的RegExp对象,并将它赋值给变量pattern。这...
  • 串-定义和模式匹配算法

    千次阅读 2017-03-12 21:38:59
    一般记为s= "a1a2......an"(n>0),其中,s是串的名称,用双引号(有些书中也用单引号)括起来的字符序列是串的值,注意单双引号不属于串的内容。ai(1串中的字符数目n称为串的长度,定义中谈到"有限"是指长度n是一个...
  • scala 高级扩展scala 系列前言思维导图模式匹配简单模式匹配匹配类型守卫匹配样例类匹配集合变量声明正则匹配正则表达式匹配分割替换查找注解(Annotation) 前言 上一篇博客已经给大家介绍了 scala OOP, 掌握了...
  • 在Scala的模式匹配中,可以使用类型、通配符、序列、正则表达式,甚至可以深入获取对象的状态。这种对象状态的获取遵循一定的协议,也就是对象内部状态的可见性由该类型的实现来控制,这样我们就可以获取暴露的状态...
  • 1. 这本书对Python的知识点的描述很详细,而且排版看的很舒服. 2. 几个例题:假装自己从零开始学,将一些有代表性、有意思的例题抽取出来. 3. 还有自己对一部分课后复习题,全部课后上机实践题的解题思路
  • Java Pattern和Matcher字符匹配详解

    万次阅读 多人点赞 2017-09-02 21:40:33
    用于编译正则表达式后创建一个匹配模式。  指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可以与任意字符序列匹配
  • 此博文利用正则表达中的懒惰模式(非贪婪模式匹配文档中的对话(:“ ”),并用自定义计数器累计出一篇文章中有多少段对话,可用之判断一篇文章的类型。 二、正则表达 — 懒惰匹配 .*? 正则表达式语法繁多复杂,...
  • 1、三个引号:a regular(定期的、合格的、有规律的) expression 用处:字符串中含有特殊字符,java中需要转义符号,scala可以在三个引号中直接输特殊字符,不需要转义符 ...2、正则表达式模式匹配 sca...
  • MySQL 面试题

    万次阅读 多人点赞 2019-09-02 16:03:33
    8、列类型是字符串类型,查询时一定要给值加引号,否则索引失效。 9、 LIKE 查询, % 不能在前,因为无法使用索引。如果需要模糊匹配,可以使用全文索引。 关于这块,可以看看 《服务端指南 数据存储...
  • Scala的模式匹配机制

    千次阅读 2017-02-08 16:02:09
    Scala强大的模式匹配机制,可以应用在switch语句、类型检查以及“析构”等场合。样例类对模式匹配进行了优化。 更好的switch 12345678var sign = .....
  • Shell

    千次阅读 多人点赞 2019-08-16 22:01:18
    Shell 介绍 shell是一个用c语言编写的程序,他被称为用户使用linux的桥梁 shell即是一种命令语言,又是一种程序语言 ... shell编程和java,python等一样,只需要一个文本编辑器和解释工具即可 linux的...
  • 使用正则表达式regex匹配特殊字符(2种方法记忆): 方法1:首先加"\"匹配该特殊字符本身,然后在转义字符(即"\")前加"\" 方法2:在特殊字符前加"\\"(或者使用[]),特别的"\"需要使用"\\\\"来匹配 字符 说明 ...
  • 前端面试题

    万次阅读 多人点赞 2019-08-08 11:49:01
    前端面试题汇总 ... 你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么?...它和Standards模式有什么区别 21 div+css的布局较table布局有什么优点? 22 img的alt与title有何异同? strong与em的异同? 22 你能...
  • 你打算用Java 8一辈子都不打算升级到Java 14,真香

    万次阅读 多人点赞 2020-03-26 10:04:35
    模式匹配的 instanceof 在 Java 14 中是预览版的,默认是不启用的,所以这段代码会有一个奇怪的编译错误(Java 14 中不支持模式匹配的 instanceof)。 那怎么解决这个问题呢?需要在项目配置中手动设置一下语言的...
  • 测试开发笔记

    万次阅读 多人点赞 2019-11-14 17:11:58
    测试开发笔记 第一章 测试基础 7 什么是软件测试: 7 ★软件测试的目的、意义:(怎么做好软件测试) 7 3.软件生命周期: 7 第二章 测试过程 8 1.测试模型 8 H模型: 8 V模型 9 2.内部测试 10 ...
  • 正则表达式是一个描述字符模式的对象。JavaScript中的正则表达式使用RegExp对象表示,可以使用RegExp()构造函数来创建RegExp对象。 1. RegExp对象通过一种特殊的直接量语法来创建。就像通过引号包裹字符的...
  • 第十二章 Scala进阶——模式匹配

    千次阅读 2019-02-12 01:03:33
    前一章提到过,Scala的内建控制结构里有一个match表达式,用于模式匹配或偏函数。模式匹配是Scala中一个强大的高级功能,并且在Chisel中被用于硬件的参数化配置,可以快速地裁剪、配置不同规模的硬件电路。所以,...
  • 这篇文章主要介绍了 Java 利用MessageFormat实现短信模板的匹配,觉得挺不错的,现在分享给大家,也给大家做个参考。 其实没什么技术含量,因为老是想不起来,所以在此文做下记录。 通常我们的应用系统中都会有很多...
  • C#基础教程-c#实例教程,适合初学者

    万次阅读 多人点赞 2016-08-22 11:13:24
    C#语法和C++和JAVA语法非常相似,如果读者用过C++和JAVA,学习C#语言应是比较轻松的。 用C#语言编写的源程序,必须用C#语言编译器将C#源程序编译为中间语言(MicroSoft Intermediate Language,MSIL)代码,形成扩展名...
  • 这里我使用的是java.text包中MessageFormat.format方法,可以方便的匹配解析我们的模板消息。 MessageFormat方法的介绍 MessageFormat用来格式化一个消息,通常是一个字符串,比如: String str = "I'm not a ...
  • shell脚本

    千次阅读 多人点赞 2016-12-22 11:19:36
    都表示传递给函数或脚本的所有参数,不被双引号 (" ") 包含时,都以 "$1" "$2" … "$n" 的形式输出所有参数。 但是当它们被双引号 (" ") 包含时, "$*" 会将所有的参数作为一个整体,以 "$1 $2 … ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 26,086
精华内容 10,434
关键字:

java模式匹配引号

java 订阅