120
輕鬆學Google的雲端開發 - Google App Engine入門 Simon Su & Sunny Hu JCConf 2015 http://goo.gl/X8YY73

JCConf 2015 - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Embed Size (px)

Citation preview

Page 1: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

輕鬆學Google的雲端開發 - Google App Engine入門

Simon Su & Sunny HuJCConf 2015

http://goo.gl/X8YY73

Page 2: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Githubhttps://github.com/peihsinsu/JCConf2015-GAE-Workshop

Page 3: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 4: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

We are QNAPer, Now!

Page 5: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

https://www.facebook.com/groups/GCPUG.TW/

https://plus.google.com/u/0/communities/116100913832589966421

Google Cloud Platform User Group Taiwan我們是Google Cloud Platform Taiwan User Group。在Google雲端服務在台灣地區展露頭角之後,

有許多新的服務、新的知識、新的創意,歡迎大家一起分享,一起了解 Google雲端服務...

GCPUG透過網際網路串聯喜好Google Cloud的使用者,分享與交流使用 GCP的點滴鑑驗。如果您

是Google Cloud Platform的初學者,您應該來聽聽前輩們的使用經驗;如果您是 Google Cloud Platform的Expert,您應該來分享一下寶貴的經驗,並與更多高手互相交流;如果您還沒開始用

Google Cloud Platform,那麼您應該馬上來聽聽我們是怎麼使用 Google Cloud的!

Page 6: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 7: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●●●●●

Page 8: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Compute

Compute Engine

App Engine Container Engine

Storage

Cloud Storage

Cloud SQL Cloud Datastore

App Services

Cloud EndpointsPrediction API Translate APIBigQuery

Big Data

Pub/Sub Dataflow Bigtable

Page 9: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

https://console.developers.google.com/project?utm_referrer=blank

Create your own project

Page 10: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

https://console.cloud.google.com/freetrial

Free USD$300 Trail

Page 11: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 13: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Eclipse version Installation instructions Direct plugin link

Eclipse 4.4 (Luna) Plugin for Eclipse 4.4 (Luna) https://dl.google.com/eclipse/plugin/4.4

Eclipse 4.3 (Kepler) Plugin for Eclipse 4.3 (Kepler) https://dl.google.com/eclipse/plugin/4.3

Eclipse 3.8/4.2 (Juno) Plugin for Eclipse 3.8/4.2 (Juno) https://dl.google.com/eclipse/plugin/4.2

Page 14: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 15: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●

Page 16: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 17: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Java source code

Web source code

GAE setting

Servlet setting

Page 18: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 19: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●●

Page 20: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 21: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 22: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Page 23: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●

●●

Page 24: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 25: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

基本設定

Page 26: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

<async-session-persistence enabled="true" />

Page 27: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 28: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 29: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 30: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 31: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Page 32: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

CallbackPage

ResultPage

extends: AbstractAppEngineAuthorizationCodeServlet

extends: AbstractAppEngineAuthorizationCodeCallbackServlet

1

2

34

Page 33: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

整合

Page 34: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

web.xml

Page 35: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 36: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

取得

/get-application-id.jsp

Page 37: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 38: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 39: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●●

Page 40: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●

Page 41: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Googler’s wayAppEngine

Traditional Web applications

Web application framework

AppEngine(Java, Python, Go, PHP)

Java, Perl/CGI, PHP, Ruby, Python...

Persistent storageNoSQL

● Datastore● Cloud SQL

RDBMS● MySQL● PostgreSQL● SQL Server● Oracle

Page 42: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Datastore RDBMS

Query language flexibility

SQL-like query language● Limited to simple

filter and sort

Full support of SQL● Table JOIN● Flexible filtering● Subquery

Reliability and Scalability

Highly scalable and reliable

Hard to scale

Page 43: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●○○○

●○○

Page 44: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Datastore RDBMS

Category of object Kind Table

One entry/object Entity Row

Unique identifier of data entry Key Primary Key

Individual data Property Field

Page 45: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Property

Property

Property

PostEntry User

