鸡肋的JdbcRDD,鸡肋JdbcRDD


      今天准备将mysql的数据倒腾到RDD,很早以前就知道有一个JdbcRDD,就想着使用一下,结果发现却是鸡肋一个。       首先,看看JdbcRDD的定义:
 * An RDD that executes an SQL query on a JDBC connection and reads results.
 * For usage example, see test case JdbcRDDSuite.
 *
 * @param getConnection a function that returns an open Connection.
 *   The RDD takes care of closing the connection.
 * @param sql the text of the query.
 *   The query must contain two ? placeholders for parameters used to partition the results.
 *   E.g. "select title, author from books where ? <= id and id <= ?"
 * @param lowerBound the minimum value of the first placeholder
 * @param upperBound the maximum value of the second placeholder
 *   The lower and upper bounds are inclusive.
 * @param numPartitions the number of partitions.
 *   Given a lowerBound of 1, an upperBound of 20, and a numPartitions of 2,
 *   the query would be executed twice, once with (1, 10) and once with (11, 20)
 * @param mapRow a function from a ResultSet to a single row of the desired result type(s).
 *   This should only call getInt, getString, etc; the RDD takes care of calling next.
 *   The default maps a ResultSet to an array of Object.
 */
class JdbcRDD[T: ClassTag](
    sc: SparkContext,
    getConnection: () => Connection,
    sql: String,
    lowerBound: Long,
    upperBound: Long,
    numPartitions: Int,
    mapRow: (ResultSet) => T = JdbcRDD.resultSetToObjectArray _)

附上个例子:
package test

import java.sql.{Connection, DriverManager, ResultSet}
import org.apache.spark.rdd.JdbcRDD
import org.apache.spark.{SparkConf, SparkContext}

object spark_mysql {
  def main(args: Array[String]) {
    //val conf = new SparkConf().setAppName("spark_mysql").setMaster("local")
    val sc = new SparkContext("local","spark_mysql")

    def createConnection() = {
      Class.forName("com.mysql.jdbc.Driver").newInstance()
      DriverManager.getConnection("jdbc:mysql://192.168.0.15:3306/wsmall", "root", "passwd")
    }

    def extractValues(r: ResultSet) = {
      (r.getString(1), r.getString(2))
    }

    val data = new JdbcRDD(sc, createConnection, "SELECT id,aa FROM bbb where ? <= ID AND ID <= ?", lowerBound = 3, upperBound =5, numPartitions = 1, mapRow = extractValues)

    println(data.collect().toList)

    sc.stop()
  }
}

使用的MySQL表的数据如下:
  运行结果如下:
      可以看出:JdbcRDD的sql参数要带有两个?的占位符,而这两个占位符是给参数lowerBound和参数upperBound定义where语句的边界的,如果仅仅是这样的话,还可以接受;但悲催的是参数lowerBound和参数upperBound都是Long类型的,鸡肋的JdbcRDD - mmicky - mmicky 的博客,不知道现在作为关键字或做查询的字段有多少long类型呢?不过参照JdbcRDD的源代码,用户还是可以写出符合自己需求的JdbcRDD,这算是不幸中之大幸了。
    最近一直忙于炼数成金的spark课程,没多少时间整理博客。特意给想深入了解spark的朋友推荐一位好友的博客http://www.cnblogs.com/cenyuhai/ ,里面有不少源码博文,利于理解spark的内核。



鸡肋的出处?

参考资料baike.baidu.com/view/52148.htm#4
故事就是杨修和曹操之间的~~~~~~~~~
曹操出兵汉中进攻刘备,困于斜谷界口,欲要进兵,又被马超拒守,欲收兵回朝,又恐被蜀兵耻笑,心中犹豫不决,正碰上厨师进鸡汤。操见碗中有鸡肋,因而有感于怀。正沉吟间,夏侯敦入帐,禀请夜间口号。曹操随口答道:“鸡肋!鸡肋!”敦传令众官,都称“鸡肋!”行军主簿杨修见传“鸡肋”二字,便教随行军士收拾行装,准备归程。有人报知夏侯敦。敦大惊,遂请杨修至帐中问道:“公何收拾行装?”杨修说:“从今夜的号令来看,便可以知道魏王不久便要退兵回国,鸡肋,吃起来没有肉,丢了又可惜。现在,进兵不能胜利,退兵恐人耻笑,在这里没有益处,不如早日回去,明日魏王必然班师还朝。所以先行收拾行装,免得临到走时慌乱。”夏侯敦说:“您真是明白魏王的心事啊!”就也收拾行装。于是军寨中的诸位将领没有不准备回去的事物的。曹操得知这个情况后,传唤杨修问他,杨修用鸡肋的意义回答。曹操大怒:“你怎么敢造谣生事,动乱军心!”便喝令刀斧手将杨修推出去斩了,将他的头颅挂于辕门之外。
 

鸡肋事件的问题

既然上面的朋友说出原文了,我来说一下我的看法好了

其实曹操一直对杨修的聪明嫉妒,之前的猜石碑上之谜曹操甚至比杨修晚了三十里才猜的出来,可见杨修的聪明。但曹操不是一个肚量大到可以容下这份聪明的人,再加上他的猜忌心相当重,杨修在他心里自然像刺一样,欲拔除而后快。

---------------------------以上是事情潜在的原因--------------------

那时曹操要不要退兵曹操其实是相当两难的,因为如此他才会思考很久,说出鸡肋一辞,杨修听了之后就自作主张叫官兵收拾行装,一来这样的感觉就像你和别人说话,别人还没说出来你就马上说出对方接下来要说什麼,即使是猜对,别人一定会觉得不大爽,二来曹操再怎麼说也是军队的最高领导者,他在说鸡勒的时候,一定还在犹疑,虽然退兵机率大,但也还没下决定,杨修却叫军官先收拾行装,如果曹操不打算退兵呢,那要怎麼办。杨修似乎已经聪明到一直想要表现他的聪明,完全不懂的内敛。三来就是曹操本来就对杨修怀恨在心了,自然籍这个机会把杨修宰了。

曹操说鸡勒时只是触景生情,所以也是应合他内心的想法
参考资料:自已的感想
 

相关内容