forget for get

覚えるために忘れる

PowerShell入門

サンプルコード

hello.ps1

Set-Variable -Name MAX_LEVEL -Value 100 -Option Constant
Write-Output MAX_LEVEL;

Write-Output (Get-Date).ToString("yyyy/MM/dd HH:mm:ss") 

#配列
[int[]]$nums=1,2,3
for ($i = 0; $i -lt 3; $i++) {
  Write-Output $nums[$i]
}

#こうも書ける
foreach ($i in 1..3) {
  Write-Output $i
}

#関数
function lottery([int]$rate) {
  $random = Get-Random -Minimum 0 -Maximum 100
  return $random -lt $rate
}

if (lottery(50)) {
  Write-Output "Hit!"
} else {
  Write-Output "Miss!"
}

実行時に許可がいるので以下のように実行

powershell -NoProfile -ExecutionPolicy Unrestricted ./hello.ps1

エクセルからMySQLに接続

MySQL ODBCドライバをインストール

https://dev.mysql.com/downloads/connector/odbc/

 

使うエクセルが2007(32bit)だったので、8.0を選択。

 

ODBCデータソースの設定

コントロールパネルのODBCデータソースアドミニストレータ(32ビット)を使用して、MySQLの接続情報を設定

MySQLサーバーのIPアドレス、データベース名、ユーザー名、パスワードを入力

 

MySQL権限設定

VirtualBoxMySQLに接続しようとしたけどエラー。

権限を設定しないといけない。

CREATE USER 'remoteuser'@'%' IDENTIFIED BY 'password';

GRANT SELECT, INSERT, UPDATE, DELETE ON lightwill.* TO 'remoteuser'@'%';

FLUSH PRIVILEGES;

外部からアクセスできるユーザを作成。

SELECT, INSERT, UPDATE, DELETE の権限を付与。

反映。

 