Kinds

Key: blog-1234user: [email protected]: xxxxxxdate: 3/1/2014

Key: [email protected]: [email protected]: [[email protected], [email protected]]followers:

Key: [email protected]: [email protected]:followers: [[email protected]]

Entities

Keys

Page 46: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

DatastoreService datastore =

DatastoreServiceFactory.getDatastoreService();

Entity employee = new Entity("Employee");

employee.setProperty("name", "Simon Su");

employee.setProperty("hireDate", new Date());

Key empKey = datastore.put(employee);

# DatastoreExample.java

Page 47: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

// Use email as key when creating entity

Entity employee = new Entity("Employee", "work-id-D001");

datastore.put(employee);

// Later, use the key to retrieve the entity

Key userKey = KeyFactory.createKey("Employee", "work-id-D001");

Entity user = datastore.get(userKey);

# DatastoreExample.java

Page 48: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

DatastoreService ds = DatastoreServiceFactory.getDatastoreService();

Key key = KeyFactory.createKey("User", "[email protected]");

try {

Entity ent = ds.get(key);

out.print(ent);

Map m = ent.getProperties();

out.println(m.toString());

} catch (EntityNotFoundException e) {

e.printStackTrace();

}

Page 49: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Query query = new Query("Person");

Query.Filter nameFilter = new Query.FilterPredicate( "name", FilterOperator.EQUAL, "John");

query.setFilter(nameFilter);

PreparedQuery results = datastore.prepare(query);

# DatastoreExample.java

Page 50: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Query q = new Query("Person");

Query.Filter filter1 = new FilterPredicate(...);

Query.Filter filter2 = new FilterPredicate(...);

Query.Filter comboFilter =

CompositeFilterOperator.and(filter1, filter2);

q.setFilter(comboFilter);

q.addSort("name");

# DatastoreExample.java

Page 51: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Query query = new Query("Kind");query.setAncestor(parentKey);

Page 52: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

● Manual configure:WEB-INF/datastore-indexes.xml

● System generated: WEB-INF/appengine-generated/datastore-indexes-auto.xml

Page 53: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

<?xml version="1.0" encoding="utf-8"?><datastore-indexes> <datastore-index kind="Widget"> <property name="x" direction="asc" /> <property name="date" direction="asc" /> </datastore-index> <datastore-index kind="Widget"> <property name="y" direction="asc" /> <property name="date" direction="asc" /> </datastore-index></datastore-indexes>

<?xml version="1.0" encoding="utf-8"?><datastore-indexes autoGenerate="true"></datastore-indexes>

Page 54: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 55: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 56: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●

Page 57: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Query for: first_name = Cathy last_name > Able last_name < Mooney

Query for: first_name > Cathy last_name > Able

Page 58: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Query for: first_name = Cathy last_name > Able sort by last_name Query for:

last_name > Able sort by first_name

Page 59: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService()Transaction txn = datastore.beginTransaction();try { Key ekey = KeyFactory.createKey("Employee", "Joe"); Entity employee = datastore.get(ekey);

/*... reading and writing on employee ...*/

datastore.put(employee); txn.commit();

} finally { if (txn.isActive()) { txn.rollback(); }}

# DatastoreExample.java

Page 60: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

● Datastore basic● Datastore operation● Restrictions● Transaction

Page 61: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

DatastoreService ds = DatastoreServiceFactory.getDatastoreService();

Entity job = new Entity("User", "[email protected]");

job.setProperty("name", "Simon Su");

job.setProperty("start", "20140103");

job.setProperty("create", new Date());

try {

Key k = ds.put(job);

out.println("Done..." + k.getId());

} catch (Exception e) {

e.printStackTrace();

}

User

simonsu@...

File: DatastoreExample.java

Page 62: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

DatastoreService ds = DatastoreServiceFactory.getDatastoreService();

Key userKey = KeyFactory.createKey("User", "[email protected]");

Entity job = new Entity("Jobs", userKey);

job.setProperty("name", "engineer");

job.setProperty("start", new Date());

