当前位置: 首页 > 编程日记 > 正文

搞定MyBatis

对于从事 Java EE 的开发人员来说,iBatis 是一个再熟悉不过的持久层框架了,在 Hibernate、JPA 这样的一站式对象 / 关系映射(O/R Mapping)解决方案盛行之前,iBaits 基本是持久层框架的不二选择。即使在持久层框架层出不穷的今天,iBatis 凭借着易学易用、轻巧灵活等特点,也仍然拥有一席之地。尤其对于擅长 SQL 的开发人员来说,iBatis 对 SQL 和存储过程的直接支持能够让他们在获得 iBatis 封装优势的同时而不丧失 SQL 调优的手段,这是 Hibernate/JPA 所无法比拟的。具体而言,使用 iBatis 框架的主要优势主要体现在如下几个方面:

首先,iBatis 封装了绝大多数的 JDBC 样板代码,使得开发者只需关注 SQL 本身,而不需要花费精力去处理例如注册驱动,创建 Connection,以及确保关闭 Connection 这样繁杂的代码。

其次,iBatis 可以算是在所有主流的持久层框架中学习成本最低,最容易上手和掌握的框架。虽说其他持久层框架也号称门槛低,容易上手,但是等到你真正使用时会发现,要想掌握并用好它是一件非常困难的事。在工作中我需要经常参与面试,我曾听到过很多位应聘者描述,他们所在的项目在技术选型时选择 Hibernate,后来发现难以驾驭,不得不将代码用 JDBC 或者 iBatis 改写。

iBatis 自从在 Apache 软件基金会网站上发布至今,和他的明星兄弟们(Http Server,Tomcat,Struts,Maven,Ant 等等)一起接受者万千 Java 开发者的敬仰。然而在今年六月中旬,几乎是发布 3.0 版本的同时,iBatis 主页上的一则 “Apache iBATIS has been retired” 的声明在社区引起了一阵不小的波澜。在 Apache 寄居六年之后,iBatis 将代码托管到 Google Code。在声明中给出的主要理由是,和 Apache 相比,Google Code 更有利于开发者的协同工作,也更能适应快速发布。于此同时,iBatis 更名为 MyBatis。

从 iBatis 到 MyBatis,不只是名称上的变化,MyBatis 提供了更为强大的功能,同时并没有损失其易用性,相反,在很多地方都借助于 JDK 的泛型和注解特性进行了简化。iBatis 确实该退休了,因为一个更为出色的继任者经过 10 个 Beta 版本的蜕变已然出现在我们的面前。

本文将主要针对 MyBatis 和 iBatis 的变化之处进行讨论,以便于读者顺利从 iBatis 向 MyBatis 过渡。

由一个  MyBatis  示例开始

如果读者接触过一些常用的 Java EE 框架,应该都知道这些框架需要提供一个全局配置文件,用于指定程序正常运行所需的设置和参数信息。而针对常用的持久层框架而言(Hibernate、JPA、iBatis 等),则通常需要配置两类文件:一类用于指定数据源、事务属性以及其他一些参数配置信息(通常是一个独立的文件,可以称之为全局配置文件);另一类则用于指定数据库表和程序之间的映射信息(可能不止一个文件,我们称之为映射文件)。MyBatis 也不例外,虽然其中的一部分可以通过注解的形式进行,但是这两部分内容本身仍是必不可少的。

