Zeppelin의 장점은 다양한 언어를 하나의 노트북에서 실행할 수 있다는 점과 그 언어로 생성된 인스턴스를 서로 공유할 수 있다는 점이다. 전자는 인터프리터 객체를 이용해서 가능하고, 후자는 zeppelin-context 객체를 통해서 가능하다.
Zeppelin 내부에서는 후자의 기능을 object exchange 기능 또는 object share 기능이라고 부른다. 해당 기능의 사용 방법은 [공식 홈페이지](https://zeppelin.apache.org/docs/0.11.0/usage/other_features/zeppelin_context.html#usage-in-programming-language-cells)에 잘 정리되어 있다. 그러니 인터넷에서 이상한 코드 괜히 쓰지 말고 공식 홈페이지의 코드를 사용하자.
## String object
### Jdbc -> spark
```oracle sql
%oracle(saveAs=string)
SELECT
'oracle'
FROM
dual
;
```
- JDBC 쪽에서 인스턴스를 공유할 때는 인터프리터 옆에 `(saveAs=[키])` 옵션을 설정하여 공유한다.
```scala
%spark
z.get("string");
```
- Spark에서 String 인스턴스를 꺼낼 때는 `get`을 사용한다.
### Spark -> jdbc
```scala
%spark
var string2 = "spark";
z.put("string2", string);
z.get("string2");
```
- Spark에서 String 인스턴스를 공유할 때는 `put`을 사용한다.
```oracle sql
%oracle(interpolate=true)
SELECT
'{string2}' {string2}
FROM
dual
;
```
- JDBC 쪽에서 공유 받은 String 인스턴스를 사용할 때는 `{[키(=이름)]}` 으로 표시한다. 이때 인터프리터 옆에 `(interpolate=true)`로 옵션을 설정해야 한다.
## Table object
### Jdbc -> spark
```oracle sql
%oracle(saveAs=hr)
SELECT
1 AS id,
'John' AS first_name,
'Doe' AS last_name
FROM dual
UNION ALL
SELECT
2,
'Jane',
'Smith'
FROM dual
;
```
![[Pasted image 20240621134041.png]]
```scala
%spark
var hr = z.getAsDataFrame("hr")
.asInstanceOf[org.apache.spark.sql.DataFrame];
hr.show();
```
- Spark 쪽에서 공유 받은 table 인스턴스를 가져올 때는 `getAsDataFrame` 메서드를 사용한다.
- 공식 홈페이지에서는 `DataFrame`으로 바로 불러오는데, 나 같은 경우는 Object로 불러와져서 `.asInstanceOf[org.apache.spark.sql.DataFrame]`로 타입을 지정해줬다.
### Spark -> jdbc
String 인스턴스의 경우 template 방식으로 인스턴스를 전달했기 때문에 간단했지만, 테이블의 경우 그렇지 않다. Spark와 달리 oracle db는 외부 서버기 때문이다. 따라서 oracle_db에 테이블을 생성/갱신하는 방식으로 인스턴스를 공유해야 한다.
```scala
%spark
import scala.io.Source
import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.types.{StructType, StructField, StringType, DoubleType}
import org.apache.zeppelin.interpreter.InterpreterContext
```
- 기본적으로 설치되는 패키지기 때문에 따로 설치할 필요 없다.
![[Pasted image 20240621144747.png]]
```scala
%spark
val PROPERTIES = parse(
Source
.fromFile("/opt/zeppelin/conf/interpreter.json")
.getLines()
.mkString
)\"interpreterSettings"\"oracle"\"properties";
PROPERTIES
```
- 노트북 파일에 접속 정보를 저장하는 건 효율적이지도 않고 위험하다. 인터프리터 설정 JSON 파일을 읽어오자.
- `\"[키]"` 은 Java에서 `get("[키]")`, python에서 `["[키]"]` 와 같다.
![[Pasted image 20240621152633.png]]
```scala
%spark
val jdbcUrl = (PROPERTIES\"default.url"\"value").extract[String]
val jdbcUser = (PROPERTIES\"default.user"\"value").extract[String]
val jdbcPassword = (PROPERTIES\"default.password"\"value").extract[String]
val jdbcDriver = (PROPERTIES\"default.driver"\"value").extract[String]
```
- 필요한 접속 정보와 드라이버 정보를 변수로 저장한다.
```scala
%spark
df.write
.format("jdbc")
.option("url", jdbcUrl)
.option("dbtable", "[작성할 테이블]")
.option("user", jdbcUser)
.option("password", jdbcPassword)
.option("driver", jdbcDriver)
.save()
```
- 테이블을 새로 만들어야 하는 경우에는 `%oracle` 인터프리터를 이용해 먼저 테이블을 생성하고 진행한다.