1 背景概述
相信很多了解数通畅联软件的人对AEAI DP应用开发平台并不陌生,笔者在入职第一天就开始接触AEAI DP,使用AEAI DP开发过AEAI WM、AEAI CRM以及中国XXXX管理系统项目,在此过程中对AEAI DP有了较为深入了解,工作之余尝试对AEAI DP的工作原理、实际开发工作涉及的技术点进行梳理,希望能够对其他AEAI DP初学者和使用人员有所帮助。
本文相关说明涵盖AEAI DP的远程热部署新特性,AEAI DP V3.5以后版本支持按工程、模块、资源不同粒度实现代码远程增量部署,类似AEAI ESB中的按流程、服务、工程远程热部署模式。
2 预期读者
3 技能要求
了解Java Web开发过程,熟悉相关知识点
对AEAI DP技术手册所涉及的内容熟练掌握
4 架构及原理
4.1 DP产品架构解读
AEAI DP开发平台包括三部分,第一部分是一站式的Java Web框架,在数通畅联软件家族中命名为Hotweb,第二部分基于Eclipse插件的扩展开发设计器,在数通畅联软件家族中命名为Miscdp Studio,第三部分是用于开发调试的服务器HotServer。基于Miscdp Studio可以开发普通Java Web应用、集成Java Web应用,还可以为BPM流程平台开发业务表单及流程相关功能。
Hotweb是一站式的MVCFramework,对前端页面交互及控制层做了统一封装,各类功能模型的交互方式封装在父类中。每个页面提供一个Handler处理Java类和展现JSP页面,一个功能可能涉及多个页面,复用一套业务逻辑处理Service和通用的数据存取持久工具类DAOHelper,在Service层调用通用数据存取类DAOHelper。数据持久层基于IBatis封装,Service层基于Spring来做事务控制和服务配置。
4.2 Howeb交互机制
DispatchServlet:前端请求分发,配置于web.xml
Handler:具体请求动作处理及控制,调用Service,返回ViewRender
Service:后台业务处理,包括接口及实现,Spring配置,通过DaoHelper调用SQLMap
SQLMap:负责数据持久化处理(CRUD)
ViewRender:前端展现渲染方式定义,实例化PageBean,放置于request的attributes中
PageBean:承载前端展现的属性、方法
JSP:具体页面代码,使用PageBean来获取handler中设置相关数据。
典型请求页面交互过程模式如下:
Servlet根据HandlerId实例化Handler、根据actionType反射调用对应的处理方法,方法名跟actionType一致
在对应方法中,调用Spring配置的Service来存/取数据库
如果是ajaxRender直接response返回页面,异步加载或者做相关处理
如果是dispatchRender,一般是转向其他的handler来进行处理
如果是LocalRender,直接调用prepareDisplay来做处理
4.3 典型目录层次结构
如上图:module该目录是放置各模块的代码,每个模块有各自的Handler、Service、SQLMap以及配置文件,这种文件结构模式能够支持AEAI DP实现按模块来部署。
common包里放置的是公共类,controller包里方式放置的框架级handler,cxmodule里面方式的公共service接口和实现类。
4.4 核心配置文件说明
通过AEAI DP平台开发生成相关的配置,下面对核心配置文件进行说明:
4.4.1 web.xml配置
在web.xml中包含filter的定义以及实现
Servlet的定义以及实现
以及Listener
4.4.2 Handler配置
1. HandlerIndex.xml:定义了HandlerId所属的模块,通过Id对应的模块查找对应模块下的映射关系
2. HandlerModule.xml与HandlerContext.xml中均映射关系指向对应的Handler以及JSP。其中HandlerModule.xml中定义的是不同模块下的映射关系而HandlerContext.xml中是公共访问的如主页、左侧功能列表的显示等。
4.4.3 Service 配置
1. ServiceContext.xml中典型配置属性:如数据库、appConfig等;
2. ServiceIndex.xml:通过seviceId所对应的模块去对应模块下的ServiceModule.xml配置文件中查找对应的ServiceImpl以及SqlMap等信息
3. ServiceModule.xml将对应功能模块下的Service层Controller层,用到的java类封装成bean,并通过property指定对应的SqlMap。
4. ServiceContext.xml中,配置了公共调用的Service的实现、配置数据库连接、以及事务控制机制。
4.4.4 DB 相关配置
1. hotweb.properties:配置了数据库的连接信息,如用户名、密码等。
2. SqlMapModule.xml与SqlMapConfig.xml:是sqlmap的索引文件
3. sqlmap:在对应的xml中定义SQl进行数据库操作,sqlMap文件的namespace默认是由表名来生成,在ServcieContext.xml(ServiceModule.xml)中指向业务处理ServiceImpl中
5 开发与部署
5.1 工具设置
5.2 开发步骤
AEAI DP开发平台基于数据库驱动开发,推崇适度需求调研、数据库设计先行、原型驱动的敏捷开发模式。整体过程如下:
1. 通过工程向导创建可运行调试的工程框架,默认预置系统管理功能
2. 设计器向导选择对应的功能模型,来创建功能实例
3. 功能实例配置信息首先通过数据表或SQL来默认生成
4. 在设计器进行特定调整(如:查询条件、显示字段、表单元素、校验控制等)
5. 由代码生成器,生成相关的代码及配置
6. 直接部署运行,查看效果,根据实际需要调整设置,重复4—6步
7. 根据实际需要扩展功能代码、调试。
注意:一旦扩展了代码,就不能再次代码生成,那样会覆盖扩展的代码。
5.2.1 开发约束说明
所有的表都需要创建UUID逻辑主键(36位)
所有编码类数据在编码管理模块中统一维护
如果列表SQL有参数需要解析,必须有“where 1=1”
建议开发采用SVN或者CVS进行版本管理
如果选择上载资源,则资源关联表,只能三个字段,除了逻辑主键,另外两个字段必须为“BIZ_ID”、“RES_ID”,字段类型都为char(36),建议主键命名为“REF_ID”
6.2.2 跨模块调用说明
在AEAI DP中各个功能模块是彼此隔离的,这里就可能存在跨模块调用问题:
跨模块调用handler
不需要做特殊处理,仍然index?SomeHandlerID方式调用跨模块的handler。
跨模块调用service
把对应的接口提升到cxmodule包里,可以采用代码重构的方式,选中对应接口类,然后ctrl+shift+v。
跨模块调用sqlmap
把sqlmap索引配置迁移公共索引配置(即SqlMapModule.xml中对应配置迁移至SqlMapConfig.xml),模块中的sqlmap文件也对应迁移公共sqlmap目录。
5.2.3 常用Java类清单
类别
常用类
功能说明
编码定义及界面元素
FormSelectFactory
基于编码定义的表单下拉框Select工厂类
FormSelect
表单下拉框Select泛化模型
RadioGroup
RadioButton模型,一般基于FormSelect转换生成
CheckBoxGroup
CheckBox模型,一般基于FormSelect转换生成
树构建器及模型
TreeBuilder
树形模型构建类
TreeModel
树形泛化模型,可以生成前端的多选、单选框
权限相关
Profile
身份权限概要模型,在Handler中可以直接获取
User
用户模型,可以通过Profile来获取
Role
角色模型,可以通过User来获取
Group
分组模型,可以通过User来获取
Resource
资源模型,可以通过User来获取
数据库存取相关
DaoHelper
数据访问对象工具类,封装ibatis的相关操作
DBHelper
数据操作工具类,基于Spring的数据源配置
KeyGenerator
主键生成类,一般情况下是UUID格式
工具类相关
DateUtil
日期处理工具类
StringUtil
字符串处理工具类
FileUtil
文件处理工具类
IOUtil
输入输出流工具类
5.3 部署方式
双击项目名弹出如下界面,可以修改服务器的地址并修改对应的用户名,连接对应的服务器后部署应用即可。
注意:服务器用户名、密码在Hotserver中有对应的配置,如下图:
在Miscdp Studio对工程中任意目录、文件都可以右键,在右键菜单底部点击“Miscdp资源部署”,如下图:
弹出部署设置窗口,AEAI DP支持三种粒度部署模式:模块、资源、应用。应用就是整个工程,模块指的module目录下的各个package,除了module下的文件,其他都属于资源。可以支持多个模块或者多个资源一起部署,而且内置的部署机制会自动识别,是否要重新加载模块或者重启应用。
5.3.1 按资源部署
在除模块下部署jsp,xml,js,java文件等为资源部署。当部署的内容包含源码时,会默认重启应用
部署的内容不包含源码时默认不会重启应用,且支持同时部署多个资源文件。
5.3.2 按应用部署
在项目名下右键资源部署为部署应用且默认重启应用。
5.3.3 按模块部署
在模块下选择xml、java文件等右键部署资源均为模块部署,默认会重新加载这个模块
注意:在模块的jsp文件夹下右键资源部署(弹出界面如上图)也为模块部署,默认会重新加载部署的模块。但是如果选择是模块jsp文件夹下的jsp文件,则为部署资源,且不用重启应用(jsp是自动编译)。
5.3.4 部署后目录
正常情况下Web应用的所有的classes都在WEB-INF/classes目录下,但基于AEAI DP开发的Web应用部署后有一个特殊目录modules,所有模块里的classes以及对应的配置文件都放置在这个目录里,如下图。
5.4 调试配置
远程调试是复杂业务逻辑的错误定位过程中常用手法,通过调试也可以使程序员对代码脉络更清楚,是程序员必备的技能。AEAI DP 基于Eclipse内置远程机制进行代码调试,具体参见《AEAI DP开发平台技术手册》中的调试配置部分内容。
6 知识点汇总
6.1 分层解读
6.1.1 控制层
对应的Handler如下图:
1. prepareDisplay方法
在handler中默认执行prepareDisplay方法
mergeParam(param)方法中通过handlerId的对比确定需要append的param的信息
storeParam方法在页面间跳转时候,将param存到一个session中,跟mergetParam联合使用保证在页面间切换时候,列表页面的查询条件不丢失。
setAttributes(param)方法中做遍历将param中的值进行set将数据放入到页面中
返回new LocalRenderer(getPage()),在LocalRenderer中的executeRender方法中创建PageBean,所有handler中的属性信息都传入至PageBean中,通过request.setAttribute(PAGE_BEAN_KEY,pageBean)方法将handler信息放入页面所以在JSP中可以通过pageBean中封装的getHandlerURL()获得handlerURL。
2. processPageAttributes方法
processPageAttributes方法用于回调处理扩展属性(下拉框处理、默认值处理)
3. initParameters方法
initParameters方法中可以设置查询条件的默认值
4. getService方法
在getService方法中返回到对应的调用的Service
5. 扩展方法机制说明
方法名与actionType隐藏域变量一致,建议采用@PageActionanotation方式,如果不添加@PageAction,则方法名为do+”actionType”+Action
6.1.2 显示层
顾名思义显示层就是用于前台显示的jsp页面如下图:
1. Page指令
通过Page指令的contentType将页面编码定义为UTF-8
pageEncoding是jsp文件本身的编码
contentType的charset是指服务器发送给客户端时的内容编码
2. Jsp动作
通过jsp在头部useBean在页面引用的javaBean(即pageBean),其中class属性指定类的实例并将其绑定到名由id属性定义的变量上,scope为request,如下:
相关jsp内置方法如下:
jsp:include:在页面被请求的时候引入一个文件。
jsp:useBean:寻找或者实例化一个JavaBean。
jsp:setProperty:设置JavaBean的属性。
jsp:getProperty:输出某个JavaBean的属性。
jsp:forward:把请求转到一个新的页面。
jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记
3. Jsp表单
一般情况下页面均会包含一个表id为form1,且内部有一个隐藏域actionType在表单提交时需要赋值。
一般情况下明细表单除了actionType以外还会包含一个operaType隐藏域,用来区分当前操作的状态是insert还是 update。
在form表单中action动作指令通过pageBean.getHandlerURL()获得handler指定跳转的路径,method="post"提交方式为post
4. 资源文件
在Jsp页面中引入通用的资源文件:
<%@include file="/jsp/inc/resource.inc.jsp"%>在该页面中包括常用的javascript及css
在script中定义页面处理的JS,也可以直接引用封装与于Util.js中常见的页面校验(非空、长度等)、请求方法(doDelete、doSubmit)等
util.js中封装了常用js方法如:
function doDelete(itemValue)
function doQuery(params)
function doRequest(actionType,params)
function doSubmit(reqOptions)
function postRequest(form,params)(ajax处理)
function sendRequest(targetUrl,params) (ajax处理)
style.css为最常用css,其中定义form、table、tr、td样式以及按钮的图标样式等
6.1.3 服务层
后台业务逻辑生成接口与实现类如下图:
后台业务逻辑都生成接口与实现类,都在ServiceContext.xml(ServiceModule.xml)中配置。在实现类中定义对数据库的操作
1. 继承关系说明
每个功能模型都有自己的父类和接口,继承关系如下图所示:
2. processDataType
根据数据表的元数据来转换处理表单传过来的数据,可以扩展设置类型转换器,类型转换器扩展设置在ServiceContext.xml或者ServiceModule.xml中配置,BaseService中对应代码如下:
protected void processDataType(DataParam dataParam,String tableName){
Table table = getTableMetaData(tableName);
List dateColumns = table.getDateTypeColumns();
int count = dateColumns.size();
for (int i=0;i < count;i++){
Column column = dateColumns.get(i);
String columnName = column.getName();
Object paramValue = dataParam.getObject(columnName);
if (paramValue != null && paramValue instanceof String){
if (!String.valueOf(paramValue).trim().equals("") && !String.valueOf(paramValue).trim().equals("null")){
Date dateValue = DateUtil.getDateTime((String)paramValue);
dataParam.put(columnName,dateValue);
}else{
dataParam.remove(columnName);
}
}
}
if (!this.fieldConvertMap.isEmpty()){
Iterator keys = this.fieldConvertMap.keySet().iterator();
while (keys.hasNext()){
String key = keys.next();
Column column = table.getColumn(key);
if (column != null){
DataParamConvert convert = this.fieldConvertMap.get(key);
Object value = dataParam.get(key);
Object convertValue = convert.convert(value, column);
dataParam.put(key,convertValue);
}
}
}
}
3. processPrimaryKeys
处理主键默认生成机制,AEAI DP中默认是使用uuid来作为主键的,其实框架层面还支持自增字段主键机制。
protectedvoid processPrimaryKeys(DataParam param){
KeyGenerator keyGenerator = new KeyGenerator();
if (Constants.PKType.INCREASE.equals(pkGenPolicy)){
param.put(primaryKey,keyGenerator.getMaxId(tableName, primaryKey,getDataSource()));
}
elseif(Constants.PKType.CHARGEN.equals(pkGenPolicy)){
String genPk = keyGenerator.genKey();
param.put(primaryKey,genPk);
}
}
6.2 重点技术
6.2.1 常用方法
1. 在PageBean中封装了常见的页面中获取值的方法,如下:
public String inputDate(String key)
public String inputTime(String key)
public String inputValue(int i,String key)
public String selectValue(int i,String key,String formSelectKey)
public RadioGroup selectRadio(String elementName)
public String selectedValue(String elementName)
public String selectedText(String elementName)
public String disabled(boolean expression)
public String readonly(String expression)
2. 根据需要返回不同的ViewRender,一般情况下为:AjaxRender、DispatchRender、RedirectRenderer、LocalRender
1) AjaxRender:直接response返回值页面,异步加载或者做相关处理
2) DispatchRender:一般是转向其他Handler来进行处理,页面跳转传递request和response可以支持跳转到第三方按Backspace可以返回
3) RedirectRenderer:也是转向其他Handler但不能传递request和response
4) LocalRender:显示 JSP页面
3. DateUtil类中预置许多关于日期处理的方法,例如:日期的格式化,日期的计算,获得当月、当年的第一天等等。
4. 主键生成
调用KeyGenerator.instance().genKey()来自动生成主键ID
5. 加密解密
通过CryptionUtil中的加密解密方法进行加密解密
加密方法encryption("root", "12345678");其中root为需要加密的明文、”12345678”为加密的KEY。
解密方法decryption(secretData, secretKey);
6. 在User类中预置了许多关于User的跟角色、群组关联属性等
7. Dataparam转换
DataRow调用row.toDataParam();
List调用ListUtil.toParamList(records,srcKeys, replaceKeys)
8. StringUtil字符串辅助类
agileai_common的jar包中内置了很多辅助类,如StringUtil,DataUtil,ListUtil、DBUtil等。
9. ListUtil类转换方法
预置许多List转换方法如listToMap()、toXML()、toDataSet()、toParamList()
10. PopupBox.js中封装基于div+iframe的弹出框
Js中使用PopupBox方法时需要将对应的var写在方法的外面,每次调用使用的都是同一个弹出框,写在方法内部时每次调用方法都会新生成一个弹出框。
11. 内置Ajax处理方式
functionpostRequest(form,params)
functionsendRequest(targetUrl,params)
第一种是post方式,第二种是get方式。
6.2.2 授权配置
1. 功能授权
系统预置功能可以设置功能目录、功能节点授权,而且可以授权给角色、群组、人员。
注意:
2. 操作授权
通过jsp引入标签按钮配置授权
通过状态、角色控制权限
参见《AEAI DP按钮权限配置说明》,http://my.oschina.net/agileai/blog/533385。
6.2.3 典型场景
1. 复制数据插入
1) 把原结果集查询出来,类型为List;
2) 使用ListUtil.toDataParam方法把结果集转换为参数集合,类型为List;
3) 使用DaoHelper调用sqlmap中配置的insertSQL来插入参数集合。
2. 排序控制说明
首先在JSP页面,添加按钮
" align="center"> 上移
" align="center">
function doMoveUp(){
if (!isSelectedRow()){
writeErrorMsg('请先选中一条记录!');
return;
}
doSubmit({actionType:'moveUp'});
}
function doMoveDown(){
if (!isSelectedRow()){
writeErrorMsg('请先选中一条记录!');
return;
}
doSubmit({actionType:'moveDown'});
}
上移下移在handler里的方法
public ViewRenderer doMoveUpAction(DataParam param){
String currentSubTableId = param.get("currentSubTableId");
boolean isFirst = getService().isFirstChild(currentSubTableId,param);
if (isFirst){
setErrorMsg(this.moveUpErrorMsg);
}else{
getService().changeCurrentSort(param, true);
}
return prepareDisplay(param);
}
public ViewRenderer doMoveDownAction(DataParam param){
String currentSubTableId = param.get("currentSubTableId");
boolean isLast = getService().isLastChild(currentSubTableId,param);
if (isLast){
setErrorMsg(this.moveDownErrorMsg);
}else{
getService().changeCurrentSort(param, false);
}
return prepareDisplay(param);
}
在service方法里调整两个字段排序顺序
publicvoid changeCurrentSort(DataParam param, boolean isUp) {
String subId = param.get("currentSubTableId");
String statementId = sqlNameSpace+"."+"find"+StringUtil.upperFirst(subId)+"Records";
List records = this.daoHelper.queryRecords(statementId, param);
String tableName = subTableIdNameMapping.get(subId);
String idField = "当前表的主键字段名";
String currentId = "记录标识";
String sortField = "排序字段名";
DataRow curRow = null;
String curSort = null;
if (isUp){
DataRow beforeRow = null;
for (int i=0;i < records.size();i++){
DataRow row = records.get(i);
String tempMenuId = row.stringValue(idField);
if (currentId.equals(tempMenuId)){
curRow = row;
beforeRow = records.get(i-1);
break;
}
}
curSort = curRow.stringValue(sortField);
String beforeSort = beforeRow.stringValue(sortField);;
curRow.put(sortField,beforeSort);
beforeRow.put(sortField,curSort);
this.updateSubRecord(subId,curRow.toDataParam(true));
this.updateSubRecord(subId,beforeRow.toDataParam(true));
}else{
DataRow nextRow = null;
for (int i=0;i < records.size();i++){
DataRow row = records.get(i);
String tempMenuId = row.stringValue(idField);
if (currentId.equals(tempMenuId)){
curRow = row;
nextRow = records.get(i+1);
break;
}
}
curSort = curRow.stringValue(sortField);
String nextSort = nextRow.stringValue(sortField);
curRow.put(sortField,nextSort);
nextRow.put(sortField,curSort);
this.updateSubRecord(subId,curRow.toDataParam(true));
this.updateSubRecord(subId,nextRow.toDataParam(true));
}
}
2. 结果集转换为FormSelect
在进行开发的时候,会遇到select下拉框形式 的表单元素,这时就需要在控制层的pricessPageAttributes方法中将查询得到的结果集转换为formselect类型,如下例:
List records = getService().findPcNameRecords(param);
FormSelect formSelect = new FormSelect();
formSelect.setKeyColumnName("PC_CODE");
formSelect.setValueColumnName("PC_NAME");
formSelect.putValues(records);
setAttribute("pcName",formSelect.addSelectedValue(param.get("pcName")));
首先通过查询得到list结果集records,结果集中需要存在有id(编码)和value(值)两列属性
然后new一个FormSelect类型的变量,然后给这个变量添加对应的id和value两个属性字段,再通过putValues方法把结果集中的数据放到formSelect中。在setAttribute中将param中对应的变量的值通过formSelect将这个选中的值存入到变量pcName中。
3. 基于HTML导出Word、PDF
1) 构造Html模板
2) 将模板转换为IO流
3) 调用对应的API进行格式转换
4. 批量处理结果集
首先需要前台jsp页面添加checkbox复选框,代码如下:
隐藏域:
name="ids" value="<%=pageBean.inputValue("ids")%>" />
上面个代码选中了当前记录的ID,然后点击操作按钮调用对应的JS方法,将ids传到后台handler中处理:
function doDeleteRequest(){
var ids = "";
var confirmsubMsg="您确认删除该数据吗?";
$("input:[name='ID_ID'][checked]").each(function(){
ids = ids+$(this).val()+",";
});
if (ids.length > 0){
ids = ids.substring(0,ids.length-1);
}
if(confirm(confirmsubMsg)) {
//showSplash(deleteMsg);
$("#ids").val(ids);
doSubmit({actionType:'batchDelete'});
}
}
由于接到的参数为多条记录,并用逗号分隔的,需要在后台进行处理,具体代码如下:
public ViewRenderer doBatchDeleteAction(DataParam param) {
String ids = param.get("ids");
if(!"".equals(ids)){
String[] idArray = ids.split(",");
for(int i=0;i < idArray.length;i++ ){
String id = idArray[i];
DataParam idParam = new DataParam();
idParam.put("ID_ID", id);
getService().deleteClusterRecords(idParam);
}
}
return prepareDisplay(param);
}
5. 数值公式计算
我们在项目使用MVL的TemplateRuntime计算方式,具体代码如下:
publicstaticvoid main(String[] args) {
String testFormula = "@{value+5}";
Map vars = new HashMap();
vars.put("value", 3.0);
Number number = (Number) TemplateRuntime.eval(testFormula,vars);
System.out.print(number);
}
输出后的结果:
6. 后台控制jsp页面
标签合并
public ViewRenderer prepareDisplay(DataParam param){
initParameters(param);
this.setAttributes(param);
if (!TreeAndContentManage.BASE_TAB_ID.equals(tabId)){
param.put("columnId",columnId);
List rsList = getService().findContentRecords(filterTreeModel,tabId,param);
this.processRowSpanField(rsList);
this.setRsList(rsList);
request.setAttribute("rsList", rsList);
}else{
DataParam queryParam = new DataParam(columnIdField,columnId);
DataRow row = getService().queryTreeRecord(queryParam);
this.setAttributes(row);
}
processPageAttributes(param);
return new LocalRenderer(getPage());
}
privatevoid processRowSpanField(List rsList){
int spanCount = 0;
DataRow beforeRow = null;
for (int i=0;i < rsList.size();i++){
DataRow curRow = rsList.get(i);
String curRlName = curRow.getString("RL_NAME")!=null?curRow.getString("RL_NAME"):"";
if (beforeRow == null){
beforeRow = curRow;
spanCount++;
beforeRow.put("rowSpan",spanCount);
continue;
}
String beforeRLName = beforeRow.getString("RL_NAME")!=null?beforeRow.getString("RL_NAME"):"";
if (beforeRLName.equals(curRlName)){
spanCount++;
beforeRow.put("rowSpan",spanCount);
curRow.put("rowSpan",0);
}
else{
curRow.put("rowSpan",1);
beforeRow = curRow;
spanCount = 0;
spanCount++;
}
}
}
在显示列表页面时,调用下面代码
<%=(i+1)%> <%if (0 != rowSpan){%>
<%=dataRow.getString("RL_NAME","")%> <%}%>
6.3 学习技巧
6.3.1 利用system代码
使用AEAI DP创建工程的时候默认就会创建系统管理相关代码,系统管理里面涉及的模块几乎是所有管理系统都带的功能,这部分代码较多,值得推荐学习,事实上很多开发所需要的代码样例都可以在里面找到。
6.3.2 跟踪研读父类
Hotweb预置很多典型的功能模型,每个Handler和Service都继承对应功能模型的Handler和Service,而且hotweb源码都直接打入hotweb_core.jar,在开发、调试过程中可以跟踪研究父类来深入掌握相关调用机制、借鉴相关代码技巧。
6.3.3 查找类似代码
很多js代码、工具类的调用方式其实都散落在系统框架(预置的以及自动生成)的代码里,可以通过DP Studio(Eclipse)的文件查找方式来了解相关调用机制。
6.3.4 反编译参考代码
在hotweb中也引用了一些地方类库,如:ecside、ibatis、spring、mvel等等,包括AEAI Portal、AEAI BPM的一些classes、jar文件,都可以通过jd-gui来反编译学习分析代码,参考样例,如:反编译预置的portlet代码、参考开发新portlet。
7 感悟与收获
AEAI DP开发平台可以快速上手,对于最开始入职的我较容易产生成就感,但是随着后续深入使用,实际应用过程中的各种扩展开发,逐渐暴露出我自己的知识积累不足,同时也发现Miscdp Studio可以生成典型功能、典型的方法,便于调试部署,但更多代码的精华是藏在Hotweb框架里,Hotweb预留很多方法用于扩展,预置很多工具类通过组合使用可以几乎所有场景的功能,同时第三方的类库也很容易在AEAI DP中调用来满足实际项目的特定需求。
AEAI DP开发平台精要文档 下载
你可能感兴趣的:(AEAI,DP,开发平台)
云智慧发布对象关系型数据库CloudPanguDB,打破传统技术壁垒
近日,云智慧推出关系型数据库CloudPanguDB(中文名称:盘古数据库),旨在通过高兼容性能和创新技术架构,降低企业项目整体运营成本。无论是处理海量复杂数据,还是构建清晰有序的数据结构关系,CloudPanguDB都具有强大的应用价值。随着各产业数字化转型的迅速发展,企业对国产化数据库需求与日俱增。CloudPanguDB以云智慧自身产品技术为基础,统一优化技术架构,功能覆盖关系型数据库、全文
Dify1.01版本vscode 本地环境搭建运行实践
hamish-wu
vscode 编辑器 dify 大模型 python flask
dify是python编写的低代码AI开发平台,是常用的大模型开发平台。本文基于最新的1.0.1版本实践完成,有需要的可以私信交流。咨询免费,详细文档及视频需要一定成本,大概相当于节约的时间成本。搭建环境windows11开发工具vscode搭建步骤:1.Startthedocker-composestackwindow环境下运行docker命令,需要下载docker官网镜像,会遇到timeout
ERROR: Failed building wheel for pyaudioFailed to build pyaudioERROR: ERROR: Failed to build insta
小李飞刀李寻欢
python audio pyaudio 安装库 python
ERROR:FailedbuildingwheelforpyaudioFailedtobuildpyaudioERROR:ERROR:Failedtobuildinstallablewheelsforsomepyproject.tomlbasedprojects(pyaudio)这个错误表明在编译pyaudio时缺少PortAudio开发库。以下是完整解决方案:Linux系统解决方案#1.安装系统
TCP和MQTT通信协议
御风_21
物联网分享篇 tcp/ip 网络 服务器 网络协议
协议分层网络分层协议应用层CoAPMQTTHTTP传输层UDPTCP网络层IP链路层Enternet网络分层中最常见的几种协议应用层:应用程序负责将数据以相应规则(协议)进行包装,发给传输层MQTT:消息队列遥测传输CoAP:受限应用协议HTTP:超文本传输协议传输层:负责将应用层传输过来的数组进行分组,为确保终端接收数据的顺序和完整性,会对每个分组进行标记,交给网络层TCP:传输控制协议UDP:
Java并发实战——线程池一篇详解
1加1等于
Java并发 java 多线程
本文将深入探讨Java线程池的各个方面,从基础概念到高级应用,从而全面掌握线程池的使用,解决频繁地创建和销毁线程带来巨大的系统开销,包括内存消耗、CPU时间浪费等,通过复用线程,避免了线程的频繁创建和销毁,从而提高了系统的性能和稳定性。本文目录一、线程池简介二、线程池优点三、线程池相关概念ThreadPoolExecutor的构造函数任务队列拒绝策略四、线程池的使用五、线程池工厂类固定大小线程池单
前端面试常见的计算机网络内容梳理
GISer_Jinger
前端 javascript
前端面试常见的计算机网络内容梳理,我得从搜索结果里找相关的信息。先看看各个网页的内容。网页1和网页2主要讲OSI模型、TCP/IP模型,ARP、DNS、TCP/UDP区别这些基础概念,这些都是常考的点。网页3提到了TCP三次握手、HTTP缓存、跨域方法,还有CDN原理,这些都是前端面试的重点。网页4详细讨论了HTTP请求方法、状态码、请求头和响应头,这些内容也很关键。网页5提到了HTTPS加密原理
洛谷 P11293 [NOISG 2022 Qualification] L-Board
Yingye Zhu(HPXXZYY)
思维题 前缀和 算法
[Analysis]\texttt{\color{blue}{[Analysis]}}[Analysis]很显然,对于单个点来说,它的第一项对答案的贡献就是往左最大连续子段和和往右最大连续子段和的较大值,第二项对答案的贡献就是往上的最大连续子段和和往下的最大连续子段和的较大值,第三项是本身。于是把问题转化为求最大连续子段和。当然这个问题可以用一个经典的dp解决。但是对于一个退役的大学生来说,问题应
字节跳动算法高频题:动态规划最优模板
知识产权13937636601
计算机 算法 动态规划
本文系统梳理字节跳动近三年算法面试中的动态规划(DP)高频题型,提炼出适用于80%场景的通用解题模板。通过背包问题、字符串处理、状态压缩等六大核心模块解析,结合跳槽、股票交易、编辑距离等15道真题案例,揭示动态规划的状态转移方程构建规律与维度优化技巧,助您在面试中实现时间复杂度与空间复杂度的双重最优解。第一章动态规划基础框架1.1动态规划三大特征特征判定标准真题案例重叠子问题递归树中存在重复计算节
Java 并发编程实战:深入理解线程池的核心原理与最佳实践
全栈探索者chen
java java 服务器 开发语言 性能优化 缓存 node.js 数据库
Java并发编程实战:深入理解线程池的核心原理与最佳实践1.为什么需要线程池?在Java并发编程中,直接创建和管理线程的成本较高,频繁创建线程会带来性能开销和资源浪费。线程池(ThreadPool)的作用:降低线程创建和销毁的开销,提高系统响应速度。提高系统吞吐量,充分利用CPU资源。避免资源耗尽,限制最大线程数,防止OOM(内存溢出)。支持任务排队,确保任务按照一定规则执行。2.线程池的核心组成
洛谷 P2157 [SDOI2009] 学校食堂
syzyc
动态规划 动态规划 状压 dp
题目传送门前言第一次见这么新颖的dpdpdp,竟然可以从当前枚举的iii的前面或者后面转移过来,这不就有后效性了吗?好了开玩笑其实只要状态设计好,还是没有后效性的。思路状态设计首先Bi≤7B_i\leq7Bi≤7,所以肯定是状压dpdpdp,所以一定起码有两维:一维是当前枚举到的iii,一维是压缩后的状态sss(具体是什么等会说)。然后他又说【当前做的菜所用的时间】还和【前一个菜的口味】有关系,所
【费马小定理】【欧拉定理】【扩展欧拉定理】及其证明
syzyc
数论 数论
费马小定理&欧拉定理及其证明注:此文所提到的“整数”“素数”等均指正数费马小定理对于一个素数ppp,任意整数aaa,若gcd(a,p)=1\gcd(a,p)=1gcd(a,p)=1(即aaa,ppp互质),则:ap−1≡1(modp)a^{p-1}\equiv1\pmod{p}ap−1≡1(modp)证明先找出所有小于等于ppp的与ppp互质的正整数,为序列A={1,2,3,…,p−1}A=\{
神经网络中层与层之间的关联
iisugar
神经网络 深度学习 计算机视觉
目录1.层与层之间的核心关联:数据流动与参数传递1.1数据流动(ForwardPropagation)1.2参数传递(BackwardPropagation)2.常见层与层之间的关联模式2.1典型全连接网络(如手写数字分类)2.2卷积神经网络(CNN,如图像分类)2.3循环神经网络(RNN/LSTM,如文本生成)2.4Transformer(如机器翻译)3.层间关联的核心原则3.1数据传递的“管道
第二十一篇:伦理/道德Ethics
flying_1314
NLP ethics 伦理/道德 隐私 偏见 双重用途
目录什么是伦理/道德?我们为什么要关心?为什么道德很难?学习成果大纲反对NLP道德检查的论据我们应该审查科学吗?H5N1透明度不是更好吗?AIvs.Cybersecurity核心NLP伦理概念偏见词嵌入中的偏差双重用途OpenAIGPT-2隐私GDPRAOL搜索数据泄露小组讨论提示自动刑期预测自动简历处理语言社区分类打包带走~什么是伦理/道德?我们应该如何生活——苏格拉底•正确的做法是什么?•为什
动作捕捉手套如何让虚拟现实人机交互 “触手可及”?
广州虚拟动力-动捕&虚拟主播
VR手套 数据手套 动捕手套 动捕数据手套
在虚拟与现实逐渐交融的当下,动作捕捉技术正以前所未有的速度革新着多个领域。动作捕捉技术,简称“动捕”,已经从早期的影视特效制作,逐步拓展到游戏开发、虚拟现实、机器人控制等多个领域。而mHandPrO数据手套作为这一领域的新兴力量,正以其实时、精准的动作捕捉能力,为用户带来全新的交互体验。其内置的感应节点、震动器和反馈装置,能够精准捕捉手部的细微动作,并实时转化为虚拟空间中的自然、流畅互动。在VR娱
P2P通信:WebRTC的原理与实现
幻想彩虹中的绚丽光华
p2p webrtc 网络协议 WebRTC
WebRTC(WebReal-TimeCommunication)是一种用于在Web浏览器之间进行实时通信的开放标准。它提供了一种直接的点对点(P2P)通信方式,使得浏览器之间可以实时传输音频、视频和数据。本文将详细介绍WebRTC的原理和实现,并提供相应的源代码示例。WebRTC的原理:WebRTC利用了多种技术,包括实时传输协议(RTP)、会话发起协议(SDP)、媒体传输控制协议(RTCP)和
封装Socket编程接口
南林yan
Linux学习 网络 linux 服务器
一、Socket编程接口与TCP/UDP的关系Socket是网路通信接口,介于传输层和应用层之间,其封装了传输层的TCP/UDP协议以及网络层的IP协议,允许开发者通过调用编程接口选择使用TCP或UDP协议来实现不同的通信需求。TCP协议特点:面向连接:通过三次握手建立连接(第一次握手:客户端调用connect函数向服务端申请建立连接;第二次握手:服务端处于监听状态,接收客户端的连接;第三次握手:
AF3 rot_matmul 和 rot_vec_mul函数解读
qq_27390023
生物信息学 深度学习 pytorch python
AlphaFold3rigid_utils模块的rot_matmul和rot_vec_mul函数实现了手动计算两个旋转矩阵的乘法A×B以及矩阵-向量乘法R×t,避免了直接用矩阵乘法的AMP(AutomaticMixedPrecision)问题。源代码:defrot_matmul(a:torch.Tensor,b:torch.Tensor)->torch.Tensor:"""Performsmatr
Linux内核网络源码分析——发送数据
hellolwl
Android/Linux linux内核 网络 struct output socket constructor
原文地址:http://www.penna.cn/blog/?p=218UDP发送:|sys_writefs/read_write.c|sock_writevnet/socket.c|sock_sendmsgnet/socket.c|inet_sendmsgnet/ipv4/af_inet.c|udp_sendmsgnet/ipv4/udp.c|ip_build_xmitnet/ipv4/ip_o
协议层攻防战:群联AI云防护为何比传统方案更精准?
群联云防护小杜
安全问题汇总 人工智能 tcp/ip 网络协议 网络 安全
一、四层/七层攻击防御的核心挑战协议层攻击类型传统方案缺陷四层SYNFlood、UDP反射依赖硬件清洗,误封合法流量七层HTTPCC、SQL注入规则静态,无法适应新型攻击二、群联的协议层定制防御技术1.四层协议防护:智能动态指纹技术原理:基于AI分析TCP/UDP流量特征,动态生成协议指纹库,识别伪造源IP的畸形包。文档引用:“防护模块灵活,支持定制版防护模块,适用于非网站业务”。配置示例:#动态
四层协议攻防手册:从SYN Flood到UDP反射的深度防御
群联云防护小杜
安全问题汇总 udp 网络 网络协议 服务器 爬虫 运维 web安全
一、四层协议攻击类型与特征攻击类型协议层特征SYNFloodTCP大量半开连接,SYN_RECV状态堆积UDP反射放大UDP小请求包触发大响应(如NTP、DNS响应)TCP分片攻击TCP发送异常分片耗尽重组资源连接耗尽攻击TCP建立大量空闲连接占用端口资源二、TCP层定制防御方案1.SYNCookie防护(内核参数优化)#启用SYNCookieecho1>/proc/sys/net/ipv4/tc
从边缘到核心:群联云防护如何重新定义安全加速边界?
群联云防护小杜
安全问题汇总 安全 分布式 ddos 前端 node.js udp
一、安全能力的全方位碾压1.协议层深度防护四层防御:动态过滤畸形TCP/UDP包(如SYNFlood),传统CDN仅限速率控制。技术示例:基于AI的协议指纹分析,拦截异常连接模式。七层防御:精准识别业务逻辑攻击(如薅羊毛API调用),CDN仅支持基础URL黑名单。文档引用:“支持基于HTTP头部字段的多条件组合精准访问控制”(产品文档)。2.资源调度与成本优势节点复用:群联共享节点池降低单客户成本
The following modules are *disabled* in configure script:_sqlite3
waketzheng
python
Unabletoupgradepast3.6.9-#24byRosuav-PythonHelp-DiscussionsonPython.orgsudoaptinstalllibsqlite3-devcdPython-3.13.1./configure--enable-optimizations--enable-loadable-sqlite-extensionsmakesudomakealtins
C# 语法糖:深度解析与代码实例演示
墨瑾轩
一起学学C#【一】 c#
C#作为一种现代、面向对象的编程语言,内置了许多语法糖(SyntacticSugar)特性,旨在简化代码书写、提升代码可读性与编写效率,而不会牺牲程序的语义或性能。语法糖并非语言的新功能,而是对已有功能的封装或简化表示,编译器在编译阶段会将其转换为等效的基础语法。以下是一些C#中常见的语法糖特性,结合详细描述、代码示例和注释进行展示。1.属性(Auto-ImplementedProperties)
Python使用minIO上传下载
身似山河挺脊梁
python
前提VSCode+Python3.9minIO有Python的例子1.python生成临时文件2.写入一些数据3.上传到minIO4.获取分享出连接5.发出通知#创建一个客户端minioClient=Minio(endpoint='xx',access_key='xx',secret_key='xx',secure=False)#生成文件名current_datetime=datetime.dat
Android Studio 中将 AAR 包发布到 Maven 本地仓库
帅次
Android Studio android studio maven android kotlin flutter gradle macos
目录1.配置build.gradle.kts(或build.gradle)2.配置publishing任务3.发布到本地Maven仓库3.1Couldnotfindmethodpublications()forarguments...3.2bash:./gradlew:Permissiondenied3.3AndroidGradlepluginrequiresJava17torun.Youarec
access读取EXCEL文件,并根据动态生成表,完成报表的导入
MES先生
ACCESS VBA access
OptionCompareDatabasePublicsheetidAsString'报表IDPublictempAsString'获取年月时分秒PublictmpIAsInteger'对应EXCEL行PublictmpJAsInteger'对应EXCEL列PublicXlsAppAsObjectPublicXlsWorkbookAsObjectPublicXlsWorkSheetAsObject
SpringBoot 整合security 实现自定义Token和clientId登录及退出(二)
.猫的树
spring boot spring java
接上一篇6.认证相关处理创建登录成功DemoAuthenticationSuccessHandler.java/***用户身份验证通过处理*/@Component@SuppressWarnings("all")publicclassDemoAuthenticationSuccessHandlerimplementsAuthenticationSuccessHandler{@Autowiredpri
Android 中蓝牙Profile与UUID
jaylkh
android bluetooth
在Android中,常用的几种BluetoothProfile分别为:SPP(SerialPortProfile)、A2DP(AdvancedAudioDistributionProfile)、AVRCP(Audio/VideoRemoteControlProfile)、HID(HumanInterfaceDeviceProfile)、HFP(Hands-FreeProfile)。其中Media相
不神话大模型,不做技术乌托邦,用"传统IT+AI积木"实现企业智能转型
人工智能
一、开篇:AI革命的务实辩证法在技术狂热与落地鸿沟并存的AI时代,灵燕智能体开发平台提出"三轮驱动法则":•不颠覆的智慧:MySQL、知识图谱库、MQ等传统中间件构成数字地基•不空想的创新:大模型仅承担"认知苦力",在人类设计的思考链中定向发力•不取巧的工程:通过D2R映射、低代码工具、元数据治理实现可落地的智能装配二、核心价值:智能开发的工业流水线技术要素原子化拆解将复杂需求分解为可执行的"技术
基于AWS Endpoint Security(EPS)的自动化安全基线部署
weixin_30777913
云计算 aws python 安全 架构
设计AWS云架构方案实现基于AWSEndpointSecurity(EPS)的自动化安全基线部署,AMSAdvanced(AWS托管服务)环境会为所有新部署的资源自动安装EPS监控客户端,无需人工干预即可建立统一的安全基线。这种自动化机制特别适用于动态扩缩的云环境,确保新启动的EC2实例、容器等终端设备从初始状态即受保护,以及具体实现的详细步骤和关键代码。以下是基于AWSEndpointSecur
分享100个最新免费的高匿HTTP代理IP
mcj8089
代理IP 代理服务器 匿名代理 免费代理IP 最新代理IP
推荐两个代理IP网站:
1. 全网代理IP:http://proxy.goubanjia.com/
2. 敲代码免费IP:http://ip.qiaodm.com/
120.198.243.130:80,中国/广东省
58.251.78.71:8088,中国/广东省
183.207.228.22:83,中国/
mysql高级特性之数据分区
annan211
java 数据结构 mongodb 分区 mysql
mysql高级特性
1 以存储引擎的角度分析,分区表和物理表没有区别。是按照一定的规则将数据分别存储的逻辑设计。器底层是由多个物理字表组成。
2 分区的原理
分区表由多个相关的底层表实现,这些底层表也是由句柄对象表示,所以我们可以直接访问各个分区。存储引擎管理分区的各个底层
表和管理普通表一样(所有底层表都必须使用相同的存储引擎),分区表的索引只是
JS采用正则表达式简单获取URL地址栏参数
chiangfai
js 地址栏参数获取
GetUrlParam:function GetUrlParam(param){
var reg = new RegExp("(^|&)"+ param +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null
怎样将数据表拷贝到powerdesigner (本地数据库表)
Array_06
powerDesigner
==================================================
1、打开PowerDesigner12,在菜单中按照如下方式进行操作
file->Reverse Engineer->DataBase
点击后,弹出 New Physical Data Model 的对话框
2、在General选项卡中
Model name:模板名字,自
logbackのhelloworld
飞翔的马甲
日志 logback
一、概述
1.日志是啥?
当我是个逗比的时候我是这么理解的:log.debug()代替了system.out.print();
当我项目工作时,以为是一堆得.log文件。
这两天项目发布新版本,比较轻松,决定好好地研究下日志以及logback。
传送门1:日志的作用与方法:
http://www.infoq.com/cn/articles/why-and-how-log
上面的作
新浪微博爬虫模拟登陆
随意而生
新浪微博
转载自:http://hi.baidu.com/erliang20088/item/251db4b040b8ce58ba0e1235
近来由于毕设需要,重新修改了新浪微博爬虫废了不少劲,希望下边的总结能够帮助后来的同学们。
现行版的模拟登陆与以前相比,最大的改动在于cookie获取时候的模拟url的请求
synchronized
香水浓
java thread
Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然
maven 简单实用教程
AdyZhang
maven
1. Maven介绍 1.1. 简介 java编写的用于构建系统的自动化工具。目前版本是2.0.9,注意maven2和maven1有很大区别,阅读第三方文档时需要区分版本。 1.2. Maven资源 见官方网站;The 5 minute test,官方简易入门文档;Getting Started Tutorial,官方入门文档;Build Coo
Android 通过 intent传值获得null
aijuans
android
我在通过intent 获得传递兑现过的时候报错,空指针,我是getMap方法进行传值,代码如下 1 2 3 4 5 6 7 8 9
public
void
getMap(View view){
Intent i =
apache 做代理 报如下错误:The proxy server received an invalid response from an upstream
baalwolf
response
网站配置是apache+tomcat,tomcat没有报错,apache报错是:
The proxy server received an invalid response from an upstream server. The proxy server could not handle the request GET /. Reason: Error reading fr
Tomcat6 内存和线程配置
BigBird2012
tomcat6
1、修改启动时内存参数、并指定JVM时区 (在windows server 2008 下时间少了8个小时)
在Tomcat上运行j2ee项目代码时,经常会出现内存溢出的情况,解决办法是在系统参数中增加系统参数:
window下, 在catalina.bat最前面
set JAVA_OPTS=-XX:PermSize=64M -XX:MaxPermSize=128m -Xms5
Karam与TDD
bijian1013
Karam TDD
一.TDD
测试驱动开发(Test-Driven Development,TDD)是一种敏捷(AGILE)开发方法论,它把开发流程倒转了过来,在进行代码实现之前,首先保证编写测试用例,从而用测试来驱动开发(而不是把测试作为一项验证工具来使用)。
TDD的原则很简单:
a.只有当某个
[Zookeeper学习笔记之七]Zookeeper源代码分析之Zookeeper.States
bit1129
zookeeper
public enum States {
CONNECTING, //Zookeeper服务器不可用,客户端处于尝试链接状态
ASSOCIATING, //???
CONNECTED, //链接建立,可以与Zookeeper服务器正常通信
CONNECTEDREADONLY, //处于只读状态的链接状态,只读模式可以在
【Scala十四】Scala核心八:闭包
bit1129
scala
Free variable A free variable of an expression is a variable that’s used inside the expression but not defined inside the expression. For instance, in the function literal expression (x: Int) => (x
android发送json并解析返回json
ronin47
android
package com.http.test;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import
一份IT实习生的总结
brotherlamp
PHP php资料 php教程 php培训 php视频
今天突然发现在不知不觉中自己已经实习了 3 个月了,现在可能不算是真正意义上的实习吧,因为现在自己才大三,在这边撸代码的同时还要考虑到学校的功课跟期末考试。让我震惊的是,我完全想不到在这 3 个月里我到底学到了什么,这是一件多么悲催的事情啊。同时我对我应该 get 到什么新技能也很迷茫。所以今晚还是总结下把,让自己在接下来的实习生活有更加明确的方向。最后感谢工作室给我们几个人这个机会让我们提前出来
据说是2012年10月人人网校招的一道笔试题-给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 将重物放到天平左侧,问在两边如何添加砝码
bylijinnan
java
public class ScalesBalance {
/**
* 题目:
* 给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 (假设N无限大,但一种重量的砝码只有一个)
* 将重物放到天平左侧,问在两边如何添加砝码使两边平衡
*
* 分析:
* 三进制
* 我们约定括号表示里面的数是三进制,例如 47=(1202
dom4j最常用最简单的方法
chiangfai
dom4j
要使用dom4j读写XML文档,需要先下载dom4j包,dom4j官方网站在 http://www.dom4j.org/目前最新dom4j包下载地址:http://nchc.dl.sourceforge.net/sourceforge/dom4j/dom4j-1.6.1.zip
解开后有两个包,仅操作XML文档的话把dom4j-1.6.1.jar加入工程就可以了,如果需要使用XPath的话还需要
简单HBase笔记
chenchao051
hbase
一、Client-side write buffer 客户端缓存请求 描述:可以缓存客户端的请求,以此来减少RPC的次数,但是缓存只是被存在一个ArrayList中,所以多线程访问时不安全的。 可以使用getWriteBuffer()方法来取得客户端缓存中的数据。 默认关闭。 二、Scan的Caching 描述: next( )方法请求一行就要使用一次RPC,即使
mysqldump导出时出现when doing LOCK TABLES
daizj
mysql mysqdump 导数据
执行 mysqldump -uxxx -pxxx -hxxx -Pxxxx database tablename > tablename.sql
导出表时,会报
mysqldump: Got error: 1044: Access denied for user 'xxx'@'xxx' to database 'xxx' when doing LOCK TABLES
解决
CSS渲染原理
dcj3sjt126com
Web
从事Web前端开发的人都与CSS打交道很多,有的人也许不知道css是怎么去工作的,写出来的css浏览器是怎么样去解析的呢?当这个成为我们提高css水平的一个瓶颈时,是否应该多了解一下呢?
一、浏览器的发展与CSS
《阿甘正传》台词
dcj3sjt126com
Part Ⅰ:
《阿甘正传》Forrest Gump经典中英文对白
Forrest: Hello! My names Forrest. Forrest Gump. You wanna Chocolate? I could eat about a million and a half othese. My momma always said life was like a box ochocol
Java处理JSON
dyy_gusi
json
Json在数据传输中很好用,原因是JSON 比 XML 更小、更快,更易解析。
在Java程序中,如何使用处理JSON,现在有很多工具可以处理,比较流行常用的是google的gson和alibaba的fastjson,具体使用如下:
1、读取json然后处理
class ReadJSON
{
public static void main(String[] args)
win7下nginx和php的配置
geeksun
nginx
1. 安装包准备
nginx : 从nginx.org下载nginx-1.8.0.zip
php: 从php.net下载php-5.6.10-Win32-VC11-x64.zip, php是免安装文件。
RunHiddenConsole: 用于隐藏命令行窗口
2. 配置
# java用8080端口做应用服务器,nginx反向代理到这个端口即可
p
基于2.8版本redis配置文件中文解释
hongtoushizi
redis
转载自: http://wangwei007.blog.51cto.com/68019/1548167
在Redis中直接启动redis-server服务时, 采用的是默认的配置文件。采用redis-server xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务。下面是Redis2.8.9的配置文
第五章 常用Lua开发库3-模板渲染
jinnianshilongnian
nginx lua
动态web网页开发是Web开发中一个常见的场景,比如像京东商品详情页,其页面逻辑是非常复杂的,需要使用模板技术来实现。而Lua中也有许多模板引擎,如目前我在使用的lua-resty-template,可以渲染很复杂的页面,借助LuaJIT其性能也是可以接受的。
如果学习过JavaEE中的servlet和JSP的话,应该知道JSP模板最终会被翻译成Servlet来执行;而lua-r
JZSearch大数据搜索引擎
颠覆者
JavaScript
系统简介:
大数据的特点有四个层面:第一,数据体量巨大。从TB级别,跃升到PB级别;第二,数据类型繁多。网络日志、视频、图片、地理位置信息等等。第三,价值密度低。以视频为例,连续不间断监控过程中,可能有用的数据仅仅有一两秒。第四,处理速度快。最后这一点也是和传统的数据挖掘技术有着本质的不同。业界将其归纳为4个“V”——Volume,Variety,Value,Velocity。大数据搜索引
10招让你成为杰出的Java程序员
pda158
java 编程 框架
如果你是一个热衷于技术的
Java 程序员, 那么下面的 10 个要点可以让你在众多 Java 开发人员中脱颖而出。
1. 拥有扎实的基础和深刻理解 OO 原则 对于 Java 程序员,深刻理解 Object Oriented Programming(面向对象编程)这一概念是必须的。没有 OOPS 的坚实基础,就领会不了像 Java 这些面向对象编程语言
tomcat之oracle连接池配置
小网客
oracle
tomcat版本7.0
配置oracle连接池方式:
修改tomcat的server.xml配置文件:
<GlobalNamingResources>
<Resource name="utermdatasource" auth="Container"
type="javax.sql.DataSou
Oracle 分页算法汇总
vipbooks
oracle sql 算法 .net
这是我找到的一些关于Oracle分页的算法,大家那里还有没有其他好的算法没?我们大家一起分享一下!
-- Oracle 分页算法一
select * from (
select page.*,rownum rn from (select * from help) page
-- 20 = (currentPag