根据 iBatis 的习惯,我们通常把全局配置文件命名为 sqlMapConfig.xml,文件名本身并没有要求,在 MyBatis 中,也经常会将该文件命名为 Configuration.xml (读完全文后读者也许会发现,在 iBatis 中经常出现的 “sqlMap” 在 MyBatis 中被逐渐淡化了,除了此处,还比如 iBatis 配置文件的根元素为 ,指定映射文件的元素为 ,以及 SqlMapClient 等等,这个变化正说明,iBatis 仅是以 SQL 映射为核心的框架,而在 MyBatis 中多以 Mapper、Session、Configuration 等其他常用 ORM 框架中的名字代替,体现的无非是两个方面:首先是为了减少开发者在切换框架所带来的学习成本;其次,MyBatis 充分吸收了其他 ORM 框架好的实践,MyBatis 现在已不仅仅是一个 SQL 映射框架了)。在全局配置文件中可以配置的信息主要包括如下几个方面:

  • properties --- 用于提供一系列的键值对组成的属性信息,该属性信息可以用于整个配置文件中。
  • settings --- 用于设置 MyBatis 的运行时方式,比如是否启用延迟加载等。
  • typeAliases --- 为 Java 类型指定别名,可以在 XML 文件中用别名取代 Java 类的全限定名。
  • typeHandlers --- 在 MyBatis 通过 PreparedStatement 为占位符设置值,或者从 ResultSet 取出值时,特定类型的类型处理器会被执行。
  • objectFactory --- MyBatis 通过 ObjectFactory 来创建结果对象。可以通过继承 DefaultObjectFactory 来实现自己的 ObjectFactory 类。
  • plugins --- 用于配置一系列拦截器,用于拦截映射 SQL 语句的执行。可以通过实现 Interceptor 接口来实现自己的拦截器。
  • environments --- 用于配置数据源信息,包括连接池、事务属性等。
  • mappers --- 程序中所有用到的 SQL 映射文件都在这里列出,这些映射 SQL 都被 MyBatis 管理。

上面提及的大多数元素都不是必需的,通常 MyBatis 会为没有显式设置的元素提供缺省值。一个简单的全局配置文件示例如下

清单  1.  简单的全局配置文件示例

<?xml version="1.0" encoding="UTF-8" ?>

<!--iBatis 和 MyBatis 的全局配置文件使用不同的 DTD 约束,在将应用由

iBatis 升级至 MyBatis 时需要注意(两者的映射文件 DTD 约束也不相同)-->

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<!-- 配置数据源相关的信息 -->

<environments default="demo">

<environment id="demo">

<transactionManager type="JDBC"/>

<dataSource type="POOLED">

<property name="driver" value= … />

<property name="url" value= … />

<property name="username" value="root"/>

<property name="password" value="root"/>

</dataSource>

</environment>

</environments>

<!-- 列出映射文件 -->

<mappers>

<mapper resource="footmark/mybatis/demo/UserInfoMapper.xml"/>

</mappers>

</configuration>

有了这些信息,MyBatis 便能够和数据库建立连接,并应用给定的连接池信息和事务属性。MyBatis 封装了这些操作,最终暴露一个 SqlSessionFactory 实例供开发者使用,从名字可以看出来,这是一个创建 SqlSession 的工厂类,通过 SqlSession 实例,开发者能够直接进行业务逻辑的操作,而不需要重复编写 JDBC 相关的样板代码。根据全局配置文件生成 SqlSession 的代码如下:

Reader reader = Resources.getResourceAsReader("Configuration.xml");

SqlSessionFactory sqlSessionFactory =

new SqlSessionFactoryBuilder().build(reader);

SqlSession sqlSession = sqlSessionFactory.openSession();

可以把上面的三行代码看做是 MyBatis 创建 SqlSession 的样板代码。其中第一行代码在类路径上加载配置文件,Resources 是 MyBatis 提供的一个工具类,它用于简化资源文件的加载,它可以访问各种路径的文件,不过最常用的还是示例中这种基于类路径的表示方式。如果读者对 Hibernate 有所了解,一定会发现 MyBatis 不论是使用风格还是类名都和 Hibernate 非常相像,笔者曾今多次在国内外 Java 社区看到有人说 MyBatis 在向 Hibernate/JPA 靠拢。暂且不论这是否属实,持久化技术在经过一番蓬勃的竞争和发展,最终在社区形成统一的认识并被广泛接受,这对开发者而言未必不是一件好事,MyBatis 在这一点上只是向事实上的标准靠近了一步。

