1 | <update id=“updateAuthor”> |
说明:flushCache=”true”为更新二级缓存,timeout=“20”超时连接
1 | <update |
1 | <update id=“updateAuthor”> |
说明:flushCache=”true”为更新二级缓存,timeout=“20”超时连接
1 | <update |
这里只是给出xml配置文件,测试文件就不写了。下面说的是配置文件都是数据库和实体类一样的情况,如果主键自增不一样,参考情况2.
情况1:
1 | <insert id=“insertAuthor”> |
情况2:
插入有主键id的情况:
1 | <insert id=“insertAuthor” useGeneratedKeys=”true” |
1 | public class MybatisUtils{ |
在传统的配置下,我们一般使用xml配置来完成bean的注入,例如
1 | <bean id=”beanService” class=”com.bean.service.beanServiceImpl”/> |
现在利用@javaConfig就能完成整个配置。下面是一个例子。
例子一:
1.Helloeorld类
1 | public interface Helloeorld { |
2.HelloworldImpl类
1 | public class HelloworldImpl implements Helloeorld{ |
1 | @Configuration |
4.测试类
1 | ApplicationContext context = new AnnotationConfigApplicationContext(TestConfig.class); |
例子2:
@Import
在我们运用传统xml方式进行配置Spring时,可以通过如下方式加载多个配置文件:
1、CustomerBo类
1 | public class CustomerBo { |
2.CustomerConfig类
1 | @Configuration |
3.AppConfig类
1 | @Configuration |
1.拼装成一个对象
1 | var json2={}; |
2.拼接成一个list
1 | var json4=[]; |
3.转化成字符串给后台
1 | var serdate=JSON.stringify(json4); |
4.后台处理后返回的
1 | var cargodata_in = eval(‘(‘ + result + ‘)’); |
environments主要是用于配置多个数据源,可以是mysql,也可以是oracle,还可以是plsql.
下面的就是增对下面的一个模板,可以配置不同的数据库
配置mybaits.xml
1 | <?xml version=“1.0” encoding=“UTF-8” ?><!DOCTYPE configuration |
@Service服务层组件,用于标注业务层组件,表示定义一个bean,自动根据bean的类名实例化一个首写字母为小写的bean,例如Chinese实例化为chinese,如果需要自己改名字则:@Service(“你自己改的bean名”)。
@Controller用于标注控制层组件(如struts中的action)
@Repository持久层组件,用于标注数据访问组件,即DAO组件
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
可以使用以下方式指定初始化方法和销毁方法(方法名任意):
1 | @PostConstruct |
注明:spring结合springmvc完成以上的建立
1.安装maven
1 | <dependency> |
注意:加一个logger 这个参考官方文档
2.创建一个实体类,和dao层
1 | class类 student |
配置mybaits.xml
1 | <?xml version=“1.0” encoding=“UTF-8” ?><!DOCTYPE configuration |
测试类
1 | @test |
1.在jar加入sring-aop.jar加入进来,
2.在xml配置
1 | xmlns:aop=”http://www.springframework.org/schema/aop”; |
3.建立一个model层,如下图,其中testService4是测试类。
4.student类说明
1 | @Component |
5.在xml配置
1 | <context:component-scan base-package=“com.bean.service4”/> |
控制反转主要是由代码控制的对象将调用权转给容器,通过容器来实现对象的装配和管理。控制反转重要的是对象控制权的反转,从程序代码本身反转到了外部容器。
spring的ioc主要是依赖注入和依赖查找。依赖注入是最优秀的解耦方式。
依赖注入的三种方式:
1.构造器注入
1 | <bean id=“school1” class=“com.bean.service3.School”> |
2.set值注入
1 | <bean id=“school1” class=“com.bean.service3.School”> |
3.接口注入
方法注入 init-method=”dopost”,类似这样的
匿名bean列子:
1 | <bean class=“com.bean.service3.School” autowire=“byName”> |
内部匿名例子:
1 | public class Some { |
同类抽象:
由上面的例子可知重复代码过多,要求封装:
1 | <bean class=“com.bean.service3.student” > |
改为:
1 | <bean id=”ss” class=“com.bean.service3.student” abstract=“true”> |
异类抽象:
1 | <bean id=”ss” abstract=“true”> |
js获取URL中的一些参数的意思
location对象 含有当前URL的信息. 属性 href 整个URL字符串.
protocol 含有URL第一部分的字符串,如http:
host 包含有URL中主机名:端口号部分的字符串.如//www.cenpok.net/server/
hostname 包含URL中主机名的字符串.如http://www.cenpok.net ;
port 包含URL中可能存在的端口号字符串.
pathname URL中”/”以后的部分.如~list/index.htm
hash “#”号(CGI参数)之后的字符串.
search “?”号(CGI参数)之后的字符串.
第一种:只适用于/User/vip_card_manager?useless=219
1 | function UrlSearch() { |
第二种:
适应以下两种模式,来获取url参数值:
/User/vip_card_manager/useless/219/id/18
/User/vip_card_manager?useless=219&id=18
1 | console.log(getQueryString(“useless”)); |
第三种:自己没有用过,是同事给的
1 | /** |
1.数据有对象,有list
数据1:
1 | var xml_data = [{ |
数据2:
1 | var json={ "addr_num":"runoob", "user_guid":10000}; |
2.ajax调用
1 | $.ajax({ |
3.后台采用的是spring mvc来接收的,后台接收的方式也分为了两种,一种是用@RequestBody来处理的,一种是用common io的工具类IOUtils来读取二进制流将其解析成一个字符串,之后再用fastjson来将一个Json字符串转成java对象
1 | @Controller |
1.byName就是通过Bean的id或者name,byType就是按Bean的Class的类型。
下面的例子就是一个时候才可以用
1 | <bean id=“school1” class=“com.bean.service3.School” autowire=“byName”> |
2.如果是两个,可能会出现以下情况
1 | <bean id=“school1” class=“com.bean.service3.School” autowire=“byType“> |
结果:报错。因为他们的class是一样的。
说明:byType不仅仅是以上的关系,还有is-a都不行。因为is-a是继承关系。
1 | public class Some { |
xml配置
1 | <bean id=“school1” class=“com.bean.service3.School”> |
测试方法如下:
1 | @Test |
1.调用无参的构造器,创建实例对象。
1 | public class beanServiceImpl implements beanService{ |
2.调用参数的setter,为属性注入值。
1 | <bean id=“beanService” class=“com.bean.service2.beanServiceImpl”> |
1 | private String dao; |
3.若bean实现了beanNameAware接口,则会执行接口方法setBeanName(String beanId),使bean类可以获取其在容器中的id名称。
1 | public class beanServiceImpl implements beanService,BeanNameAware |
继承了BeanNameAware的默认方法
1 | public void setBeanName(String name) { |
4.若bean实现了beanFactoryAware接口,则会执行接口方法setBeanFactory(BeanFactrory factory),使bean类可以获取到beanFactory对象。
1 | public class beanServiceImpl implements beanService,BeanNameAware,BeanFactoryAware |
继承了BeanFactoryAware的默认方法
1 | public void setBeanFactory(BeanFactory beanFactory) throws BeansException { |
5.若定义并注册了bean后处理器beanpostProcessor,则执行接口方法postProcessBeforeInitialization();
创建beanpostprocessor实现BeanPostProcessor
1 | public class beanpostprocessor implements BeanPostProcessor{ |
6.若bean实现initializingBean接口,则执行接口方法afterPropertiesSet().该方法在bean的所有属性的set方法执行完毕后执行,是bean初始化的标志,实例化结束。
1 | public void afterPropertiesSet() throws Exception { |
7.若设置了init-method方法,则执行。
1 | <bean id=“beanService2” class=“com.bean.service2.beanServiceImpl” init-method=“doAfter”> |
8若定义并注册了bean后处理器beanpostProcessor,则执行接口方法postProcessAfterInitialization();
1 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { |
9.执行业务方法。
1 | public void dotest(); |
10.若bean实现了DisposableBean接口,则执行接口方法destroy().
1 | public void destroy() throws Exception { |
11.若设置了destrory-method方法,则执行。
1 | <bean id=“beanService2” class=“com.bean.service2.beanServiceImpl” init-method=“doAfter” destroy-method=“doDestroy”> |
GSON是谷歌提供的开源库,用来解析Json格式的数据,非常好用。如果要使用GSON的话,则要先下载gson-2.2.4.jar这个文件,如果是在Android项目中使用,则在Android项目的libs目录下添加这个文件即可;如果是在Java项目中,则把gson-2.2.4.jar先添加到当前项目的任意一个包中,然后右键点击这个jar包 -> 构建路径 -> 添加至构建路径。这样准备工作就做好了。
比如有如下Json数据:
1 | {“name”:”John”, “age”:20} //也可以用单引号,写成:{‘name’:’John’, ‘age’:20} |
解析该数据步骤如下:
1、定义Person类:
1 | public class Person{ |
2、创建GSON对象并解析:
1 | String jsonData = “{\”name\”:\”John\”, \”age\”:20}”; //注:这里也可以不使用转义字符,而用单引号:String jsonData = “{‘name’:’John’, ‘age’:20}”; |
3、然后使用Person对象的getter方法就可以获取到数据了。
4、扩展:考虑到Json数据的不同,那么解析Json的时候所用的类也可能不同,比如这里用的是Person,如果解析其他数据可能用的又是Dog、Cat…所以考虑将用GSON解析的步骤封装,并提供泛型参数,示例程序如下:
1 | import com.google.gson.Gson; |
输出结果:
John,20
比如有如下Json数据:
1 | {“name”:”John”, “age”:20,”grade”:{“course”:”English”,”score”:100,”level”:”A”}} |
对这样的数据就要用内部类的来解决了。解析步骤如下:
1、定义Student类:
1 | class Student { |
2、使用(一)中封装的GsonUtil工具类进行解析:
1 | public class GsonTest1 { |
比如有如下Json数据:
1 | [{‘name’:’John’, ‘grade’:[{‘course’:’English’,’score’:100},{‘course’:’Math’,’score’:78}]}, {‘name’:’Tom’, ‘grade’:[{‘course’:’English’,’score’:86},{‘course’:’Math’,’score’:90}]}] //注:Json数组最外层一定要加”[]” |
如何处理这样的数据呢?就要用到List。步骤如下:
示例程序如下:
1 | import java.lang.reflect.Type; |
1.创建订单表
2.创建订单详情表
3,在创建订单表时,创建订单表的一样的订单状态
4.在更新订单表时,更新订单表的一样的订单状态
5.在删除订单表时,删除订单表的一样的订单状态
代码如下:
1.创建订单:
1 | delimiter $$ |
2.更新订单
1 | drop trigger if exists up_order_satus; |
3.删除订单
1 | drop trigger if exists del_order_satus; |
handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型)
A、处理requet uri 部分(这里指uri template中variable,不含queryString部分)的注解: @PathVariable;
B、处理request header部分的注解: @RequestHeader, @CookieValue;
C、处理request body部分的注解:@RequestParam, @RequestBody;
D、处理attribute类型是注解: @SessionAttributes, @ModelAttribute;
当使用@RequestMapping URI template 样式映射时, 即 someUrl/{paramId}, 这时的paramId可通过 @Pathvariable注解绑定它传过来的值到方法的参数上。
示例代码:
1 | @Controller |
上面代码把URI template 中变量 ownerId的值和petId的值,绑定到方法的参数上。若方法参数名称和需要绑定的uri template中变量名称不一致,需要在@PathVariable(“name”)指定uri template中的名称。
@RequestHeader 注解,可以把Request请求header部分的值绑定到方法的参数上。
示例代码:
这是一个Request 的header部分:
1 | Host localhost:8080 |
1 | @RequestMapping(“/displayHeaderInfo.do”) |
上面的代码,把request header部分的 Accept-Encoding的值,绑定到参数encoding上了, Keep-Alive header的值绑定到参数keepAlive上。
@CookieValue 可以把Request header中关于cookie的值绑定到方法的参数上。
例如有如下Cookie值:
1 | JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84 |
参数绑定的代码:
1 | @RequestMapping(“/displayHeaderInfo.do”) |
@RequestParam
示例代码:
1 | @Controller |
@RequestBody
该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;
它是通过使用HandlerAdapter 配置的HttpMessageConverters来解析post data body,然后绑定到相应的bean上的。
因为配置有FormHttpMessageConverter,所以也可以用来处理 application/x-www-form-urlencoded的内容,处理完的结果放在一个MultiValueMap<String, String>里,这种情况在某些特殊需求下使用,详情查看FormHttpMessageConverter api;
示例代码:
1 | @RequestMapping(value = “/something”, method = RequestMethod.PUT) |
@SessionAttributes:
该注解用来绑定HttpSession中的attribute对象的值,便于在方法中的参数里使用。
该注解有value、types两个属性,可以通过名字和类型指定要使用的attribute 对象;
示例代码:
1 | @Controller |
@ModelAttribute
该注解有两个用法,一个是用于方法上,一个是用于参数上;
用于方法上时: 通常用来在处理@RequestMapping之前,为请求绑定需要从后台查询的model;
用于参数上时: 用来通过名称对应,把相应名称的值绑定到注解的参数bean上;要绑定的值来源于:
用到方法上@ModelAttribute的示例代码:
1 | // Add one attribute |
这种方式实际的效果就是在调用@RequestMapping的方法之前,为request对象的model里put(“account”, Account);
用在参数上的@ModelAttribute示例代码:
1 | @RequestMapping(value=“/owners/{ownerId}/pets/{petId}/edit”, method = RequestMethod.POST) |
首先查询 @SessionAttributes有无绑定的Pet对象,若没有则查询@ModelAttribute方法层面上是否绑定了Pet对象,若没有则将URI template中的值按对应的名称绑定到Pet对象的各属性上。
@RequestBody
作用:
使用时机:
GET、POST方式提时, 根据request header Content-Type的值来判断:
PUT方式提交时, 根据request header Content-Type的值来判断:
说明:request的body部分的数据编码格式由header部分的Content-Type指定;
@ResponseBody
作用:
该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
使用时机:
返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;
org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter 实现远程服务调用
服务端 必须要实现 bean实体类 service接口类 serviceImpl服务实现类
客户端只需拷贝 bean 实体类 service接口类(注意 ,客户端 bean,service类要和服务端bean,service类包路径相同,比如都是
com.hlzt.csm.model.DataPlatFormCountBean,不然会报找不到类,而且 bean要序列化 public class DataPlatFormCount implements Serializable;
如果服务端有 序列化的private static final long serialVersionUID = 1L号,客户端也必须有,如果服务端没有此id,客户端也不要有此id,不然会出错。service类的包路径也要相同,最好服务端写好后直接把实体类和service服务接口类打包,拷贝到客户端,以免造成两端不同。
)
服务器端要在spring-mvc配置文件 spring-mvc-servlet.xml中加入以下(注意是在spring-mvc的配置文件中,不是spring的配置文件)
1 | <beans xmlns=“http://www.springframework.org/schema/beans” |
1 | <!– 启用spring mvc 注解 –> |
服务端 web.xml的配置
客户端配置
客户端 spring的xml文件配置
1 | <?xml version=“1.0” encoding=“UTF-8”?> |
注意的是 id=”csmDataCountSer” 本人测试结果是 此实例不能在java中通过 rource 或Autowired自动注入,而要通过手工载入方式获得
ApplicationContext context =new ClassPathXmlApplicationContext(“/spring/spring-remote.xml”);
CsmDataCountSer csmDataCountSer=(CsmDataCountSer)context.getBean(“csmDataCountSer”);
首先看下实例程序目录结构:
Spring中发布RMI服务(ZLv_RMIServerWithSpring):
(1) 定义接口MessageProvider及接口中供调用的方法(MessageProvider.java):
1 | package org.thera.rmi.service; |
(2) 实现MessageProvider接口(MessageProviderImpl.java):
1 | package org.thera.rmi.service; |
做好了上述准备,下面我们就可以通过Spring中集成RMI,方便的发布RMI服务端
(3) Spring配置文件作如下配置(context.xml):
1 | <?xml version="1.0" encoding="UTF-8"?> |
(4) 加载Spring容器,发布RMI服务(Main.java):
1 | package org.thera.rmi.service.main; |
到这里,RMI的服务端已经发布成功,运行结果如下截图:
Spring中客户端调用RMI服务(ZLv_RMIClientWithSpring):
(1) 移植服务端服务接口文件MessageProvider.java;
(2) Spring配置文件做如下配置:
1 | <?xml version="1.0" encoding="UTF-8"?> |
(3) 加载Spring容器,调用RMI服务端(Main.java):
1 | package org.thera.rmi.service.main; |
运行Main.java,结果如下图:
RPC调用类似于调用本地对象的方法,都是同步的操作,调用代码将被阻塞,直到被调用过程完成为止。
本地调用就是execute process在同一个应用的两个代码块中交换。RPC就是execute process从一个应用通过网络传递给另外一个应用。
Spring RemoteService支持这几种模式:RMI, Hessian, Burlap, HTTP invoker和JAX-RPC。
在Server端,Spring可以通过相应的RemoteExporter将一个Bean的发布成一个remote service。
RMI缺点:RMI在有防火墙的环境下运行会有困难,而且RMI要求客户端和服务器端都必须用Java编写。
Hession和Burlap都是Caucho Technology的框架,基于HTTP的轻量级remote service。
Hessian使用binary消息来建立客户端和服务器端之间的交流,因为基于binary所以对通迅带宽的占用小。所以不依赖于语言可以被Java之外的语言所用。
Burlap是基于XML的技术,消息可读性比较好,而且Burlap相比其他基于XML的技术比如SOAP来说,Burlap的消息结构比较简单,不需要WSDL之类的东西额外定义。
使用Hessian(客户端代码)
和RMI类似,Spring使用HessianProxyFactoryBean来创建一个指向Hessian服务的proxy。
由此可见,当使用Spring时,可以很简单的在各种Spring所支持的remote技术之间切换,而仅仅需要更改很少的配置。
输出Hessian服务
使用HessianServiceExporter
将POJO的public方法公开成Hessian服务。HessianServiceExporter是一个Spring MVC controller,接收Hessian的请求然后翻译成对POJO的方法调用。
输出Burlap服务
Burlap服务的输出几乎和Hessian是一样的,不同的地方就是使用org.springframework.remoting.caucho.BurlapServiceExporter。也需要为它配置URL handler和DispatcherServlet。
RMI使用Java标准的序列化机制,但是很难穿过防火墙;Hessian/Burlap能穿越防火墙但是使用自己私有的一套系列化机制。
因此HTTP invoker应运而生,使用HTTP协议能通过防火墙,并且使用Java序列化机制。
使用HTTP invoker
和RMI,Hessian等相同,HTTP invoker也是通过HttpInvokerProxyFactoryBean。
输出HTTP invoker服务
和Hessian相同,不同的地方就是使用org.springframework.remoting.httpinvoder.HttpInvokerServiceExporter。也需要为它配置URL handler和DispatcherServlet。
HTTP invoder的限制就是客户端和服务器端必须使用Spring