1、作用
删除指定长度的字符,并在指定的起点处插入另一组字符。
2、语法
STUFF ( character_expression , start , length ,character_expression )
3、示例
以下示例在第一个字符串 abcdef 中删除从第 2 个位置(字符 b)开始的三个字符,然后在删除的起始位置插入第二个字符串,从而创建并返回一个字符串SELECT STUFF('abcdef', 2, 3, 'ijklmn')
GO
下面是结果集
aijklmnef
4、参数
character_expression
一个字符数据表达式。character_expression 可以是常量、变量,也可以是字符列或二进制数据列。
start
一个整数值,指定删除和插入的开始位置。如果 start 或 length 为负,则返回空字符串。如果 start 比第一个 character_expression长,则返回空字符串。start 可以是 bigint 类型。
length
一个整数,指定要删除的字符数。如果 length 比第一个 character_expression长,则最多删除到最后一个 character_expression 中的最后一个字符。length 可以是 bigint 类型。
5、返回类型
如果 character_expression 是受支持的字符数据类型,则返回字符数据。如果 character_expression 是一个受支持的 binary 数据类型,则返回二进制数据。
6、备注
如果结果值大于返回类型支持的最大值,则产生错误。
(资料来源于网络)
spring bean 实例化的方式
1.默认情况下是调用bean对象的默认构造函数来示例话bean
2.调用工厂的静态方法来实例化bean
<bean id="bean实例name" class="工厂类" factory-method="工厂的静态方法"></bean>
3.调用工厂方法来实例化bean
<bean id="工厂实例name" class="工厂类" class="工厂类名">
<bean id="bean实例name" factory-name="工厂实例name",factory-method="工厂的非静态方法">
spring bean 的作用域 (可以使用scope="singleton/prototype/request/session/global session"来配置)
1.默认作用域(singleton)情况下:
bean的实例化是在容器实例化(被主动申请加载)时就实例化
将lazy-init="true" (延迟初始化) 不会再容器实例化实例化bean (不建议使用)
用init-method="methodName" 可以指定bean被实例化时调用的方法
用destory-method="methodName" 可以制定容器调用close方法后bean执行的方法
2.配置prototype(原型)作用域:
bean的实例化是在调用getBean方法时被实例化的
每次调用一个getBean方法都回返回一个新的对象
Spring Dependency Injection(Spring的依赖注入)
1.使用映射的方式注入
<bean id="personDao" class="接口实现类路径"></bean>
<bean id="persionService" class="接口实现的类路径">
<property name="personDao" ref="personDao"></property> <!--反射赋值-->
<property name="name" value="tom test!!!!!!!!"></property> <!--为基本类型赋值-->
<property name="name" value="100"></property> <!--为基本类型赋值-->
</bean>
2.使用内部bean 的方式注入
<bean id="persionService" class="实现的类路径">
<property name="persionDao">
<bean class="dao实现路径"/>
</property>
</bean>
3.集合类型的注入
<bean id="personService" class="实现类路径">
<property name="sets">
<set> <!--此处可以为list-->
<value>一个value</value>
<value>两个value</value>
</set>
<map>
<entry key="key-1" value="value-1"/>
<entry key="key-2" value="value-2"/>
<entry key="key-3" value="value-3"/>
</map>
</property>
</bean>
4.使用构造器参数注入(调用特定的构造函数)
如果PersonServiceBean中的有构造函数PersonServiceBean(PersonDao personDao,String name){}
<bean id="personDao11111111" class="类实现路径"><bean>
<bean id="personService" class="类实现路径">
<constructor-arg index="0" type="自定义type类的路径" ref="personDao111111">
<constructor-arg index="1" type="基本类型可以省去......" value="111111111">
</bean>
5.使用Field注入(用于注解的方式)
属性的值注入
@Resource private PersonDao personDao; /* 先找到 容器中的 bean的对应名称进行匹配,若无,找类型匹配 */
属性的set方法注入
@Resource
public void setXXX(Object object){}
Spring 自动扫描和管理(扫描的方式去自动管理组建)
引入类配置<context:component-scan base-package>
@Service @ Resposity
通过class 类名首字母小写 @Service("对象名")来获得,也可以 @scope("prototype") 来设置初始化类的属性
可以在方法名上面@PostConstruct 可以制定初始化方法
可以在方法名上面@PreDestory 可以在bean实例被摧毁之前执行的方法。
Spring和Struts2的整合
1.找到Struts2-Spring-plugin-.XX.jar包和Spring.jar包 加入到web项目的lib包下
2.配置WEB-INF/web.xml文件,加入与struts整合的监听器
<!--
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
-->
<!-- 若applicationContext.xml文件不在WEB-INF 下则需要将将路径放入上面参数中-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
3.在struts.xml文件中加入spring常量(structs中对象的创建叫给spring)
<constant name="struts.objectFactory" value="spring"/>
<action class="loginAction" name="loginAction_*" method="{1}">
<result name="success" type="redirect">index.jsp</result>
</action>
4.创建applicationContext.xml文件,文件可以放在web-inf目录下,这样可以不用在1中加入context的配置
<?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-2.5.xsd">
<bean id="loginAction" class="xxxxxxxxxxxxxxxxxxxxxxx" scope="prototype"/>
注意:(1)struts2中需要加入prototype(原型)的配置,这样才能满足struts2为每次请求创建一个对象的服务方式
(2)此处的id 名需要与3中的class同名
ReentrantReadWriteLock的特性
1.公平性和非公平性获取锁:
支持按照公平的原则获取锁,即读写线程按照最长等待时间分配锁
若构造为非公平性的,则按照先到先得的顺序,但是有读线程想获取锁时,该顺序被打破
2.重复获得锁:读线程可以重复的获取锁,尽管当前读线程占用
3.锁降级:
可以将write lock 的等级降为 read lock ,顺序是:先获得WriteLock再获得ReadLock,然后释放WriteLock,这时候线程将保持Readlock的持 有。
反过来ReadLock想要升级为WriteLock则不可能
4.中断锁的获取:读锁和写锁的获取期间都允许被中断
5.Condition 类的支持:该支持仅仅就写操作而言,若readLock(0.newCondition() 将会throws UnsupprotedoperationException
6.可监测性:这个类支持操作是否对锁的获取还是竞争,只是为检测系统状态,而不是为了同步而设计的。
显式锁(Lock)和隐式锁(Synchronized)的不同点,括号注明隐式锁与重复读写锁(ReentrantReadWriteLock)的区别
1.不能主动中断正在试图获得锁的线程 (显式写操作锁可以主动的挂起读操作锁,进行写操作)
2.试图获得锁时不能设置超时
3.在对象内部锁只有一个并且内部锁只有一个单一的条件,可能不够用(显示锁可以有多个,不断重复的对读写操作加锁)
对ReentrantReadWriteLock类测试
1.读/写操作的锁多线程测试 : 单独的读操作和写操作何以完成读或写的同步
2.读操作所和写操作锁多线程测试 : 能同步 (必需操作类中将 ReentrantReadWriteLock声明为static的成员变量)
3.读操作进程和写操作进程间测试:不支持进程间的同步