在完成全局配置文件,并通过 MyBatis 获得 SqlSession 对象之后,便可以执行数据访问操作了。对于 iBatis/MyBatis 而言,要执行的操作其实就是在映射文件中配置的 SQL 语句。两者的配置基本相同,如下所示:

清单  2.  在映射文件中配置  SQL  语句

<?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="mybatis.demo.UserInfoMapper">

<select id="selectUser" parameterType="int"

resultType="mybatis.demo.UserInfo">

select * from UserInfo where userid =#{userid}

</select>

</mapper>

在 iBatis 中,namespace 不是必需的,且它的存在没有实际的意义。在 MyBatis 中,namespace 终于派上用场了,它使得映射文件与接口绑定变得非常自然。关于接口绑定,后面会有篇幅专门描述。使用 SqlSession 执行 SQL 的方式如下:


清单  3.  使用  SqlSession  执行映射文件中配置的  SQL  语句

try

{

UserInfo userinfo = (UserInfo) sqlSession.selectOne

("mybatis.demo.UserInfoMapper.getUser", 2);

System.out.println(userinfo);

} finally

{

sqlSession.close();

}

需要注意的是,SqlSession 的使用必需遵守上面的格式,即在 finally 块中将其关闭。以保证资源得到释放,防止出现内存泄露!

以上就是一个简单而完整的 MyBatis 程序。其中涉及了全局配置文件,映射文件,构建 SqlSession 对象,执行数据访问操作等四个步骤。下面将针对除构建 SqlSession 对象之外的三块内容进行分解。

MyBatis  全局配置文件的改变

MyBatis 全局配置文件的各主要元素基本和 iBatis 相同,只是在用法和个别名称上做了调整。元素的意义就不再描述,下面主要讲述针对 iBatis 和 MyBatis 配置文件的主要区别之处。

首先,两个版本的 DTD 约束不同,MyBatis 的 DTD 文件已经包含在发布包下的 mybatis-3.0.x.jar 包中。这直接影响到的是,iBatis 配置文件的根元素是 <sqlMapConfig>,而 MyBatis 使用的是 <configuration>。

其次,<settings> 的用法发生了改变,之前的格式为:

清单  4.    iBatis  中设置属性的方式

<settings props1="value1" props2="value2"… />

要设置的属性直接以键值对的形式作为 <settings> 的属性。而在 MyBatis 中调整为略显复杂但却更有条理的方式:


清单  5.    MyBatis  中设置属性的方式

<settings>

<setting name="props1" value="value1"/>

<setting name="props2" value="value2"/>

……

</settings>

另外,之前配置事务管理器和数据源的方式如下:


清单  6.    iBatis  中配置事务管理器和数据源的方式

<transactionManager type="JDBC" >

<dataSource type="SIMPLE">

<property name="JDBC.Driver" value="${driver}"/>

<!-- 其他数据源信息省略 -->

</dataSource>

</transactionManager>

在 MyBatis 中调整为如下的方式:


清单  7.    MyBatis  中配置事务管理器和数据源的方式

<environments default="demo">

<environment id="demo">

<transactionManager type="JDBC"/>

<dataSource type="POOLED">

<property name="JDBC.Driver" value="${driver}"/>

<!-- 其他数据源信息省略 -->

</dataSource>

</environment>

</environments>

通过 <environments> 来进行数据源管理,主要是为了简化在多套数据源配置之间的切换,比如开发和发布使用不同的配置。

最后,在 iBatis 中指定映射文件的方式如下:


清单  8.    iBatis  中指定映射文件的方式

<sqlMap resource=... />

<sqlMap resource=... />

<sqlMap resource=... />

在 MyBatis 中调整为如下方式:


清单  9.    MyBatis  中指定映射文件的方式

<mappers>

<mapper resource=... />

<mapper resource=... />

</mappers>

上面的这些调整,主要出发点其实并不是使得 MyBatis 功能更为强大,而是使配置更为合理,让开发者更容易阅读和理解。

