Quantcast
Channel: プログラム の個人的なメモ
Viewing all 860 articles
Browse latest View live

【Python】Webフレームワーク 「Flask」 ~ Hello World編 ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37735811.html
で少し触れた「Flask(フラスク)」のHello Worldをやってみる

■ 環境構築

前提条件

 * 実行環境を以下の関連記事を参考に構築する
https://blogs.yahoo.co.jp/dk521123/33850352.html

インストール

以下をコマンドして、インストールする
python -m pip install --upgrade pip
pip install Flask

■ サンプル

hello-flask.py

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
  return "Hello World!"

if __name__ == "__main__":
  app.run()

■ 実行コマンド

python hello-flask.py

動作確認

 * 以下のサイトをブラウザでアクセスする
  => 「Hello World!」と表示されたらOK
} [[http://localhost:5000]]


関連記事

Python で、簡単なWebアプリ ~ formデータを受け取る ~

https://blogs.yahoo.co.jp/dk521123/37735811.html

【Python】Webフレームワーク 「Flask」 ~ REST API編 ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37736310.html
の続き。
今度は、簡易的なRest APIを作成する。

■ 環境構築

前提条件

 * 実行環境を以下の関連記事を参考に構築する
https://blogs.yahoo.co.jp/dk521123/33850352.html
https://blogs.yahoo.co.jp/dk521123/37736310.html

インストール

以下をコマンドして、インストールする
python -m pip install --upgrade pip
pip install flask-restful

■ サンプル

restapi-flask.py

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import sys
import json
from flask import Flask, render_template, request
from flask_restful import Resource, Api, reqparse

app = Flask(__name__, template_folder='.')
api = Api(app)

@app.route('/')
def home():
  return render_template('demo-json.html')
@app.route('/result', methods=['GET', 'POST'])
def result():
  json_data = request.get_json(force=True)
  id = json_data['id']
  name = json_data['name']
  return json.dumps({'status':'OK', 'result-id':id, 'result-name':name});
    
if __name__ == "__main__":
  app.run(debug=True, host="localhost", port=8000)

demo-json.html

<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
<body>
ID: <input type="text" size="30" name="id" id="inputId">
Name: <input type="text" size="30" name="name" id="inputName">
<button id="button-json">Click Me</button>
</form>
<div id="result">[[Result]]</div>
<script
  src="https://code.jquery.com/jquery-3.3.1.min.js"
  integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
  crossorigin="anonymous"></script>
<script type="text/javascript">
$('#button-json').on('click',function(){
  console.log("[Enter]");
  
  var idValue = $('#inputId').val();
  var nameValue = $('#inputName').val();
  console.log("idValue = " + idValue);
  console.log("nameValue = " + nameValue);
  
  var inputData = {
    'id': idValue,
    'name': nameValue
  };
  $.ajax({
    url: 'http://localhost:8000/result',
    type: 'POST',
    dataType: 'json',
    data: JSON.stringify(inputData)
  })
  // Ajaxリクエストが成功した時発動
  .done( (data) => {
      $('#result').append(JSON.stringify(data));
      console.log(JSON.stringify(data));
  })
  // Ajaxリクエストが失敗した時発動
  .fail( (data) => {
      $('#result').append(JSON.stringify(data));
      console.log(JSON.stringify(data));
  });
});
</script>
</body>
</html>

■ 実行コマンド

python restapi-flask.py

動作確認

 * 以下のサイトをブラウザでアクセスする
  => ID, Nameに値(例「ID001」「Mike」)を入力し、ボタン押下。
  => 「[[Result]]」に「{"status":"OK","result-id":"ID001","result-name":"Mike"}」と表示されたらOK
[[http://localhost:8000]]


関連記事

Webフレームワーク 「Flask」 ~ Hello World編 ~

https://blogs.yahoo.co.jp/dk521123/37736310.html

【Python】Webフレームワーク 「Flask」 ~ REST API編 [2] ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37736752.html
の続き。
「Formでのデータ送信」と「セッション」について取り扱う。

■ 環境構築

前提条件

 * 実行環境を以下の関連記事を参考に構築する
https://blogs.yahoo.co.jp/dk521123/33850352.html
https://blogs.yahoo.co.jp/dk521123/37736310.html

■ サンプル

restapi-flask.py

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import sys
import json
from flask import Flask, session, render_template, request
from flask_restful import Resource, Api, reqparse

app = Flask(__name__, template_folder='.')
app.secret_key = 'sample_key'
api = Api(app)

@app.route('/')
def home():
  return render_template('demo.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
  if request.form['userName'] == 'admin' and request.form['password'] == 'pass':
    return render_template('success.html')
  else:
    return render_template('fail.html')

@app.route('/count', methods=['GET', 'POST'])
def count():
  counter = 0
  if 'count' in session:
    counter = int(session.get('count'))
  counter = counter + 1
  session['count'] = str(counter)
  
  return json.dumps({'result-count':session.get('count')});
    
if __name__ == "__main__":
  app.run(debug=True, host="localhost", port=8000)

demo.html

<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
<body>
<h1>From(POST)で送信</h1>
<form name="Form" method="POST" action="/login">
 User Name: <input type="text" size="30" name="userName">
 Password: <input type="password" size="30" name="password">
<input type="submit" value="submit" name="login">
</form>
<hr />
<h1>Ajax(JSON)で送信(Session)</h1>
<button id="button-json">Click Me</button>
<div id="result">[[Result]]</div>
<script
  src="https://code.jquery.com/jquery-3.3.1.min.js"
  integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
  crossorigin="anonymous"></script>
<script type="text/javascript">
$('#button-json').on('click',function(){
  $.ajax({
    url: 'http://localhost:8000/count',
    type: 'POST',
    dataType: 'json'
  })
  // Ajaxリクエストが成功した時発動
  .done( (data) => {
      $('#result').append(JSON.stringify(data));
      console.log(JSON.stringify(data));
  })
  // Ajaxリクエストが失敗した時発動
  .fail( (data) => {
      $('#result2').append(JSON.stringify(data));
      console.log(JSON.stringify(data));
  });
});
</script>
</body>
</html>

success.html

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Success</title>
</head>
<body>
 Success
</body>
</html>

fail.html

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Fail</title>
</head>
<body>
 Fail
</body>
</html>

■ 実行コマンド

python restapi-flask.py

動作確認

 * 以下のサイトをブラウザでアクセスする
[[http://localhost:8000]]


関連記事

Webフレームワーク 「Flask」 ~ Hello World編 ~

https://blogs.yahoo.co.jp/dk521123/37736310.html

Webフレームワーク 「Flask」 ~ REST API編 [1] ~

https://blogs.yahoo.co.jp/dk521123/37736752.html

【Docker】 Docker ~ Data Volume について ~

$
0
0

■ Data Volume

 * コンテナの破棄・再作成が簡単にできるが、そのままだとデータも消えてしまう
  => データの永続性を保つ仕組みとして、「Data Volume」がある(今回のテーマ)

■ コマンド

docker volume create 【ヴォリューム名】

docker run -v 【ヴォリューム名】:【パス】


関連記事

Docker ~ Linux / 入門編 ~

https://blogs.yahoo.co.jp/dk521123/37486283.html

Docker ~ Windows / 入門編 ~

https://blogs.yahoo.co.jp/dk521123/37128692.html

スマートフォン / タブレット に対応したサイト構築で気を付ける事項

$
0
0

■ はじめに

 PC だけでなく、スマートフォン / タブレット に対応したサイト構築で
起こった問題点について、メモをする。

【1】 数字の羅列が電話番号として認識

 * スマートフォン / タブレット(iPad)だと、電話番号として認識してしまい、リンクになってしまう

【2】 Tooltip/Mouseover の動作について

 * PC版のブラウザと、iPhone/iPadとAndroidでは動きが異なる
  => iPhone/iPadとAndroidでも動きが異なるので注意

【3】 縦・横向きでの動作確認

 * 当たり前ですが、テスト項目として、縦・横向きでの動作確認を追加する必要がある

【Python】Python で MySQLを使う

$
0
0

■ 実行環境

 * OS : Windows10
 * DB : MySQL8.0.12
 * Python : Python 3.7.0

PyMySQL のインスール

以下を実行する
pip3 install PyMySQL

■ サンプル

DBデータ

CREATE SCHEMA `sample_db` ;

CREATE TABLE `person` (
  `id` bigint(12) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

INSERT INTO `sample_db`.`person` (`name`) VALUES ('Mike');
INSERT INTO `sample_db`.`person` (`name`) VALUES ('Tom');
INSERT INTO `sample_db`.`person` (`name`) VALUES ('Sam');
INSERT INTO `sample_db`.`person` (`name`) VALUES ('Kevin');

mysql-demo.py

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import pymysql

print("Hello World")

connection = pymysql.connect(
  host="localhost",
  db="sample_db",
  user="root",
  password="password",
  charset="utf8",
  cursorclass=pymysql.cursors.DictCursor
)

cursor = connection.cursor()
cursor.execute("SELECT * FROM person")
people = cursor.fetchall()

cursor.close()
connection.close()

for person in people:
  print("ID : " + str(person["id"]) + " Name : " + person["name"])

動作確認

# 実行コマンド
python mysql-demo.py

関連記事

Webフレームワーク 「Flask」 ~ MySQLを使う ~

https://blogs.yahoo.co.jp/dk521123/37745178.html

Webフレームワーク 「Flask」 ~ SQLAlchemyでMySQLを操作する ~

https://blogs.yahoo.co.jp/dk521123/37745238.html

【Python】Webフレームワーク 「Flask」 ~ MySQLを使う ~

$
0
0

■ はじめに

 以下の関連記事を使って、Flask(フラスク)内で
MySQLに接続して、データをやり取りする
MySQLを使う
https://blogs.yahoo.co.jp/dk521123/37744753.html
テンプレートエンジン「jinja2」
https://blogs.yahoo.co.jp/dk521123/37744477.html

■ サンプル

 * データベース、テーブル、データは、以下の関連記事で使用したものと同じ
https://blogs.yahoo.co.jp/dk521123/37744753.html

main.py

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from flask import Flask, render_template
import pymysql

app = Flask(__name__)

def getDbConnection():
  return pymysql.connect(
    host="localhost",
    db="sample_db",
    user="root",
    password="password",
    charset="utf8",
    cursorclass=pymysql.cursors.DictCursor)

@app.route("/db/<int:id>")
def demo_mysql(id):

  connection = getDbConnection()
  cursor = connection.cursor()

  cursor.execute("SELECT * FROM person WHERE id=%s", id)
  person = cursor.fetchone()

  cursor.execute("INSERT INTO person(name) VALUES('Naomi')")
  connection.commit()
  
  cursor.execute("SELECT * FROM person")
  people = cursor.fetchall()

  cursor.close()
  connection.close()

  return render_template("db-sample.html", person_val = person, person_vals = people)

if __name__ == "__main__":
  app.run()

templates/db-sample.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Flask - Demo</title>
</head>
<body>
<h1>Sample</h1>

  <p>GET => [{{ person_val.id }}] {{ person_val.name }}!!!</p>

{% for person in person_vals: %}
  <p>[{{ person.id }}] Hello, {{ person.name }}!!!</p>
{% endfor %}
</body>
</html>

実行コマンド

python main.py
動作確認
 * 後は、ブラウザで以下にアクセスする
[[http://localhost:5000/db/2]]

関連記事

Python で MySQLを使う

https://blogs.yahoo.co.jp/dk521123/37744753.html

Webフレームワーク 「Flask」 ~ Hello World編 ~

https://blogs.yahoo.co.jp/dk521123/37736310.html

Webフレームワーク 「Flask」 ~ テンプレートエンジン「jinja2」 ~

https://blogs.yahoo.co.jp/dk521123/37744477.html

Webフレームワーク 「Flask」 ~ SQLAlchemyでMySQLを操作する ~

https://blogs.yahoo.co.jp/dk521123/37745238.html

Webフレームワーク 「Flask」 ~ SQLAlchemyでテーブルを連結する ~

https://blogs.yahoo.co.jp/dk521123/37746541.html

【Python】Webフレームワーク 「Flask」 ~ SQLAlchemyでMySQLを操作する ~

$
0
0

■ SQLAlchemy とは?

 * Alchemy (アルケミー) = 錬金術
 * PythonのORM(Object-Relational Mapping)

利点

 * SQLインジェクションを考慮している

環境設定

# 以下のコマンドを実行
pip install flask-sqlalchemy

■ サンプル

 * データベース、テーブル、データは、以下の関連記事で使用したものと同じ
https://blogs.yahoo.co.jp/dk521123/37744753.html

main.py

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:password@localhost/sample_db?charset=utf8"
db = SQLAlchemy(app)

class Person(db.Model):
  __tablename__ = "person"
  id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
  name = db.Column(db.Text())
  
@app.route("/")
def selectAll():

  people = Person.query.all()
  return render_template("sqlalchemy-sample.html", person_vals = people)

@app.route("/add/<string:name>")
def addNew(name):

  # データ追加
  person = Person()
  person.name = name
  db.session.add(person)
  db.session.commit()

  people = Person.query.all()
  return render_template("sqlalchemy-sample.html", person_vals = people)

@app.route("/update/<int:id>")
def update(id):

  # データ修正
  person = Person.query.get(id)
  person.name = "Ada"
  db.session.commit()

  people = Person.query.all()
  return render_template("sqlalchemy-sample.html", person_vals = people)

@app.route("/delete/<int:id>")
def delete(id):

  # データ削除
  person = Person.query.get(id)
  db.session.delete(person)
  db.session.commit()

  people = Person.query.all()
  return render_template("sqlalchemy-sample.html", person_vals = people)

if __name__ == "__main__":
  app.run()

templates/sqlalchemy-sample.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Flask - Demo</title>
</head>
<body>
<h1>Sample</h1>
{% for person in person_vals: %}
  <p>[{{ person.id }}] Hello, {{ person.name }}!!!</p>
{% endfor %}
</body>
</html>

実行コマンド

python main.py
動作確認
 * ブラウザで以下にアクセスする
[[http://localhost:5000]]
 * データ追加は、以下。
[[http://localhost:5000/add/John]]
 * データ修正は、以下。
[[http://localhost:5000/update/2]]
 * データ削除は、以下。
[[http://localhost:5000/delete/3]]

■ SQLAlchemy あれこれ

IDなどで絞り込む

get() を使う
# main.py
person = Person.query.get(2)
return render_template("sqlalchemy-sample.html", person_val = person)

# templates/sqlalchemy-sample.html
<p>[{{ person_val.id }}] Hello, {{ person_val.name }}!!!</p>

条件を絞る

filter() を使う
people = Person.query.filter(Person.id > 2).all()

出力データ数を限定する

limit() を使う
# 3までデータを出力する
people = Person.query.limit(3).all()

関連記事

Python で MySQLを使う

https://blogs.yahoo.co.jp/dk521123/37744753.html

Webフレームワーク 「Flask」 ~ Hello World編 ~

https://blogs.yahoo.co.jp/dk521123/37736310.html

Webフレームワーク 「Flask」 ~ MySQLを使う ~

https://blogs.yahoo.co.jp/dk521123/37745178.html

Webフレームワーク 「Flask」 ~ SQLAlchemyでテーブルを連結する ~

https://blogs.yahoo.co.jp/dk521123/37746541.html

【Python】Webフレームワーク 「Flask」 ~ テンプレートエンジン「jinja2」 ~

$
0
0

■ はじめに

 Webフレームワーク 「Flask(フラスク)」の
標準のテンプレートエンジンが、「jinja2(神社2)」らしいので使ってみた

補足

 * 以下の動画がキャンペーンで「Flask」やってるので勉強してみる
https://paiza.jp/works/search_courses/2002

【例1】Hello World

サンプル

main.py
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# ★Point1★「render_template」をインポートする
from flask import Flask, render_template
app = Flask(__name__)

@app.route("/")
def hello_world():

  name = "Mike"
  names = ["Tom", "Kevin", "Smith"]

  # ★Point2★「render_template()」でテンプレートを呼び出す
  return render_template("index.html", name_val = name, name_vals = names)

if __name__ == "__main__":
  app.run()
templates/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Flask - Demo</title>
</head>
<body>
{% if name_val %}
  <h1>Hello, {{ name_val }}</h1>
{% else %}
  <p>Hello World!</p>
{% endif %}

{% for name in name_vals: %}
  <p>Hello, {{ name + " from USA" }}!!!</p>
{% endfor %}
</body>
</html>
実行コマンド
python main.py

# 後は、ブラウザで以下にアクセスする
[[http://localhost:5000]]

【例2】共通テンプレートを作る

サンプル

main.py
【例1】の「main.py」と同じなので、省略
templates/common-template.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Flask - Demo</title>
</head>
<body>
<h1>Template Sample</h1>
{% block content %}
{% endblock %}
</body>
</html>
templates/index.html
{% extends "common-template.html" %}
{% block content %}
  {% if name_val %}
    <h1>Hello, {{ name_val }}</h1>
  {% else %}
    <p>Hello World!</p>
  {% endif %}

  {% for name in name_vals: %}
    <p>Hello, {{ name + " from USA" }}!!!</p>
  {% endfor %}
{% endblock %}

関連記事

Webフレームワーク 「Flask」 ~ Hello World編 ~

https://blogs.yahoo.co.jp/dk521123/37736310.html

Webフレームワーク 「Flask」 ~ MySQLを使う ~

https://blogs.yahoo.co.jp/dk521123/37745178.html

【Python】Webフレームワーク 「Flask」 ~ SQLAlchemyでテーブルを連結する ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37745238.html
の続き。

今回は、SQLAlchemy (アルケミー)で、外部キーがあるテーブルを連結する。

■ サンプル

DBデータ

データベース
CREATE SCHEMA `sample_db`;
テーブル
CREATE TABLE `section` (
  `id` bigint(12) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

CREATE TABLE `person` (
  `id` bigint(12) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  `section_id` bigint(12) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `section_id_idx` (`section_id`),
  CONSTRAINT `section_id` FOREIGN KEY (`section_id`) REFERENCES `section` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
データ
INSERT INTO `sample_db`.`section` (`name`) VALUES ('Finance');
INSERT INTO `sample_db`.`section` (`name`) VALUES ('Accounting');
INSERT INTO `sample_db`.`section` (`name`) VALUES ('Engineering');
INSERT INTO `sample_db`.`section` (`name`) VALUES ('Development');

INSERT INTO `sample_db`.`person` (`name`, `section_id`) VALUES ('Mike', '1');
INSERT INTO `sample_db`.`person` (`name`, `section_id`) VALUES ('Tom', '2');
INSERT INTO `sample_db`.`person` (`name`, `section_id`) VALUES ('Sam', '2');
INSERT INTO `sample_db`.`person` (`name`, `section_id`) VALUES ('Sean', '3');
INSERT INTO `sample_db`.`person` (`name`, `section_id`) VALUES ('Kevin', '2');
INSERT INTO `sample_db`.`person` (`name`, `section_id`) VALUES ('John', '1');
INSERT INTO `sample_db`.`person` (`name`, `section_id`) VALUES ('Kevin', '2');
INSERT INTO `sample_db`.`person` (`name`, `section_id`) VALUES ('Ken', '4');

SQLAlchemy-demo.py

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:password@localhost/sample_db?charset=utf8"
db = SQLAlchemy(app)

class Person(db.Model):
  __tablename__ = "person"
  id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
  name = db.Column(db.Text())
  section_id = db.Column(db.BigInteger, db.ForeignKey('section.id'))

class Section(db.Model):
  __tablename__ = "section"
  id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
  name = db.Column(db.Text())
  
  person = db.relationship('Person', backref=db.backref('section', lazy=True))
  
@app.route("/")
def selectAll():

  people = Person.query.all()
  return render_template("SQLAlchemy-demo.html", person_vals = people)

if __name__ == "__main__":
  app.run()

SQLAlchemy-demo.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Flask - Demo</title>
</head>
<body>
<h1>Sample</h1>
<table>
{% for person in person_vals: %}
  <tr>
    <td>{{ person.id }}</td>
    <td>{{ person.name }}</td>
    <td>{{ person.section_id }}</td>
    <td>{{ person.section.name }}</td>
  </tr>
{% endfor %}
</table>
</body>
</html>

実行コマンド

python SQLAlchemy-demo.py
動作確認
 * ブラウザで以下にアクセスする
[[http://localhost:5000]]

関連記事

Webフレームワーク 「Flask」 ~ Hello World編 ~

https://blogs.yahoo.co.jp/dk521123/37736310.html

Webフレームワーク 「Flask」 ~ MySQLを使う ~

https://blogs.yahoo.co.jp/dk521123/37745178.html

Webフレームワーク 「Flask」 ~ SQLAlchemyでMySQLを操作する ~

https://blogs.yahoo.co.jp/dk521123/37745238.html

【Java】JavaをWindowsサービス化する ~ Apache Commons Daemon ~

$
0
0

■ Apache Commons Daemon を使ったサービス作成方法

[1] 以下のサイトから、必要なモジュールをダウンロードする
commons-daemon
http://commons.apache.org/proper/commons-daemon/download_daemon.cgi
http://ftp.jaist.ac.jp/pub/apache//commons/daemon/binaries/windows/
commons-logging
https://commons.apache.org/proper/commons-logging/download_logging.cgi
~~~~~~
 + commons-daemon-1.1.0-bin.zip
 + commons-daemon-1.1.0-bin-windows.zip
 + commons-logging-1.2-bin.zip
~~~~~~

[2] Windowsサービス用の処理をコーディングし、JARファイルを出力する
[3] Windowsサービス用のインスール/アンインストール用のバッチファイルを作成する
[4] ファイルを配置する
[5] Windowsサービス用のインスール用のバッチファイルを起動する
[6] Windowsサービスを開始する

■ サンプル

Windowsサービス用Javaソース

HelloWorldServiceLauncher.java
package com.sample.service;

import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.daemon.Daemon;
import org.apache.commons.daemon.DaemonContext;
import org.apache.commons.daemon.DaemonInitException;

public class HelloWorldServiceLauncher implements Daemon {
  private static IService service = null;
  private static HelloWorldServiceLauncher instance = new HelloWorldServiceLauncher();
  private ExecutorService executor = null;
  private static Scanner scanner;

  public static void main(String[] args) {
    if (args != null) {
      for (String arg : args) {
        System.out.println("Param : " + arg);
      }
    }

    HelloWorldServiceLauncher.startWindowsService();

    scanner = new Scanner(System.in);
    System.out.printf("Enter 'stop' to halt: ");
    while (!scanner.nextLine().toLowerCase().equals("stop")) {
      ;
    }

    HelloWorldServiceLauncher.stopWindowsService();
  }

  public static void startWindowsService(String... args) {
    if (args != null) {
      for (String arg : args) {
        System.out.println("Param : " + arg);
      }
    }
    instance.initialize();
  }

  public static void stopWindowsService() {
    instance.terminate();
  }

  @Override
  public void destroy() {
    // NOP
  }

  @Override
  public void init(DaemonContext arg0) throws DaemonInitException, Exception {
    // NOP
  }

  @Override
  public void start() throws Exception {
    // NOP
  }

  @Override
  public void stop() throws Exception {
    // NOP
  }

  public void initialize() {
    if (HelloWorldServiceLauncher.service == null) {
      HelloWorldServiceLauncher.service = new HelloWorldService();
    }

    this.executor = Executors.newSingleThreadExecutor();
    this.executor.execute(HelloWorldServiceLauncher.service);
  }

  public void terminate() {
    if (HelloWorldServiceLauncher.service != null) {
      HelloWorldServiceLauncher.service.stop();
    }
    if (this.executor != null) {
      this.executor.shutdown();
    }
  }
}
IService.java
package com.sample.service;

public interface IService extends Runnable {
  public void stop();
  public Boolean isStopped();
}
HelloWorldService.java
package com.sample.service;

import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class HelloWorldService implements IService {
  private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
  private Boolean isStopped = Boolean.FALSE;

  @Override
  public void run() {
    while (!this.isStopped()) {
      System.out.println("[ENTER]" + dateFormat.format(new Date()));
      try {
        // ★ここに処理を書く(今回はダミー処理を書いておく)★
        try (FileWriter fileWriter = new FileWriter("C:\\temp\\hello-world.txt", true);) {
          fileWriter.write(dateFormat.format(new Date()) + " : Hello World!\n");
        } catch (IOException ex) {
          ex.printStackTrace();
        }
        Thread.sleep(5_000L);

      } catch (InterruptedException ex) {
        this.isStopped = Boolean.TRUE;
      }
      System.out.println("[EXIT]" + dateFormat.format(new Date()));
    }
  }

  @Override
  public void stop() {
    this.isStopped = Boolean.TRUE;
  }

  @Override
  public Boolean isStopped() {
    return this.isStopped;
  }
}

Windowsサービス用のインスール/アンインストール用のバッチファイル

install.bat
set EXEC_DIR=%~dp0
echo %EXEC_DIR%
set CLASSPATH_DIR=%EXEC_DIR%lib
echo %CLASSPATH_DIR%
set CLASSPATH=%EXEC_DIR%HelloWorldLauncher.jar;%CLASSPATH_DIR%\commons-daemon-1.1.0.jar;%CLASSPATH_DIR%\commons-logging-1.2.jar;
echo %CLASSPATH%
set JVM_PATH="C:\Program Files\Java\jdk1.8.0\jre\bin\server\jvm.dll"

set INSTALL_EXE=%EXEC_DIR%prunsrv.exe
echo %INSTALL_EXE%

prunsrv //IS//HelloWorldService --DisplayName="Hello World Service" --Description="Demo for Hello World Service" ^
        --Install %INSTALL_EXE% --Startup auto --Jvm %JVM_PATH% --StartMode jvm --StopMode=jvm ^
        --Classpath=%CLASSPATH% ^
        --StartClass com.sample.service.HelloWorldServiceLauncher --StartMethod startWindowsService --StartParams Hello#World#Start ^
        --StopClass com.sample.service.HelloWorldServiceLauncher --StopMethod stopWindowsService --StopParams Hello#World#Stop ^
        --LogPath=%EXEC_DIR%logs --LogLevel=DEBUG ^
        --StdOutput=auto --StdError=auto ^


pause
uninstall.bat
prunsrv //DS//HelloWorldService
  
pause

【Spring Framework】Spring Framework ~ Hello World編 ~

【Java】 Apache Commons Logging

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37752105.html
で、Apache Commons Daemon 内部で、Apache Commons Loggingを使用した関係で少し勉強したら、
Apache Commons Logging について勘違いしている部分があったのでメモ

■ Apache Commons Logging

 * ロギングのための汎用インターフェースを提供
  => Apache Commons Logging 自体が、ログ出力している訳ではない
  => 別のロギングに処理を移譲する


関連記事

JavaをWindowsサービス化する ~ Apache Commons Daemon ~

https://blogs.yahoo.co.jp/dk521123/37752105.html

【Spring Framework】Spring Framework ~ Formデータの入出力 / Thymeleaf 編 ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37753597.html
の続き。

今回は、以下の習得を目的にサンプルを作成してみる

今回の目的

1) Formデータの入出力
2) テンプレートエンジンである「Thymeleaf (タイムリーフ)」

■ サンプル

スターター

HelloWorldApplication.java
package com.sample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class HelloWorldApplication {
  public static void main(String[] args) {
    SpringApplication.run(HelloWorldApplication.class, args);
  }
}

コントローラ側

HelloWorldController.java
package com.sample.controllers;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.sample.forms.HelloForm;

@Controller
@EnableAutoConfiguration
public class HelloWorldController {
  @RequestMapping(value = "/", method = {RequestMethod.GET, RequestMethod.POST})
  public String home(Model model) {
    model.addAttribute("resultForm", new HelloForm());
    model.addAttribute("world", "World!!");
    return "home";
  }

  @RequestMapping(value = "/result", method = RequestMethod.POST)
  public String result(@ModelAttribute HelloForm helloForm, Model model) {
    model.addAttribute("resultForm", helloForm);
    return "hello-world";
  }
}

モデル側

HelloForm.java
package com.sample.forms;

import java.io.Serializable;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class HelloForm implements Serializable {
  private static final long serialVersionUID = 1L;
  @NotNull
  @Size(min = 5, max = 10)
  private String greeting;

  private String name;

  public void setGreeting(String greeting) {
    this.greeting = greeting;
  }

  public String getGreeting() {
    return this.greeting;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }
}

ビュー側

home.html (src/main/resources/templates/home.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<h1>Hello, <span th:text="${world}"></span></h1>
<form th:action="@{/result}" method="post">
  <div><label> Greeting : <input type="text" name="greeting"/> </label></div>
  <div><label> Name: <input type="text" name="name"/> </label></div>
  <input type="submit" value="Login"/>
</form>
</body>
</html>
hello-world.html (src/main/resources/templates/hello-world.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Result</title>
</head>
<body>
<h1>Result</h1>
<p th:text="${resultForm.greeting} + ', ' + ${resultForm.name} + '!'" />
<a href="/">Next</a>
</body>
</html>

■ 実行する

[1] プロジェクトを右クリックし、[Run As]-[3 Spring Boot App]を選択
[2] ブラウザで以下のURLにアクセスする
 => 例えば、Greetingに「Hello」、Name「Mike」を入力し、「Login」ボタン押下。
 => 「Hello, Mike!」が表示される
[[[http://localhost:8080/]]]


関連記事

Spring Framework ~ Hello World編 ~

https://blogs.yahoo.co.jp/dk521123/37753597.html

【Oracle】Oracle DB での テスト環境作成

$
0
0

■ 表領域(TABLESPACE)

表領域作成

CREATE TABLESPACE SAMLE_DB
  DATAFILE 'C:\oraclexe\app\oracle\product\11.2.0\server\database\SAMLE_DB.dbf' SIZE 100M
  SEGMENT SPACE MANAGEMENT AUTO
;

■ ユーザ

ユーザ作成

CREATE USER TEST_USER
    IDENTIFIED BY "password"
    DEFAULT TABLESPACE SAMLE_DB
    TEMPORARY TABLESPACE TEMP
    ACCOUNT UNLOCK;

■ テーブル

テーブル作成

create table person
(
 id char(3) ,
 name varchar2(10),
 primary key(id)
)

テーブル削除

drop table person

参考文献

http://oracle.se-free.com/ddl/A1_cre_tbl.html

■ テストデータ

テストデータ作成

INSERT INTO person (id, name) VALUES ('001', 'Mike');
INSERT INTO person (id, name) VALUES ('002', 'Tom');
INSERT INTO person (id, name) VALUES ('003', 'Sam');

【Oracle】【Java】 Java で Oracle DB にアクセスする

$
0
0

■ 環境設定

JDBCドライブ

 * JDBCドライブ(今回は「ojdbc7.jar」)を以下のサイトから、
   ダウンロードし、インポートする
https://www.oracle.com/technetwork/database/features/jdbc/jdbc-drivers-12c-download-1958347.html

テストデータ

 * 以下の関連記事を参照。
https://blogs.yahoo.co.jp/dk521123/37756250.html

■ サンプル

OracleDbSample.java

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class OracleDbSample {
  public static void main(String[] args) throws ClassNotFoundException, SQLException {
    Class.forName("oracle.jdbc.driver.OracleDriver");

    try (Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "TEST_USER", "password");
        Statement stmt = connection.createStatement();
        ResultSet resultSet = stmt.executeQuery("select ID, NAME from PERSON");) {
      while (resultSet.next()) {
        System.out.println(resultSet.getString(1) + "\t" + resultSet.getString(2));
      }
    }
  }
}

出力結果

001	Mike
002	Tom
003	Sam


関連記事

Oracle DB での テスト環境作成

https://blogs.yahoo.co.jp/dk521123/37756250.html

Spring Framework ~ JPA / Oracle DB 編 ~

https://blogs.yahoo.co.jp/dk521123/37758365.html

【Spring Framework】Spring Framework ~ JPA / Oracle DB 編 ~

$
0
0

■ 環境設定

 * サンプルを実行する上での環境設定

Spring用のプロジェクト作成

[1] Eclipse で [File]-[New]-[Other]-[Spring Boot]-[Spring Starter Project]を選択し「Next」ボタン押下
[2] 以下を入力し、「Next」ボタン押下
 + Name : 任意文字列(今回は「sample」)
 + Type : Gradle
[3] Spring Boot Versionを選択(今回は「2.1.0 M4」)し、以下にチェックを付けて、「Finish」ボタン押下
 + Core - DevTools
 + SQL - JPA / JDBC
 + Template Engine - Thymeleaf
 + Web - Web

JDBCドライブ

本当は、 Gradle からやりたかったけど...
 * JDBCドライブ(今回は「ojdbc7.jar」)を以下のサイトから、
   ダウンロードし、インポートする
https://www.oracle.com/technetwork/database/features/jdbc/jdbc-drivers-12c-download-1958347.html

テストデータ

 * 以下の関連記事を参照。
https://blogs.yahoo.co.jp/dk521123/37756250.html

■ サンプル

スターター

PersonApplication.java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class PersonApplication {
  public static void main(String[] args) {
    SpringApplication.run(PersonApplication.class, args);
  }
}

コントローラ側

PersonController.java
package com.example.demo.controllers;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.example.demo.models.PersonModel;
import com.example.demo.repositories.PersonRepository;

@Controller
@EnableAutoConfiguration
public class PersonController {
  @Autowired
  PersonRepository repository;

  @RequestMapping(value = "/", method = { RequestMethod.GET, RequestMethod.POST })
  public String home(Model model) {
    List<PersonModel> people = this.repository.getAll();
    model.addAttribute("people", people);
    return "home";
  }
}

モデル側

Person.java
package com.example.demo.models;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Person implements Serializable {
  private static final long serialVersionUID = 1L;
  
  @Id
  private String id;
  @Column
  private String name;
  
  public Person(String id, String name) {
    this.id = id;
    this.name = name;
  }
  
  public String getId() {
    return this.id;
  }
  public void setId(String id) {
    this.id = id;
  }
  public String getName() {
    return this.name;
  }
  public void setName(String name) {
    this.name = name;
  }
}

データアクセス側

PersonRepository.java
package com.example.demo.repositories;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.example.demo.models.Person;

@Repository
public class PersonRepository {
  private final JdbcTemplate jdbcTemplate;

  @Autowired
  public PersonRepository(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
  }

  public List<Person> getAll() {
    return jdbcTemplate.query("SELECT * FROM person",
        (resultSet, rowNum) -> new Person(resultSet.getString("id"), resultSet.getString("name")));
  }
}

ビュー側

home.html (src/main/resources/templates/home.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
<tr>
  <th>ID</th>
  <th>Name</th>
</tr>
<tr th:each="person:${people}">
  <td th:text="${person.getId()}"></td>
  <td th:text="${person.getName()}"></td>
</tr>
</table> 
</body>
</html>

設定ファイル

application.properties (src/main/resources/application.properties)
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:xe
spring.datasource.username=TEST_USER
spring.datasource.password=password
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver

■ 実行する

[1] プロジェクトを右クリックし、[Run As]-[3 Spring Boot App]を選択
[2] ブラウザで以下のURLにアクセスする
[[[http://localhost:8080/]]]

関連記事

Spring Framework ~ Hello World編 ~

https://blogs.yahoo.co.jp/dk521123/37753597.html

Spring Framework ~ Formデータの入出力 / Thymeleaf 編 ~

https://blogs.yahoo.co.jp/dk521123/37755544.html

【Oracle】Javaストアド ~ Oracle から Java を呼ぶ ~

$
0
0

■ はじめに

 Oracle から Java をコールする方法を探していたら、
「Javaストアド・プロシージャ」という機能があるらしいので調べてみる。

■ 注意

 Oracle Database 11g Express Editionでは、
Javaがサポートされていないので利用できない

■ 設定例

【1】Javaファイルを作成する

HelloWorld.java
public class HelloWorld {
  public static String sayHello() {
    return "Hello world";
  }
}

【2】Javaファイルをコンパイルする

cd C:\work
javac HelloWorld.java

 => HelloWorld.class ができる

【3】class ファイルを Oracle DB に登録する

CREATE DIRECTORY java_dir AS 'C:\work';
CREATE OR REPLACE JAVA CLASS USING BFILE (java_dir, 'HelloWorld.class')

【4】Java メソッドを呼び出すストアドファンクションを作成する

CREATE OR REPLACE FUNCTION say_hello RETURN VARCHAR2 AS LANGUAGE JAVA NAME 'HelloWorld.sayHello() return java.lang.String';

【5】動作確認

SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE(say_hello);
END;

【SQL】相関サブクエリ / 自己相関サブクエリ のサンプル

$
0
0

■ サンプル1:変化(増加/変化なし/減少)

使用テーブル / データ

 * Oracle 11g
テーブル
-- 年間売上
CREATE TABLE "SALES" 
(
  "YEAR" INT,
  "SALE" INT,
  PRIMARY KEY ("YEAR")
);

# DROP TABLE SALES;
データ
INSERT INTO SALES VALUES(2000, 1280);
INSERT INTO SALES VALUES(2001, 1220);
INSERT INTO SALES VALUES(2002, 1470);
INSERT INTO SALES VALUES(2003, 1310);
INSERT INTO SALES VALUES(2004, 1310);
INSERT INTO SALES VALUES(2005, 1920);
INSERT INTO SALES VALUES(2006, 1680);
INSERT INTO SALES VALUES(2007, 1790);
INSERT INTO SALES VALUES(2008, 2170);
INSERT INTO SALES VALUES(2009, 1810);
INSERT INTO SALES VALUES(2010, 1810);

-- 例1-2用の追加データ()
INSERT INTO SALES VALUES(2011, 1420);
INSERT INTO SALES VALUES(2013, 1720);
INSERT INTO SALES VALUES(2014, 1640);
INSERT INTO SALES VALUES(2017, 2310);
INSERT INTO SALES VALUES(2018, 2810);


確認用 select文
SELECT * FROM SALES;

YEAR	SALE
2000	1280
2001	1220
2002	1470
2003	1310
2004	1310
2005	1920
2006	1680
2007	1790
2008	2170
2009	1810
2010	1810

【例1-1】年間売上の変化(増加/変化なし/減少)

SELECT
 S1.YEAR AS YEAR,
 CASE WHEN S1.SALE = S2.SALE THEN '→'
      WHEN S1.SALE > S2.SALE THEN '↑'
      WHEN S1.SALE < S2.SALE THEN '↓'
 ELSE '-' END AS UP_OR_DOWN,
 S1.SALE AS SALE,
 S2.SALE AS PREVIOUS_SALE,
 S1.SALE - S2.SALE AS DIFF
FROM
 SALES S1
LEFT OUTER JOIN
 SALES S2
ON
 S1.YEAR = S2.YEAR + 1
ORDER BY
 YEAR;
出力結果
YEAR UP_OR_DOWN SALE PREVIOUS_SALE DIFF
2000 -      1280 « NULL »      « NULL »
2001 ↓      1220 1280          -60
2002 ↑     1470 1220          250
2003 ↓     1310 1470          -160
2004 →     1310 1310          0
2005 ↑     1920 1310          610
2006 ↓     1680 1920          -240
2007 ↑     1790 1680          110
2008 ↑     2170 1790          380
2009 ↓     1810 2170          -360
2010 →     1810 1810          0
参考文献
https://codezine.jp/article/detail/907

【例1-2】年間売上の変化(増加/変化なし/減少。歯抜けデータ)


■ サンプル2:性別・部署別の最高齢

使用テーブル / データ

 * MySQL
テーブル
-- 従業員
CREATE TABLE Employees
(
id char(4) NOT NULL,
name varchar(20) NULL,
departmentId char(4) NULL,
bossId char(4) NULL,
sex char(1) NULL, -- m : male, f : famale
birthDate Date NULL
)

-- 部署
CREATE TABLE Departments
(
id char(4) NOT NULL,
name varchar(20) NULL,
)
データ
INSERT INTO Employees VALUES('1000', 'Robin','D000', NULL, 'm', '1973-5-6')
INSERT INTO Employees VALUES('1001', 'Mike','D001', NULL, 'm', '1945-11-9')
INSERT INTO Employees VALUES('1002', 'Tony','D000', NULL, 'm', '1965-1-12')
INSERT INTO Employees VALUES('1003', 'Claire','D001', '1001', 'f', '1987-9-22')
INSERT INTO Employees VALUES('1004', 'John','D002', '1002', 'm', '1972-4-2')
INSERT INTO Employees VALUES('1005', 'Ken','D002', '1001', 'm', '1982-12-22')
INSERT INTO Employees VALUES('1006', 'Hilary','D001', '1003', 'f', '1979-9-9')
INSERT INTO Employees VALUES('1007', 'Becky','D000', '1007', 'f', '1980-3-2')
INSERT INTO Employees VALUES('1008', 'Anne','D002', '1007', 'f', '1969-1-31')
INSERT INTO Employees VALUES('1007', 'Steve','D000', NULL, 'm', '1955-2-24')
INSERT INTO Employees VALUES('1008', 'Thomas','D001', '1007', 'm', '1959-9-12')

INSERT INTO Departments VALUES('D000', 'IT')
INSERT INTO Departments VALUES('D001', 'Sales')
INSERT INTO Departments VALUES('D002', 'Accounting')
確認用 select文
SELECT 
E1.Id,
E1.name,
D.name,
E1.bossId,
E1.sex,
E1.birthDate,
((CONVERT(INT,CONVERT(VARCHAR(8),GETDATE(),112)) - CONVERT(INT,CONVERT(VARCHAR(8),E1.birthDate,112))) / 10000) AS age
FROM
  Employees E1
INNER JOIN
  Departments D
ON
  E1.departmentId = D.id
出力結果
Id	name	name	bossId	sex	birthDate	age
1000	Robin	IT	NULL	m	1973-05-06	42
1001	Mike	Sales	NULL	m	1945-11-09	70
1002	Tony	IT	NULL	m	1965-01-12	51
1003	Claire	Sales	1001	f	1987-09-22	28
1004	John	Accounting	1002	m	1972-04-02	43
1005	Ken	Accounting	1001	m	1982-12-22	33
1006	Hilary	Sales	1003	f	1979-09-09	36
1007	Becky	IT	1007	f	1980-03-02	35
1008	Anne	Accounting	1007	f	1969-01-31	46
1007	Steve	IT	NULL	m	1955-02-24	60
1008	Thomas	Sales	1007	m	1959-09-12	56

【例2-2】性別別の最高齢

SELECT 
E1.Id,
E1.name,
D.name,
E1.bossId,
E1.sex,
E1.birthDate,
((CONVERT(INT,CONVERT(VARCHAR(8),GETDATE(),112)) - CONVERT(INT,CONVERT(VARCHAR(8),E1.birthDate,112))) / 10000) AS age
FROM
  Employees E1
INNER JOIN
  Departments D
ON
  E1.departmentId = D.id
WHERE
  ((CONVERT(INT,CONVERT(VARCHAR(8),GETDATE(),112)) - CONVERT(INT,CONVERT(VARCHAR(8),E1.birthDate,112))) / 10000) = 
  (SELECT MAX((CONVERT(INT,CONVERT(VARCHAR(8),GETDATE(),112)) - CONVERT(INT,CONVERT(VARCHAR(8),E2.birthDate,112))) / 10000)
  FROM Employees E2 WHERE E1.sex = E2.sex
  )

【例2-2】部署別の最高齢

SELECT 
E1.Id,
E1.name,
D.name,
E1.bossId,
E1.sex,
E1.birthDate,
((CONVERT(INT,CONVERT(VARCHAR(8),GETDATE(),112)) - CONVERT(INT,CONVERT(VARCHAR(8),E1.birthDate,112))) / 10000) AS age
FROM
  Employees E1
INNER JOIN
  Departments D
ON
  E1.departmentId = D.id
WHERE
  ((CONVERT(INT,CONVERT(VARCHAR(8),GETDATE(),112)) - CONVERT(INT,CONVERT(VARCHAR(8),E1.birthDate,112))) / 10000) = 
  (SELECT MAX((CONVERT(INT,CONVERT(VARCHAR(8),GETDATE(),112)) - CONVERT(INT,CONVERT(VARCHAR(8),E2.birthDate,112))) / 10000)
  FROM Employees E2 WHERE E1.departmentId = E2.departmentId
  )


関連記事

相関サブクエリ / 自己相関サブクエリ

https://blogs.yahoo.co.jp/dk521123/35761987.html

自己相関サブクエリ でパフォーマンスが悪かった話とその解決策

https://blogs.yahoo.co.jp/dk521123/37516643.html

【Java】【C】【C++】 JNR ~ 入門編 ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/36187289.html
で、JNA(Java Native Access)を使って、JavaからC/C++コードを呼び出した。
しかし、JNR (Java Native Runtime)ってのもあるらしいので、簡単に調べてみた。

■ JNR (Java Native Runtime)とは?

 * C/C++コードを、Javaから直接呼び出すことができるライブラリ

公式サイト

https://github.com/jnr/jnr-ffi

■ JNAとの違い

https://stackoverflow.com/questions/44760972/what-is-the-difference-between-jna-and-jnr
より
~~~~~~
JNA uses reflection to call native methods.
# JNAはネイティブメソッドを呼ぶために、リフレクションを使う

JNR generates bytecode in runtime only once therefore JNR works faster then JNA.
# JNRは、ランタイムで一度、バイトコードを生成する、故にJNRはJNAより早く動作します
~~~~~~
JNR VS JNA
https://java.libhunt.com/compare-jnr-ffi-vs-jna
だと、人気や安定性では、現状(2018/10/09現在)まだまだJNAの方に分がありそう。


関連記事

JNA (Java Native Access)

入門編
https://blogs.yahoo.co.jp/dk521123/36187289.html
基本編
https://blogs.yahoo.co.jp/dk521123/37087661.html
あれこれ編
https://blogs.yahoo.co.jp/dk521123/37089190.html

JNI

Java から C++ のソースを呼び出す
https://blogs.yahoo.co.jp/dk521123/33062191.html
C++ から Java のソースを呼び出す
https://blogs.yahoo.co.jp/dk521123/33067170.html
Viewing all 860 articles
Browse latest View live
<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>