1.什么是源码Java语言
2.Java学习资源
3.很开心,在使用mybatis的下载过程中我踩到一个坑。
4.Mybatis 源码OGNL导致的并发安全问题
5.实战Arthas:常见命令与最佳实践
6.为何Mybatis将Integer为0的属性解析成空串?
什么是Java语言
Java简介
Java是由Sun Microsystems公司于年5月推出的Java程序设计语言(以下简称Java语言)和Java平台的总称。用Java实现的下载HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台、动感的源码Web、Internet计算。下载igraph 源码包安装从此,源码Java被广泛接受并推动了Web的下载迅速发展,常用的源码浏览器现在均支持Java applet。另一方面,下载Java技术也不断更新。源码
Java平台由Java虚拟机(Java Virtual Machine)和Java 应用编程接口(Application Programming Interface、下载简称API)构成。源码Java 应用编程接口为Java应用提供了一个独立于操作系统的下载标准接口,可分为基本部分和扩展部分。源码在硬件或操作系统平台上安装一个Java平台之后,Java应用程序就可运行。现在Java平台已经嵌入了几乎所有的操作系统。这样Java程序可以只编译一次,就可以在各种系统中运行。Java应用编程接口已经从1.1x版发展到1.2版。目前常用的Java平台基于Java1.4,最近版本为Java1.6。
Java分为三个体系JavaSE,JavaEE,JavaME。
Java语言
Java语言是一个支持网络计算的面向对象程序设计语言。Java语言吸收了Smalltalk语言和C++语言的优点,并增加了其它特性,如支持并发程序设计、网络通信、和多媒体数据控制等。主要特性如下:
1、Java语言是简单的。Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用Java。另一方面,Java丢弃了C++ 中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java语言不使用指针,并提供了自动的废料收集,使得程序员不必为内存管理而担忧。
2、Java语言是一个面向对象的。Java语言提供类、接口和继承等原语,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为implements)。Java语言全面支持动态绑定,而C++ 语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。
3、Java语言是热血军团 源码分布式的。Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java.net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、 ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。
4、Java语言是健壮的。Java的强类型机制、异常处理、废料的自动收集等是Java程序健壮性的重要保证。对指针的丢弃是Java的明智选择。Java的安全检查机制使得Java更具健壮性。
5、Java语言是安全的。Java通常被用在网络环境中,为此,Java提供了一个安全机制以防恶意代码的攻击。除了Java语言具有的许多安全特性以外,Java对通过网络下载的类具有一个安全防范机制(类ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查,并提供安全管理机制(类SecurityManager)让Java应用设置安全哨兵。
6、Java语言是体系结构中立的。Java程序(后缀为java的文件)在Java平台上被编译为体系结构中立的字节码格式(后缀为class的文件), 然后可以在实现这个Java平台的任何系统中运行。这种途径适合于异构的网络环境和软件的分发。
7、Java语言是可移植的。这种可移植性来源于体系结构中立性,另外,Java还严格规定了各个基本数据类型的长度。Java系统本身也具有很强的可移植性,Java编译器是用Java实现的,Java的运行环境是用ANSI C实现的。
8、Java语言是解释型的。如前所述,Java程序在Java平台上被编译为字节码格式, 然后可以在实现这个Java平台的任何系统中运行。在运行时,Java平台中的Java解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。
9、Java是高性能的。与那些解释型的高级脚本语言相比,Java的确是高性能的。事实上,Java的运行速度随着JIT(Just-In-Time)编译器技术的发展越来越接近于C++。
、Java语言是多线程的。在Java语言中,线程是一种特殊的对象,它必须由Thread类或其子(孙)类来创建。通常有两种方法来创建线程:其一,使用型构为Thread(Runnable) 的构造子将一个实现了Runnable接口的对象包装成一个线程,其二,从Thread类派生出子类并重写run方法,惠夺宝源码使用该子类创建的对象即为线程。值得注意的是Thread类已经实现了Runnable接口,因此,任何一个线程均有它的run方法,而run方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。 Java语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为synchronized)。
、Java语言是动态的。Java语言的设计目标之一是适应于动态变化的环境。Java程序需要的类能动态地被载入到运行环境,也可以通过网络来载入所需要的类。这也有利于软件的升级。另外,Java中的类有一个运行时刻的表示,能进行运行时刻的类型检查。
Java语言的优良特性使得Java应用具有无比的健壮性和可靠性,这也减少了应用系统的维护费用。Java对对象技术的全面支持和Java平台内嵌的API能缩短应用系统的开发时间并降低成本。Java的编译一次,到处可运行的特性使得它能够提供一个随处可用的开放结构和在多平台之间传递信息的低成本方式。特别是Java企业应用编程接口(Java Enterprise APIs)为企业计算及电子商务应用系统提供了有关技术和丰富的类库。
1、JDBC(Java Database Connectivity)提供连接各种关系数据库的统一接口。
2、EJB(Enterprise JavaBeans)使得开发者方便地创建、部署和管理跨平台的基于组件的企业应用。
3、Java RMI(Java Remote Method Invocation)用来开发分布式Java应用程序。一个Java对象的方法能被远程Java虚拟机调用。这样,远程方法激活可以发生在对等的两端,也可以发生在客户端和服务器之间,只要双方的应用程序都是用Java写的。
4、Java IDL(Java Interface Definition Language) 提供与CORBA(Common Object Request Broker Architecture)的无逢的互操作性。这使得Java能集成异构的商务信息资源。
5、JNDI(Java Naming and Directory Interface)提供从Java平台到的统一的无逢的连接。这个接口屏蔽了企业网络所使用的各种命名和目录服务。
6、JMAPI(Java Management API)为异构网络上系统、网络和服务管理的开发提供一整套丰富的对象和方法。
7、JMS(Java Message Service)提供企业消息服务,如可靠的消息队列、发布和订阅通信、以及有关推拉(Push/Pull)技术的各个方面。
8、JTS(Java transaction Service)提供存取事务处理资源的开放标准,这些事务处理资源包括事务处理应用程序、事务处理管理及监控。
在Java技术中,值得关注的还有JavaBeans,它是一个开放的标准的组件体系结构,它独立于平台,但使用Java语言。一个JavaBean是一个满足JavaBeans规范的Java类,通常定义了一个现实世界的java opencv源码事物或概念。一个JavaBean的主要特征包括属性、方法和事件。通常,在一个支持JavaBeans规范的开发环境(如Sun Java Studio 和IBM VisualAge for Java)中,可以可视地操作JavaBean,也可以使用JavaBean构造出新的JavaBean。JavaBean的优势还在于Java带来的可移植性。现在,EJB (Enterprise JavaBeans) 将JavaBean概念扩展到Java服务端组件体系结构,这个模型支持多层的分布式对象应用。除了JavaBeans,典型的组件体系结构还有DCOM和CORBA,关于这些组件体系结构的深入讨论超出了本书的范围。
Java开源项目
Spring Framework
Spring 是一个解决了许多在J2EE开发中常见的问题的强大框架。 Spring提供了管理业务对象的一致方法并且鼓励了注入对接口编程而不是对类编程的良好习惯。Spring的架构基础是基于使用JavaBean属性的 Inversion of Control容器。然而,这仅仅是完整图景中的一部分:Spring在使用IoC容器作为构建完关注所有架构层的完整解决方案方面是独一无二的。 Spring提供了唯一的数据访问抽象,包括简单和有效率的JDBC框架,极大的改进了效率并且减少了可能的错误。Spring的数据访问架构还集成了 Hibernate和其他O/R mapping解决方案。Spring还提供了唯一的事务管理抽象,它能够在各种底层事务管理技术,例如JTA或者JDBC事务提供一个一致的编程模型。 Spring提供了一个用标准Java语言编写的AOP框架,它给POJOs提供了声明式的事务管理和其他企业事务--如果你需要--还能实现你自己的 aspects。这个框架足够强大,使得应用程序能够抛开EJB的复杂性,同时享受着和传统EJB相关的关键服务。Spring还提供了可以和IoC容器集成的强大而灵活的MVC Web框架。.
WebWork
WebWork 是由OpenSymphony组织开发的,致力于组件化和代码重用的拉出式MVC模式J2EE Web框架。WebWork目前最新版本是2.1,现在的WebWork2.x前身是Rickard Oberg开发的WebWork,但现在WebWork已经被拆分成了Xwork1和WebWork2两个项目。 Xwork简洁、灵活功能强大,它是一个标准的Command模式实现,并且完全从web层脱离出来。 Xwork提供了很多核心功能:前端拦截机(interceptor),运行时表单属性验证,类型转换,强大的表达式语言(OGNL – the Object Graph Notation Language),IoC(Inversion of Control倒置控制)容器等。 WebWork2建立在Xwork之上,处理HTTP的响应和请求。WebWork2使用ServletDispatcher将HTTP请求的变成 Action(业务层Action类), session(会话)application(应用程序)范围的映射,request请求参数映射。WebWork2支持多视图表示,视图部分可以使用 JSP, Velocity, FreeMarker, JasperReports,XML等。在WebWork2.2中添加了对AJAX的支持,这支持是构建在DWR与Dojo这两个框架的基础之上.
Struts
Struts 是一个基于Sun J2EE平台的MVC框架,主要是采用Servlet和JSP技术来实现的。由于Struts能充分满足应用开发的需求,简单易用,敏捷迅速,在过去的一年中颇受关注。Struts把Servlet、社区医疗 源码JSP、自定义标签和信息资源(message resources)整合到一个统一的框架中,开发人员利用其进行开发时不用再自己编码实现全套MVC模式,极大的节省了时间,所以说Struts是一个非常不错的应用框架。
Hibernate
Hibernate 是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序实用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。Eclipse平台下的Hibernate辅助开发工具:
Quartz
Quartz 是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 1.5.0。
Velocity
Velocity 是一个基于java的模板引擎(template engine)。它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象。当Velocity应用于web开发时,界面设计人员可以和java程序开发人员同步开发一个遵循MVC架构的web站点,也就是说,页面设计人员可以只关注页面的显示效果,而由java程序开发人员关注业务逻辑编码。Velocity将java代码从web页面中分离出来,这样为web站点的长期维护提供了便利,同时也为我们在JSP和PHP之外又提供了一种可选的方案。 Velocity的能力远不止web站点开发这个领域,例如,它可以从模板(template)产生SQL和PostScript、XML,它也可以被当作一个独立工具来产生源代码和报告,或者作为其他系统的集成组件使用。Velocity也可以为Turbine web开发架构提供模板服务(template service)。Velocity+Turbine提供一个模板服务的方式允许一个web应用以一个真正的MVC模型进行开发。
IBATIS
使用ibatis 提供的ORM机制,对业务逻辑实现人员而言,面对的是纯粹的Java对象, 这一层与通过Hibernate 实现ORM 而言基本一致,而对于具体的数据操作,Hibernate 会自动生成SQL 语句,而ibatis 则要求开发者编写具体的SQL 语句。相对Hibernate等 “全自动”ORM机制而言,ibatis 以SQL开发的工作量和数据库移植性上的让步,为系统设计提供了更大的自由空间。作为“全自动”ORM 实现的一种有益补充,ibatis 的出现显 得别具意义。
Compiere ERP&CRM
Compiere ERP&CRM为全球范围内的中小型企业提供综合型解决方案,覆盖从客户管理、供应链到财务管理的全部领域,支持多组织、多币种、多会计模式、多成本计算、多语种、多税制等国际化特性。易于安装、易于实施、易于使用。只需要短短几个小时,您就可以使用申购-采购-发票-付款、报价-订单-发票-收款、产品与定价、资产管理、客户关系、供应商关系、员工关系、经营业绩分析等强大功能了。
Roller Weblogger
这个weblogging 设计得比较精巧,源代码是很好的学习资料。它支持weblogging应有的特性如:评论功能,所见即所得HTML编辑,TrackBack,提供页面模板,RSS syndication,blogroll管理和提供一个XML-RPC 接口。
Eclipse
Eclipse平台是IBM向开发源码社区捐赠的开发框架,它之所以出名并不是因为IBM宣称投入开发的资金总数 —4千万美元,而是因为如此巨大的投入所带来的成果:一个成熟的、精心设计的以及可扩展的体系结构。
XPlanner
XPlanner 一个基于Web的XP团队计划和跟踪工具。XP独特的开发概念如iteration、user stories等,XPlanner都提供了相对应的的管理工具,XPlanner支持XP开发流程,并解决利用XP思想来开发项目所碰到的问题。 XPlanner特点包括:简单的模型规划,虚拟笔记卡(Virtual note cards),iterations、user stories与工作记录的追踪,未完成stories将自动迭代,工作时间追踪,生成团队效率,个人工时报表,SOAP界面支持。
HSQLDB
HSQLDB(Hypersonic SQL)是纯Java开发的关系型数据库,并提供JDBC驱动存取数据。支持ANSI- 标准 SQL语法。而且他占的空间很小。大约只有K,拥有快速的数据库引擎。
Liferay
代表了完整的J2EE应用,使用了Web、EJB以及JMS等技术,特别是其前台界面部分使用Struts 框架技术,基于XML的portlet配置文件可以自由地动态扩展,使用了Web Services来支持一些远程信息的获取,使用 Apahce Lucene实现全文检索功能。
主要特点:
1、提供单一登陆接口,多认证模式(LDAP或SQL);
2、管理员能通过用户界面轻松管理用户,组,角色;
3、用户能可以根据需要定制个性化的portal layout;
4、能够在主流的J2EE应用服务器上运行,如JBoss+Jetty/Tomcat,JOnAS;
5、支持主流的数据库,如PostgreSQL,MySQL;
6、使用了第三放的开源项目,如Hibernate, Lucene, Struts;
7、支持包括中文在内的多种语言;
8、采用最先进的技术 Java, EJB, JMS, SOAP, XML;
JetSpeed
Jetspeed 是一个开放源代码的企业信息门户(EIP)的实现,使用的技术是Java和XML。用户可以使用浏览器,支持WAP协议的手机或者其它的设备访问Jetspeed架设的信息门户获取信息。Jetspeed扮演着信息集中器的角色,它能够把信息集中起来并且很容易地提供给用户。
Jetspeed具有如下的特征:
* 即将成为标准化的Java Portlet API
* 基于模板的布局, 包括JSP和Velocity
* 通过开放的内容同步技术支持远程XML内容交换
* 定制默认的主页
* 使用数据库进行用户认证
* 内存缓存技术, 加快页面的响应
* 通过Rich Site Summary技术, 支持同步内容
* 和Cocoon, WebMacro, Velocity集成.
* Wireless Markup Language (WML) 支持
* 使用XML格式的配置文件注册portlet.
* 完整的Web Application Archive (WAR) 支持
* Web应用程序开发的基础设施
* 可以在本地缓存远程内容
* 与Avantgo同步
* 可移植到所有支持JDK1.2和Servlet 2.2的平台
* 与Turbine模块和服务集成
* 可以根据用户, 安装媒体类型和语言的不同设定, 产生不同的个性化服务
* 持续化服务使得所由的portlet能够容易的存储每个用户的状态, 页面和portlet
* 使用皮肤技术使得用户可以选择portlet的颜色和显示属性
* 自定义功能是的管理员可以选择portlet以及定义个人页面的布局
* 在数据库中存储PSML
* 通过Jetspeed的安全portlets管理用户, 组,角色和权限
* 基于角色对访问portlet进行控制
JOnAS
JOnAS 是一个开放源代码的J2EE实现,在ObjectWeb协会中开发。整合了Tomcat或Jetty成为它的Web容器,以确保符合Servlet 2.3和JSP 1.2规范。JOnAS服务器依赖或实现以下的Java API:JCA、JDBC、JTA 、JMS、JMX、JNDI、JAAS、JavaMail 。
JFox3.0
JFox 是 Open Source Java EE Application Server,致力于提供轻量级的Java EE应用服务器,从3.0开始,JFox提供了一个支持模块化的MVC框架,以简化EJB以及Web应用的开发! 如果您正在寻找一个简单、轻量、高效、完善的Java EE开发平台,那么JFox正是您需要的。
JFox 3.0 拥有以下特性:
1. 重新设计的 IoC 微内核,融入 OSGi 模块化思想
2. 设计成嵌入式架构,能够和任何 Java Web Server集成部署
3. 支持 EJB3,JPA规范,支持容器内和容器外两种方式运行EJB和JPA组件
4. 支持 EJB 发布成Web Service
5. 采用 JOTM()提供事务处理,支持两阶段提交(2PC)
6. 采用 XAPool() 提供 XA DataSource,支持智能连接池管理
7. 内置 MVC 框架,实现自动Form Mapping,Validator,Uploading等功能,支持JSP/Velocity/Freemarker页面引擎,并支持直接在Action中注入EJB
8. 支持多应用模块部署,让中大型应用充分享受模块化开发带来的优势
9. 提供 Manager 管理模块,可以查看和管理各种运行时参数
. 提供根据 JFox 特色重写的 Petstore 应用模块
Java学习资源
Java Commons Java tutorial WebService常用第三方webservice IDEEclipse Eclipse GUI Plugin Eclipse根据java代码生成UML图 Tomcat Hudson Jenkins Atlassian Bamboo TeamCity JUnit DbUnit JMockit TestNG ReportNG SLF4J Log4j Logback Log4E代码评审 guava jga Java Class Dependency Analyzer OW2Forge Rock apache Apache Commons sandbox中的项目无法直接通过maven进行依赖,必须通过svn下载源码,部署到本地maven仓库中。例如对于sandbox中的classscan项目: # 项目地址:commons.apache.org/sand... svn checkout mons/sandbox/classscan classscan cd classscan 当install带有parent的maven项目时,如果没有把parent一并install,其它项目引用时会出现 mvn install--Failed to read artifact descriptor for org.apache.maven.plugins:maven-source-plugin:jar:2.1.2 cd parent (classscan/parent) mvn clean package install -DskipTests cd ../api (classscan/api) mvn clean package install -DskipTests cd ../bcel (classscan/bcel) mvn clean package install -DskipTests 在pom.xml中添加依赖 org.apache.commons.classscan bcel 0.2-SNAPSHOT org.apache.commons.classscan api 0.2-SNAPSHOT Eclipse中Update Project,选择Force Update of Snapshots/Releases Apache HttpComponents Maven and M2Eclipse maven快速下载某个jar包依赖的所有jar 经常碰到这种事情:在一些非maven工程中(由于某种原因这种工程还是手工添加依赖的),需要用到某个新的类库(假设这个类库发布在maven库中),而这个类库又间接依赖很多其他类库,如果依赖路径非常复杂的话,一个个检查手动下载是很麻烦的事。下面给出一个便捷的办法,创建一个新目录里面建一个maven pom文件, 添加需要依赖的类库: 4.0.0 com.dep.download dep-download 1.0-SNAPSHOT com.xx.xxx yy-yyy x.y.z 在这个目录下运行命令,所有跟这个类库相关的直接和间接依赖的jar包都会下载到 ./target/dependency/下 杂项 间接依赖的jar包能否直接使用 如果工程依赖A.jar,并用maven设置好依赖,同时A.jar会依赖B.jar,所以maven在下载A.jar的同时会下载B.jar,这时如果项目发现需要使用B.jar中的一些内容,在maven中不必从新设置依赖,可以在工程中直接使用。 把某个本地jar包安装到本地仓库中 mvn install:install-file -DgroupId=“edu.jiangxin” -DartifactId=”gcu” -Dversion=“1.0.0” -Dpackaging=”jar” -Dfile=“D:\CS\J2EE\lib\edu.jiangxin.gcu-1.0.0.jar” 把某个本地jar包部署到某个远程仓库中 mvn deploy:deploy-file -DgroupId=“edu.jiangxin” -DartifactId=”gcu” -Dversion=“1.0.0” -Dpackaging=”jar” -Dfile=“D:\CS\J2EE\lib\edu.jiangxin.gcu-1.0.0.jar” -Durl= yourlocalrepository:... -DrepositoryId=internal bintray bintray.com/ Ant Eclipse Color Themes MyEclipse EclEmma eCobertura JavaNCSS Clover(收费) CAP (code analysis plugin) Visual Performance Analyzer VisualVM JD(Java Decompiler) 注:不支持命令行使用,因而很难批量编译。 jad 注:jad支持命令行方式使用,最新版本为1.5.8g,支持的class版本过低。经常出现问题:The class file version is .0 (only .3, .0 and .0 are supported)。还有一个工具uuDeJava,也是基于jad,所以估计也难以避免这个问题。 jdec JODED J Java Decompiler 注:收费软件,没有试用过 ProGuard FindBugs PMD Metric Jdepend SourceHelper Structure inFusion SourceMonitor Simian CheckStyle CCTE J-Technologies一家(收费) FORTIFY SCA(收费) coverity(收费) klocwork(收费) GProf Dot and Graphviz sikuli exe4j JBoss GlassFish Virgo Jetty cpDetector EZMorph Apache Shiro Struts Spring Hibernate iBATIS/MyBatis appfuse TopLink json neethi XML SAXON jsoup HTML Parser Java port of Mozilla charset detector(jchardet) JMX jsch * yFiles The yFiles diagramming software components are extensive class libraries that enable you to add high-quality diagramming functionality to your own software applications OpenLDAP Protobuf zip4j JFlex JavaCC sablecc Xtext antlr cglib javassist jclasslib ical4j 分词规则引擎 Drools jBPM OpenAS2 Java Native Access (JNA) mpi Java eBus JACOBA Apache POI - the Java API for Microsoft Documents iText(AGPL) aspose MVEL(Drools) OGNL(Struts) SPEL(Spring) JSP EL freemarker Velocity Aurora很开心,在使用mybatis的过程中我踩到一个坑。
在实际开发过程中,我遇到了mybatis的一个问题,觉得很有必要记录下来并分享给大家。
这个坑的具体情况是这样的:在mybatis中,OgnlOps.equal(0,"")返回的是true,这违背了我们的常识,并且会带来一些问题。
接下来,我将按照遇到问题 -> 分析问题 -> 解决问题的思路,用追踪源码的方法,对这个问题进行剖析。
同时,我会分享一下我是如何通过逆向排查的方法,通过Debug模式找到关键源码,并解决这个问题的。
本文源码:mybatis 3.5.3版本。
背景介绍和需求分析
为了简化问题,我们假设有一个订单表,表结构如下:
为了方便说明,我们假设表里面只有两条数据:订单号为的订单状态为0(关闭),订单号为的订单状态为1(开启)。
已经开发好的功能是模糊查询订单名称,接口如下:
现在需要在已有功能上添加一个根据状态过滤订单的功能。
假设某个页面有这样的一个下拉框,可以根据订单状态过滤订单数据。
准备开发
现在明确了需求,根据订单状态进行过滤。
很简单,最主要的修改地方就是对mapper.xml的修改。
开始自测,遇到问题
为了确保功能的正确性,我进行了单元测试,分别传入状态0和1,预期的结果是各自查询出一条数据。
然而,执行结果却与预期不符,status=0时查询出2条数据,status=1时查询出1条数据。
当时我意识到这个问题可能并不简单,于是决定分析原因。
分析问题
为了找到问题的根源,我首先将sql打印出来,查看最终执行的sql。
通过分析sql,我发现当status为0时,mybatis并没有给我们拼接where关键字。
逆向排查法
为了定位问题,我通过日志找到了关键源码,并使用逆向排查的方法进行追踪。
最终,我发现问题的根源在于mybatis中的OgnlOps.equal(0,"")返回了true。
关键源码
通过分析源码,我找到了导致这个问题的关键代码,并解决了这个问题。
解决问题
为了解决这个问题,我修改了mapper.xml文件中的if标签,最终实现了预期效果。
总结
这次的经历让我深刻认识到,在开发过程中遇到问题时,要善于分析、思考和总结,才能不断提升自己的技能。
Mybatis OGNL导致的并发安全问题
Mybatis是一个轻量级半自动化ORM框架,通过xml描述符或注解将对象与SQL语句结合,实现面向对象与数据库映射的简化。其最大优势在于将应用程序与Sql语句解耦,Sql语句在xml文件中定义。
OGNL(Object-Graph Navigation Language)是Mybatis中广泛使用的表达式语言,用于设置和获取Java对象属性,执行列表投影和lambda表达式。灵活的OGNL表达式在Struts2等框架中应用时,也会引入可执行漏洞风险。
某公司使用Mybatis 3.2.3版本作为数据访问层。在线业务系统运行期间,出现并发安全问题。异常表现为随机出现,构造特定OGNL表达式时不会重现,具体异常堆栈信息显示List的size()方法不可访问。此问题在测试环境未重现,占总调用次数的0.%。
编写模拟多线程并发环境下的测试代码以验证问题。并发测试代码执行后,异常在预期的并发环境下重现。异常堆栈信息指向OgnlRuntime类无法访问java.util.Collections私有成员SingletonList。
问题关键在于method作为共享变量,即java.util.Collections$SingletonList.size()方法。在第一个线程允许调用method方法,第二个线程将其设为不可访问后,第一个线程再次调用时引发MethodFailedException异常。这是典型的并发同步问题。
OGNL 2.7版本已修复此问题,Mybatis在3.3.0版本中进行了修复升级。源码已直接嵌入mybatis包中,解决了并发访问共享资源导致的异常问题。
实战Arthas:常见命令与最佳实践
本文深入介绍实战 Arthas 的常见命令与最佳实践,帮助开发者更高效地进行 Java 应用程序的诊断和调优。推荐关注 Arthas 官方文档与 Arthas Idea 插件,以加速学习与问题排查。以下是常用命令详解与使用技巧:
类命令:getstatic 用于查看类的静态属性,推荐使用 ognl 命令以获取更灵活的交互方式。
jad 命令反编译指定已加载类的源码,适用于快速验证代码是否生效。retransform 命令则用于加载外部 .class 文件,重新编译已有类,但需谨慎使用,以免影响程序稳定性。
监测排查命令包括:monitor 实现方法执行监控,stack 输出当前方法调用路径,thread 显示当前线程信息,trace 显示方法内部调用路径及耗时,trace 命令尤其适用于性能问题定位,而 tt 命令则记录方法调用的详细信息。
JVM 监控命令有:heapdump 生成堆转储文件,jfr 集成 Java Flight Recorder 收集诊断数据,memory 查看 JVM 内存信息,dashboard 实时显示系统数据,classloader 列出所有 classloader 信息,logger 查看 logger 信息,sc 查看已加载类,mbean 显示 MBean 信息,profiler 生成应用热点火焰图,vmoption 查看和更新 VM 参数,vmtool 利用 JVMTI 接口实现内存对象查询和强制 GC。
特殊命令中,-v 用于查看匹配表达式的执行结果,ognl 命令灵活执行 OGNL 表达式,options 为全局开关,help 查看命令帮助,history 列出命令历史,cls 清屏,quit 退出 Arthas。
快捷键及实用功能:使用 OGNL 语言简化表达式过滤,支持管道命令进行进一步筛选,后台异步执行检测命令,实现问题排查的灵活性。
Arthas 强大的功能和灵活性为开发者提供了强大的工具,帮助提高诊断和调优效率。探索更多 Arthas 的用法与功能,将有助于提升开发工作的便利性和效率。
为何Mybatis将Integer为0的属性解析成空串?
在一次代码审查中,同事分享了一个有趣的问题:在Mybatis中,Integer类型的age为0时,为什么会解析成空串,导致SQL语句的条件判断失效?
为了解答疑问,作者查阅了Mybatis的源码。首先,从GitHub上的最新版本下载代码,构建测试用例。在SqlSessionFactoryBuilder的构建流程中,经过XMLConfigBuilder解析配置,构建Configuration类,进而生成SqlSessionFactory和SqlSession。执行过程中,mybatis使用SimpleExecutor或CachingExecutor,后者涉及动态代理和拦截器的执行,关键在于DynamicSqlSource和IfSqlNode类。
在IfSqlNode的evaluator.evaluateBoolean方法中,使用了OGNLCache来获取值,而问题出在OGNL表达式对空字符串的处理上。在ASTNotEq类的compareWithConversion方法中,当字符串长度为0时,会被解析为0.0,这不仅影响Integer,也影响Float和Double类型。因此,问题的根源在于OGNL表达式对空字符串的解析规则。