到目前为止,我们主要讨论了 XML 形式的全局配置,其实这也不是唯一选择,MyBatis 还提供了通过代码来进行配置的方式:


清单  10.    MyBatis  中使用代码进行配置

DataSource ds = …… // 获取一个 DataSource

TransactionFactory txFactory = new JdbcTransactionFactory();

Environment env = new Environment("demo", txFactory, ds);

Configuration cfg = new Configuration(env);

cfg.addMapper(UserInfoMapper.class);

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(cfg);

结合前面的配置文件,很容易理解这段代码的意思,故不再赘述。不过,需要注意的是 Configuration 的 addMapper() 方法,该方法的参数通常是一个接口,可以在接口里面定义若干方法,在方法上使用注解来指定映射的 SQL 语句。一个典型的接口定义以及对应的数据访问方法如下:


清单  11.  将映射的  SQL  语句与接口中的方法绑定

// 映射 SQL 绑定接口

public interface UserInfoMapper

{

@Select("select * from userinfo where userid = #{userid}")

public UserInfo getUserInfo(int userid);

}

// 接口绑定对应的数据访问方法

try

{

//UserInfo userinfo = (UserInfo) sqlSession.selectOne

("mybatis.demo.UserInfoMapper.selectUser", 2);

UserInfoMapper userinfoMapper =

sqlSession.getMapper(UserInfoMapper.class);

UserInfo userinfo = userinfoMapper.getUserInfo(1);

System.out.println(userinfo);

} finally

{

sqlSession.close();

}

MyBatis  映射文件的改变

MyBatis 针对映射文件进行格式调整的地方很多,但大部分仅仅只是名称上的变化,现代的 IDE 都支持联想功能,可以很方便的获取到当前位置可以有哪些元素、哪些属性等。所以这基本不会给开发者造成什么麻烦。

针对映射文件,首先是一系列的属性名称的改变,这些仅仅是名称的改变,用法和含义并没有发生变化:

  • 和全局配置文件一样,由于 DTD 约束发生变化,根元素也由原来的 <sqlMap> 调整为 <mapper>。
  • <select> 等元素的 parameterClass 属性改为了 parameterType 属性。
  • <select> 等元素的 resultClasss 属性改为了 resultType 属性。
  • <parameterMap> 等元素的 class 属性改为了 type 属性。
  • <result> 元素的 columnIndex 属性被移除了。
  • 嵌套参数由 #value# 改为了 #{value}。
  • <parameter> 等元素的 jdbcType 属性取值中,原来的 "ORACLECURSOR" 取值改为了现在的 "CURSOR","NUMBER" 取值改为了 "NUMERIC"。

iBatis/MyBatis 对存储过程的支持一直是值得称道的。之前通过使用 <procedure> 元素进行存储过程的定义,示例如下:


清单  12. iBatis  中调用存储过程的方式

<procedure id="getValues" parameterMap="getValuesPM">

{ ? = call pkgExample.getValues(p_id => ?) }

</procedure>

在 MyBatis 中,<proccedure> 元素已经被移除,通过 <select>、<insert> 和 <update> 进行定义:


清单  13. MyBatis  中调用存储过程的方式

如上所示,通过 statementType 属性将该语句标识为存储过程而非普通 SQL 语句。

代码层面的改变

通过前面的示例可以看出,MyBatis 在编码中的最大的改变就是将一个最常用的 API 由 SqlMapClient 改为了 SqlSessionFactory。另外,类型处理器接口也由原来的 TypeHandlerCallback 改为了 TypeHandler。最后 DataSourceFactory 也进行了调整,移动到 org.apache.ibatis.datasource 包下,其中的方法也作了微调。总之,代码层面公开的部分改动较少,不会给开发者造成较大的移植成本。

转载于:https://www.cnblogs.com/boyangx/p/4133673.html

相关文章:

6-6.用HLSL定义点光源