try {

Key k = ds.put(job);

out.println("Done..." + k.getId());

} catch (Exception e) {

e.printStackTrace();

}

User

Jobs

File: DatastoreExample2.java

Page 63: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

DatastoreService ds = DatastoreServiceFactory.getDatastoreService();

Query q = new Query("Jobs");

Key ancestor = KeyFactory.createKey("User", "[email protected]");

q.setAncestor(ancestor);

PreparedQuery results = ds.prepare(q);

Iterator iter = results.asIterable().iterator();

while(iter.hasNext()) {

Entity ent = (Entity) iter.next();

out.println(ent);

}

File: DatastoreExample2.java

Page 64: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 65: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 66: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●●

Page 67: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Memcache

Page 68: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●●●

Page 69: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

MemcacheService cache = MemcacheServiceFactory.getMemcacheService();

cache.setErrorHandler(

ErrorHandlers.getConsistentLogAndContinue(Level.INFO));

// read from cache

value = (byte[]) cache.get(key);

// save to cache

if (value == null) {

// ........

cache.put(key, value);

}

# DatastoreExample.java

Page 70: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

// Using the asynchronous cache

AsyncMemcacheService asyncCache =

MemcacheServiceFactory.getAsyncMemcacheService();

asyncCache.setErrorHandler(

ErrorHandlers.getConsistentLogAndContinue(Level.INFO));

// read from cache

Future<Object> futureValue = asyncCache.get(key);

// ... do other work in parallel to cache retrieval

value = (byte[]) futureValue.get();

Page 71: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

if (value == null) {

// get value from other source

// ........

// asynchronously populate the cache

// Returns a Future<Void> which can be used to block until completion

asyncCache.put(key, value);

}

Page 72: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

import java.util.Collections;

import net.sf.jsr107cache.*;

Cache cache;

try {

CacheFactory cacheFactory =

CacheManager.getInstance().getCacheFactory();

cache = cacheFactory.createCache(Collections.emptyMap());

} catch (CacheException e) {

// ...

}

Page 73: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

String key; // ...

byte[] value; // ...

// Put the value into the cache.

cache.put(key, value);

// Get the value from the cache.

value = (byte[]) cache.get(key);

Page 74: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 75: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Page 76: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●

Page 77: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Task Queue

Page 78: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●●

○○○○

Page 79: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●○○

●○

■■

○■■■

Page 80: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

<queue-entries>

<queue>

<name>Queue-Name</name>

<rate>1/s</rate>

...

</queue>

<queue>

<name>Queue-Name2</name>

<mode>pull</mode>

...

</queue>

</queue-entries>

Push Queue

Pull Queue

Page 81: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 82: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Queue queue = QueueFactory.getDefaultQueue(); //named queue: //QueueFactory.getQueue("Qname");

TaskOptions task = TaskOptions.Builder .withUrl("/path-to-my-worker") .param(key, value);

queue.add(task);

Reachable Servlet

Page 85: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