エクセルマクロ(VBA

Sub AccessMySQL()
    Dim conn As Object
    Dim rs As Object
    Dim strSql As String
    Dim strConn As String
    
    ' MySQLへの接続情報を設定
    strConn = "Driver={MySQL ODBC 8.0 Unicode Driver};Server=192.168.33.10;Database=lightwill;Uid=remoteuser;Pwd=password;"
    
    ' ADO Connectionオブジェクトを作成
    Set conn = CreateObject("ADODB.Connection")
    
    ' 接続を開く
    conn.Open strConn
    
     ' SQLクエリを作成
    strSql = "SELECT * FROM dp_comments order by id desc LIMIT 0, 30;"
    
    ' ADO Recordsetオブジェクトを作成
    Set rs = CreateObject("ADODB.Recordset")
    
    ' RecordsetにSQLクエリの結果を格納
    rs.Open sql, conn
    
    ' データをExcelに貼り付け
    Sheet1.Range("A1").CopyFromRecordset rs
    
    ' 接続を閉じる
    rs.Close
    conn.Close
    
    ' オブジェクトの解放
    Set rs = Nothing
    Set conn = Nothing
End Sub

 

 

 

 

SpringBoot入門:DBから値を取得

気軽に試せるH2データベースを使えるようにする

src/main/resources/
application.properties

spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

spring.sql.init.encoding=UTF-8
spring.sql.init.mode=always
spring.sql.init.schema-locations=classpath:schema.sql
spring.sql.init.data-locations=classpath:data.sql

spring.h2.console.enabled=true

 

スキーマとテストデータのSQL

schema.sql

create table if not exists employee(
  id varchar(50) primary key,
  name varchar(50),
  age int
);

 

data.sql

insert into employee(id, name, age)
values('1', 'Tom', 30);

Model、Repository、Service、Controller、Viewを作成、修正

src/main/java/com.example.demo/hello
Employee.java

@Data
public class Employee {
	private String employeeId;
	private String employeeName;
	private int employeeAge;
}

HelloRepository.java

@Repository
public class HelloRepository {
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	public Map<String, Object> findById(String id) {
		String query = "select *"
				+ " from employee"
				+ " where id=?";		
		Map<String, Object> employee = jdbcTemplate.queryForMap(query, id);		
		return employee;
	}
}

HelloService.java

@Service
public class HelloService {
	@Autowired
	private HelloRepository repository;
	
	public Employee getEmployee(String id) {
		Map<String, Object> map = repository.findById(id);
		
		String employeeId = (String) map.get("id");
		String name = (String) map.get("name");
		int age = (Integer) map.get("age");
		
		Employee employee = new Employee();
		employee.setEmployeeId(employeeId);
		employee.setEmployeeName(name);
		employee.setEmployeeAge(age);
		
		return employee;
	}
}

HelloController.javaに追記

	@Autowired
	private HelloService service;
	
	@PostMapping("/hello/db")
	public String postDbRequest(@RequestParam("eid") String id, Model model) {
		Employee employee = service.getEmployee(id);
		model.addAttribute("employee", employee);
		return "hello/db";
	}

src/main/resources/templates
db.htmlを作成

        <p th:text="${employee.employeeId}"></p>
        <p th:text="${employee.employeeName}"></p>
        <p th:text="${employee.employeeAge}"></p>

 

hello.htmlに追記

        <form method="post" action="/hello/db">
            <input type="text" name="eid" th:value="${eid_value}">
            <button>送信</button>
        </form>

 

H2データベースのコンソール
http://localhost:8080/h2-console
JDBC URL: jdbc:h2:mem:testdb

 

 

 

 

SpringBoot入門:環境構築

参考書はこちらを選択(Kindle Unlimitedで無料で読めるので)
Spring 解体新書

 

環境構築


IDE
Spring Tools 4 for Eclipse
https://spring.io/tools/
windows版をダウンロード、任意の場所に配置して「java -jar spring-tool-suite-xxx.jar」
sts-x.x.x.RELEASEの中のSpringToolSuite4.exeが本体

 

Pleiadesの日本語化プラグイン
https://willbrains.jp/
Pleiades プラグイン・ダウンロードからWindowsをダウンロード
解凍してsetup.exe
先ほどのSpringToolSuite4.exeを選択して日本語化

 

Lombokインストール
https://projectlombok.org/download
java -jar lombok.jar
SpringToolSuite4.exeを選択してインストール

 

Spring Tools 4の設定
コード補完の設定
ウィンドウ→設定→Java→エディタ→コンテンツアシスタント
Javaの自動有効化トリガー
.abcdefghijkemnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_
※デフォルトだと.を入力した時しか補完されない
「Enter以外の挿入トリガーを使用不可にする」にチェック

Ctrl + Shift + Fでコード整形

 

新規Springスタータープロジェクトの作成
追加ライブラリ
Spring Boot DevTools, Lombok, JDBC API, Spring Data JDBC, H2 Database, Thymeleaf, Spring Web

 

src/main/resources/templates
hello.htmlを作成

<html xmlns:th="http://www.thymeleaf.org">
    <body>
        Hello World
    </body>
</html>

 

src/main/java/com.example.demo/hello
HelloController.javaを作成

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloController {
	@GetMapping("/hello")
	public String getHello() {
		return "hello";
	}
}

プロジェクトを右クリック→実行→SpringBootアプリケーション
http://localhost:8080/hello

Java入門

筆者はPHPを習得しているので環境構築くらいしか書くことがない。

(言語の違いで気づいたことがあれば追記していく)

 

JavaDriveでJava入門
https://www.javadrive.jp/start/

 

JDKのインストール
https://jdk.java.net/
Ready for use: JDK XXをクリック
BuildsからWindowsのzipをダウンロード
任意のディレクトリに展開

 

環境変数の設定
検索窓に「環境変数」と入力して環境変数Windowを開く
ユーザー環境変数かシステム環境変数に「JAVA_HOME」を追加
変数値には先ほど配置したパスを指定「C:\xxx\jdk-xx.x.x」
「Path」の編集で、新規→「%JAVA_HOME%\bin」を追加
コマンドプロンプトで「javac -version」で確認

 

公式ドキュメント
https://www.oracle.com/jp/java/technologies/documentation.html
該当バージョンのリンク日本語→左メニューのAPIドキュメント

 

Hello, World
Hello.java

class Hello {
  public static void main(String[] args) {
    System.out.println("Hello");
  }
}

 

コンパイル
javac Hello.java
実行
java Hello

 

サンプルプログラム

import java.time.LocalDate;

class Sample {
  public static void main(String[] args) {
  	final int MAX_LEVEL = 100;
  	
  	System.out.println(MAX_LEVEL);
  	
  	LocalDate ld = LocalDate.now();
    System.out.println(ld);
  	
  	//配列
  	int[] nums = new int[3];
  	nums[0] = 1;
  	nums[1] = 2;
  	nums[2] = 3;
  	
  	for (int i = 0; i < 3; i++) {
  		System.out.println(nums[i]);
  	}
  	
  	//こうも書ける
  	int[] nums2 = {1, 2, 3};
  	for (int num : nums2) {
        System.out.println(num);
    }
  	
  	//String型や配列型は参照型なので、代入すると同じものを参照する
  	int[] others = nums2;
  	nums2[0] = 4;
  	// 同じものを参照しているので、4になる
    System.out.println(others[0]);
  	
  	int[] others2 = nums2.clone();
  	nums2[0] = 5;
  	// cloneだと別オブジェクトになるので5にならない
    System.out.println(others2[0]);
  }
}

 

 

Compositeパターン

容器と中身の同一視。
ファイルシステムでは、ディレクトリとファイルが入れ子になっている。
ディレクトリとファイルは異なるものですが、「ディレクトリに入るもの」とみなしている。

Leaf(葉):MyFile
中身
Composite(複合体):MyDirectory
容器
Component:Entry
LeafとCompositeを同一視するためのスーパークラス
Client(依頼者):Main

他にも複数と単数の同一視など。

Entry.php

abstract class Entry {
  abstract function getName();
  abstract function getSize();
  function add(Entry $entry) {
    throw new Exception("FileTreatmentException");
  }
  abstract function printList($prefix=null);
  function toString() {
    return $this->getName() . "(" . $this->getSize() . ")";
  }
}

MyFile.php

class MyFile extends Entry {
    private $name;
    private $size;
    function __construct(String $name, int $size) {
        $this->name = $name;
        $this->size = $size;
    }
    function getName() {
        return $this->name;
    }
    function getSize() {
        return $this->size;
    }
    function printList($prefix=null) {
        echo $prefix . "/" . $this->toString() . "\n";
    }
}

MyDirectory.php

class MyDirectory extends Entry {
    private $name;
    private $directory = [];
    function __construct(String $name) {
        $this->name = $name;
    }
    function getName() {
        return $this->name;
    }
    function getSize() {
        $size = 0;
        foreach ($this->directory as $entry) {
            $size += $entry->getSize();
        }
        return $size;
    }
    function add(Entry $entry) {
        $this->directory[] = $entry;
        return $this;
    }
    function printList($prefix=null) {
        echo $prefix . "/" . $this->toString() . "\n";
        foreach ($this->directory as $entry) {
            $entry->printList($prefix . "/" . $this->name);
        }
    }
}

Main.php

require "../autoload.php";
echo "Making root entries...\n";
$rootdir = new MyDirectory("root");
$bindir = new MyDirectory("bin");
$tmpdir = new MyDirectory("tmp");
$usrdir = new MyDirectory("usr");
$rootdir->getName();
$rootdir->add($bindir);
$rootdir->add($tmpdir);
$rootdir->add($usrdir);
$bindir->add(new MyFile("vi", 10000));
$bindir->add(new MyFile("latex", 20000));
$rootdir->printList();

 

Mementoパターン

状態を保存しておいて、復元できるようにしておく。
undo,redo,history,snapshot

復元するためにインスタンスの内部情報を公開すると、カプセル化の破壊になるので、
インタフェースを使い分ける。

Originator(作成者):Gamer
自分の現在の状態を保存したいときにMementoをつくる。
以前のMementoを渡されると、その状態に戻る。
Memento(記念品):Memento
Originatorの情報を持っているが、誰にでも公開はしない。
広いインタフェース→オブジェクトを元に戻すために内部情報を得られるメソッド。Originatorだけが使える。
狭いインタフェース→Caretakerに見せるもの。
Caretaker(世話をする人):Main
Originatorの状態を保存したいときに、Originatorに伝える。
OriginatorはMementoをCaretakerに渡す。
CaretakerはMementoの狭いインタフェースしか使えないので、Mementoの内部情報をいじることはできない。

Memento.php

class Memento {
    private $money;
    private $fruits = [];
    function __construct($money) {
        $this->money = $money;
    }
    function getMoney() {
        return $this->money;
    }
    function addFruit($fruit) {
        $this->fruits[] = $fruit;
    }
    function getFruits() {
        return $this->fruits;
    }
}

Gamer.php

class Gamer {
    private $money;
    private $fruits = [];
    private $fruitNames = ["夕張メロン","すいか","もも","なし"];
    function __construct($money) {
        $this->money = $money;
    }
    function getMoney() {
        return $this->money;
    }
    function bet() {
        $dice = rand(1, 6);
        if ($dice == 1) {
            $this->money += 100;
            echo "所持金が増えました\n";
        } else if ($dice == 2) {
            $this->money /= 2;
            echo "所持金が半分になりました\n";
        } else if ($dice == 6) {
            $f = $this->getFruit();
            echo "フルーツ(" . $f . ")をもらいました\n";
            $this->fruits[] = $f;
        } else {
            echo "何も起こりませんでした\n";
        }
    }
    function createMemento() {
        $m = new Memento($this->money);
        foreach ($this->fruits as $f) {
            if (strpos($f, "おいしい") !== false) {
                $m->addFruit($f);
            }
        }
        return $m;
    }
    function restoreMemento(Memento $memento) {
        $this->money = $memento->getMoney();
        $this->fruits = $memento->getFruits();
    }
    function toString() {
        return "[money = " . $this->money 
        . ", fruits = " . implode(",", $this->fruits) . "]";
    }
    private function getFruit() {
        $prefix = rand(0, 1) ? "おいしい" : "";
        return $prefix . $this->fruitNames[rand(0, count($this->fruitNames) - 1)];
    }
}

Main.php

require "../autoload.php";
$gamer = new Gamer(100);
$memento = $gamer->createMemento();
for ($i=1;$i<=100;$i++) {
    echo $i . ":" . $gamer->toString() . "\n";
    $gamer->bet();
    echo "所持金:" . $gamer->getMoney() . "\n";
    if ($gamer->getMoney() > $memento->getMoney()) {
        echo " (保存)\n";
        $memento = $gamer->createMemento();
    } else if ($gamer->getMoney() < $memento->getMoney() / 2) {
        echo " (復元)\n";
        $gamer->restoreMemento($memento);
    }
    sleep(1);
}