6-6.用HLSL定义点光源问题直到现在&#xff0c;你已经用定向光照亮你的场景&#xff0c;它对添加阳光到3D世界很有用。常常&#xff0c;你也将需要一个单点光照&#xff0c;例如手电筒或爆炸。这种光源叫点光源。方案从你的XNA项目传递点光源的3D位置到你的XNA effect。为每个顶…

2018 JVM 生态报告:79% 的 Java 开发者使用 Java 8

百度智能云 云生态狂欢季 热门云产品1折起>>> 2018 JVM 生态调查报告已于近日发布&#xff0c;该报告由 Snyk 和 The Java Magazine&#xff08;Oracle 的双月刊&#xff09;联合推出&#xff0c;旨在了解 JDK 的实现、工具、平台和应用方面的前景。基于超过 10200 …

广度优先搜索(BFS)模板

伪代码 void BFS(int S){queue<int> q;q.push(s);while(!q.empty()){取出队首元素top;访问队首元素top;将队首元素出队;将top的下一层结点中未曾入队的结点全部入队&#xff0c;并设置为已入队;} } 说明 1. 定义队列q&#xff0c;并将起点s入队 2. 写一个while循环&a…

static关键字和内存使用

1 static静态的&#xff0c;用来修饰属性&#xff0c;方法&#xff0c;代码块&#xff0c;内部类 2 当其中一个变量对此属性进行修改&#xff0c;会导致其他对象对此属性的一个调用 vs 实例变量&#xff1a;对象各有一套副本 3 静态变量和方法随着类的加载而加载&#xff0c;可…

转载:用 Tomcat 和 Eclipse 开发 Web 应用程序

原文地址:http://www.ibm.com/developerworks/cn/opensource/os-eclipse-tomcat/所需的组件 Eclipse V3.2 Callisto 集成开发环境 (IDE) 包括了用于 Web 开发及与服务器集成的工具。所以&#xff0c;除了软件开发工具箱 (SDK) 之外&#xff0c;只需安装 Eclipse 和 Apache Tomc…

【学习——字符串】字符串之一网打尽quq

学弟lyh上午讲课&#xff0c;喜闻乐见的制胡窜 一上午讲惹KMP&#xff0c; manachar&#xff0c; trie树&#xff0c; AC自动机 orz 例题都是洛咕咕上的&#xff0c; 贴一下&#xff08;督促自己不要咕 AC自动机不会qaq&#xff08;并且没有学的意向 manachar 没写过 P4555 […

分别用BFS和DFS求给定的矩阵中“块”的个数

目录 背景介绍 BFS实现 基本思想 获取相邻位置元素技巧 BFS函数 DFS实现 基本思想 DFS函数 完整代码 背景介绍 背景 给出一个mxn的矩阵&#xff0c;矩阵中的元素为0或1。称位置(x,y)与其上下左右四个位置(x,y1),(x,y-1),(x-1,y),(x1,y)是相邻的。如果矩阵中有若干(…

[Python_7] Python Socket 编程

0. 说明 Python Socket 编程 1. TCP 协议 [TCP Server] 通过 netstat -ano 查看端口是否开启 # -*-coding:utf-8-*-"""TCP 协议的 Socket 编程&#xff0c;Server 端Server 端绑定到指定地址&#xff0c;监听特定的端口&#xff0c;接受发来的连接请求 "&q…

2014.12.01 B/S之windows8.1下安装IIS

1、打开 控制面板——程序——程序和功能——启用或关闭windows功能 2、找到Internet信息服务 3、等待安装完毕即可 4、控制面板——系统和安全——管理工具——Internet Information Services (IIS)管理器 默认路径为 C:\inetpub\wwwroot 路径更改以后记得更改权限。 转载于:h…

[分享]C# 获取Outlook帐号和密码

[分享]C# 获取Outlook帐号和密码http://www.vjsdn.com/bbs/bbsTopicDetails.aspx?pid108281214 转载于:https://www.cnblogs.com/vjsdn/archive/2009/09/26/1574341.html

BFS:走出迷宫并输出最小步数

目录 背景 描述 例子 思路 完整代码 收获总结 背景 描述 给定一个n*m大小的迷宫&#xff0c;其中*代表不可通过的墙壁&#xff0c;而“.”代表墙壁&#xff0c;S表示起点&#xff0c;T代表重点。移动过程中&#xff0c;如果当前位置是(x,y)(下标从0开始)&#xff0c;且…

人工智能和机器学习领域有哪些有趣的开源项目

人工智能和机器学习领域有哪些有趣的开源项目&#xff1f;投递人 itwriter 发布于 2014-12-02 11:21 评论(0) 有20人阅读 原文链接 [收藏] 本文简要介绍了 10 款 Quora 上网友推荐的 人工智能和机器学习领域方面的开源项目。 GraphLab GraphLab 是一种新的面向机器学习…

复杂度归纳--小结

一、复杂度分析的4个概念1.最坏情况时间复杂度&#xff1a;代码在最理想情况下执行的时间复杂度。2.最好情况时间复杂度&#xff1a;代码在最坏情况下执行的时间复杂度。3.平均时间复杂度&#xff1a;用代码在所有情况下执行的次数的加权平均值表示。4.均摊时间复杂度&#xff…

KDE社区:首个KDialogue正式开放

今天KDE社区与“People Behind KDE” 合作推出一个非常有意思的栏目&#xff0c;叫作KDialogue。 关于KDialogue&#xff0c;有点类似头脑风暴。简言之就是成员向社区发起关于KDE的话题&#xff08;或某一问题&#xff09;&#xff0c;然后KDE的开发者会被邀请参与这个话题。KE…

1091 Acute Stroke 需再做

这是BFS的典型应用场景&#xff1a;求给定矩阵中块(由相邻的点组成)的大小之和。不同的是这一次是三维。 判断是否邻接的依据是是否有公共边&#xff0c;还是可以用上增量数组的技巧 int X[6] {0,0,1,-1,0,0};//增量数组 int Y[6] {1,-1,0,0,0,0}; int Z[6] {0,0,0,0,1,-…

Ext UI 第一步

Code//Ext.onReady(function(){ var _panelnew Ext.Panel({ renderTo:Ext.getBody(), title:"XXX" });});空面板 加按钮方法:addButton(String/Object _config,Function _handler,Object _scope):添加一个按钮对象到面板Codevar loadfunction(){ …

深入浅出 Java Concurrency (29): 线程池 part 2 Executor 以及Executors[转]

Java里面线程池的顶级接口是Executor&#xff0c;但是严格意义上讲Executor并不是一个线程池&#xff0c;而只是一个执行线程的工具。真正的线程池接口是ExecutorService。 下面这张图完整描述了线程池的类体系结构。 首先Executor的execute方法只是执行一个Runnable的任务&…

WPF的消息机制(二)- WPF内部的5个窗口之隐藏消息窗口

原文:WPF的消息机制&#xff08;二&#xff09;- WPF内部的5个窗口之隐藏消息窗口版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/powertoolsteam/article/details/6109036 目录 WPF的消息机制&#xff08;一&#xff09;-让…

二叉树:root==NULL和*root==NULL的区别

root NULL 通常为查找的递归边界&#xff0c;说明当前结点不存在。 *root NULL 表明当且结点存在&#xff0c;但是内容不存在。是创建一棵二叉树时的初始化操作。 前者常用得多。

Intent携带额外的数据的方法

1、putExtras(Bundle data):向Intent中放入需要“携带”的数据。2、putXxx(String key,Xxx data):向Bundle放入Int、Long等各种类型的数据。3、putSerializable(String key,Serializable data):向Bundle中放入一个可序列化的对象。转载于:https://www.cnblogs.com/ahao214/p/41…

为什么 JavaScript 的私有属性使用 # 符号

这几天 JavaScript 的私有属性又成为了前端社区热议的话题。原因很简单&#xff0c;这家伙长这样&#xff1a; 惊不惊喜&#xff01;意不意外&#xff01; 而且 TC39 委员会以及对此达成了一致意见&#xff0c;并且该提案已经进入了 stage 3。在 es 规范阶段 stage 3 是候选提案…

程序员感悟----路该怎么走

有一句话我一直记得很深&#xff0c;“当人深处迷茫之中时早已不再迷茫”。很绕很矛盾的话&#xff0c;也可能有人听到后会马上跳脚喊&#xff0c;我一直迷茫怎么还是迷茫呢&#xff1f;呵呵。静一下想一下再喊。 大家都这么大了&#xff0c;路该怎么走&#xff0c;你知道么&am…

1020 Tree Traversals

1. 有这样一个经典结论&#xff1a;中序序列可以和先序序列、后序序列、层序序列中的任意一个来构建唯一的二叉树&#xff0c;而后三者两两搭配或者三个一起上都不行。因为从本质上来说&#xff0c;后三者都只提供根结点&#xff0c;只有通过中序才能区分左右子树。 2. 本题用…

Android添加权限大讲解

http://bbs.51cto.com/thread-1096739-1.html 对于新手来说&#xff0c;最烦恼的不是如何从网上下载到安卓项目&#xff0c;而是下载到的安卓项目不知道如何添加权限和要添加哪些权限。现在就针对安卓的权限来讲解这些权限应该具体用在什么地方 首先在项目下找到 AndroidManife…

经典算法之选择排序

问题 有一数组a&#xff0c;长度为n&#xff0c;把数组中的元素从大到小重新排列 思路 选择排序十分容易理解。可以理解为有一个盘子&#xff0c;里面装着很多钻石&#xff0c;你可以从里面拿钻石&#xff0c;但一次只可以拿一颗。第一次你当然会拿最大的出来了&#xff0c;第二…

PHP 读写数据库出现中文乱码问题

一、我在PHP读写数据库时&#xff0c;出现中文乱码问题的解决方案&#xff1a; 1、加入一句话就行了&#xff1a; mysql_query("set character set utf8");//读库 mysql_query("set names utf8");//写库 //其实读写都可以只加入 m…

1086 Tree Traversals Again

1. 这题的核心部分是&#xff0c;根据二叉树的先序序列和中序序列求后序序列。等于是在1020 Tree Traversals这一题的基础上&#xff0c;把怎么得到先序序列和中序序列的难度加大了&#xff0c;不是直接给出&#xff0c;而是要曲折一点得到。 2. 先序序列的得到就是把Push后面…

Eclipse的Java工作集和多工程构建路径

一、Java工作集&#xff1a; Eclipse有一个小功能&#xff0c;就是创建Java Working Set。它的作用是解决Package Explorer窗格中创建很多工程时出现拥挤的麻烦。 在创建&#xff08;New对话框&#xff09;时可以加入原来存在的Java工程。创建完后&#xff0c;在左方Package Ex…

ORA-08002: sequence MySeq.currval is not yet defined in this session

2019独角兽企业重金招聘Python工程师标准>>> MySeq.currval 从你的会话中的MySeq序列获取最新的值并返回&#xff0c;因此&#xff0c;它未曾被定义&#xff0c;直到你在你的会话中至少一次用MySeq.NEXTVAL获取一个值。CURRVAL的目的是让你在你的代码中使用某个序列…

【Vegas原创】exp时,ORA-00932: 数据类型不一致解决方法

现象&#xff1a; EXP-00056: 遇到 ORACLE 错误 932 ORA-00932: 数据类型不一致: 应为 BLOB, CLOB, 但却获得 CHAR EXP-00000: 导出终止失败 解决方法&#xff1a; 运行2个脚本&#xff1a; SQL> ?/rdbms/admin/catmetx.sql SQL> ?/rdbms/admin/utlrp.sql 转载于:htt…