DatastoreService ds = DatastoreServiceFactory.getDatastoreService();Queue queue = QueueFactory.getDefaultQueue();try { Transaction txn = ds.beginTransaction();

// … other operations queue.add(TaskOptions.Builder.withUrl("/path-to-my-worker")); // … other operations

txn.commit();} catch (DatastoreFailureException e) { // … exception handle}

Page 86: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Queue queue =

QueueFactory.getQueue("queue_name");

TaskOptions task =

TaskOptions.Builder

.withMethod(TaskOptions.Method.PULL)

.payload(payload);

queue.add(task);

Page 87: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Queue queue =

QueueFactory.getQueue("queue_name");

tasks = q.leaseTasks(

duration,

TimeUnit.SECONDS,

how-many);

Page 88: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

//delete named taskqueue.deleteTask("task_ name");

//purge all tasks from queueQueueFactory.getQueue("queue_name").purge();

Page 89: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

<queue>

<name>pull-queue1</name>

<mode>pull</mode>

<acl>

<user-email>[email protected]</user-email>

<writer-email>[email protected]</writer-email>

<writer-email>[email protected]</writer-email>

</acl>

</queue>

Page 90: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Cron

Page 91: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

<cronentries>

<cron>

<url>/recache</url>

<description>

Put your description here

</description>

<schedule>every 5 minutes</schedule>

</cron>

</cronentries>

Page 92: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●●●●●●

Page 93: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 94: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●

Page 96: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 97: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●●●

Page 98: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●

Page 99: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

$ gcloud auth login

$ gcloud config set project [my-project-id]

$ gsutil mb gs://[my-bucket]

$ gsutil ls gs://[my-bucket]

Page 101: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

$ gcloud sql -h

$ gcloud sql instances create [inst-name]

$ gcloud sql instances list

$ gcloud sql instances import instance-name --uri \

gs://your-bucket/sql-dump-file.gz

$ gcloud sql instances patch --assign-ip [inst-name]

$ gcloud sql instances get [inst-name]

Page 102: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

$ gcloud sql instances set-root-password test-sql \

-p [password]

$ gcloud sql instances patch test-sql \

--authorized-networks=[your-ip-address]

Page 104: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●

Page 105: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Using Cloud Storage

Page 106: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)
Page 107: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

BlobstoreService blobstoreService =

BlobstoreServiceFactory.getBlobstoreService();

UploadOptions uploadOptions =

UploadOptions.Builder.withGoogleStorageBucketName(

"BUCKET-NAME"); //Name without “gs://”

String uploadUrl = blobstoreService.createUploadUrl(

"/callback-url", uploadOptions);

resp.getWriter().println("<form action=" + uploadUrl

+ " method=\"post\" enctype=\"multipart/form-data\">");

resp.getWriter().println("<input type=\"file\" name=\"field-name\"");

Page 108: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {

BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();

Map<String, List<FileInfo>> blobs = blobstoreService.getFileInfos(req);

List<FileInfo> keys = blobs.get("field-name"); //input file name on form if (keys != null && keys.size() > 0) { FileInfo fileKey = keys.get(0);

String objectUploaded = fileKey.getGsObjectName();…. (Save the objectUploaded mapping to datastore or database)

Page 109: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

public void doGet(HttpServletRequest req, HttpServletResponse resp){

BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();

BlobKey blobKey = blobstoreService.createGsBlobKey("/gs/<bucket>/<object>");

try {blobstoreService.serve(blobKey, resp);

} catch (IOException e){e.printStackTrace();

}

….

Page 110: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

補充

Page 111: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●

Page 112: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Connect Cloud SQLSystemProperty.Environment.Value.Production) {

Class.forName("com.mysql.jdbc.GoogleDriver");

String url= "jdbc:google:mysql://instance-name/";

conn = DriverManager.getConnection(url);

try {

conn.createPreparedStatement…

...

Page 113: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●

○○○

Page 114: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

●●

Page 115: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

<?xml version="1.0" encoding="utf-8"?><appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> <application>mitac-cp300</application> <version>eord</version> …. <use-google-connector-j>true</use-google-connector-j> ….</appengine-web-app>

Page 117: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Connection conn = null;if (SystemProperty.environment.value() ==

SystemProperty.Environment.Value.Production) {// app is running in productionClass.forName("com.mysql.jdbc.GoogleDriver");String url= "jdbc:google:mysql://instance-name/";conn = DriverManager.getConnection(url);...

} else {// app is running on localhostClass.forName("com.mysql.jdbc.Driver");String url= "jdbc:mysql://db-ip-address/";conn = DriverManager.getConnection(url);...

}conn.~

Page 118: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

DriverManager.registerDriver(new AppEngineDriver());

conn = DriverManager.getConnection(connUrl);

String sql = "SELECT count(*) as total FROM " + tableName + "";

PreparedStatement stmt = conn.prepareStatement(sql);ResultSet results = stmt.executeQuery();

while (results.next()) {int total = results.getInt("total");…

}

Page 120: JCConf 2015  - 輕鬆學google的雲端開發 - Google App Engine入門(上)

Q & A