文章AとBの類似率を数値化するJaccard係数をシェル・sqlite・mecabで実現してみた

はじめに このブログの記事Aと記事Bがどれだけ類似しているかを検出して、関連記事を自動化したいと思った。そこで簡単に思いつく方法は、それぞれの記事のキーワードを抽出し、お互いどれだけ共通のキーワードを持っているか調べれば良さそう。 そこでJaccard係数という手法を見つけた。 Jaccard係数とは Jaccard係数は、2つの集合 ( A ) と ( B ) の類似度を測る数学的なアプローチ。 $$ J(A,B)=\frac{|A\cap B|}{|A\cup B|} $$ 記事Aと記事Bのキーワードに当てはめて集合を考えると、 重複を取り除いた記事Aと記事Bのキーワードの合計が分母 重複する部分のキーワードだけを抽出したのが分子 となる。そしてこの割り算の結果をJaccard係数とし、 係数が大きいほど類似度が高いことを意味する。 Jaccard係数はsqliteで簡単に計算できる 次は、実際にこのブログサイトで関連記事を作成するために使っているSQLである。 全ての記事に対してJaccard係数を計算し、係数が0.1以上のものを関連記事として抽出する処理をさせている。 WITH target_words AS ( SELECT word FROM keywords WHERE filename = '__FILENAME__' ), intersections AS ( SELECT k.filename, COUNT(*) AS intersect_count FROM keywords k JOIN target_words t ON k.word = t.word WHERE k.filename != '__FILENAME__' GROUP BY k.filename ), unions AS ( SELECT k.filename, COUNT(DISTINCT k.word) + (SELECT COUNT(DISTINCT word) FROM target_words) - COUNT(DISTINCT CASE WHEN k.word IN (SELECT word FROM target_words) THEN k.word END) AS union_count FROM keywords k WHERE k.filename != '__FILENAME__' GROUP BY k.filename ) SELECT i.filename, CAST(i.intersect_count AS REAL) / u.union_count AS jaccard FROM intersections i JOIN unions u ON i.filename = u.filename WHERE CAST(i.intersect_count AS REAL) / u.union_count >= 0.1 ORDER BY jaccard DESC; 複雑に入り組んでいて読みにくいが、Jaccard係数を計算するために共通部分の要素を求めるintersectionsと、キーワードの和集合を求めるunionsがポイントである。 ...

公開: 2025年4月3日 · 更新: 2026年3月25日 · Toshihiko Arai

Ubuntuでnginxを導入して最初の公開設定をする手順

Ubuntu で nginx を触り始めるとき、最初に迷いやすいのは「どこまで設定すればひとまず公開できるのか」が見えにくいことです。この記事では、nginx をインストールしてブラウザから確認できる状態にし、必要なら HTTPS 化と www ありなし統一まで進める流れ をまとめます。 最初に読むべき範囲は次の4つです。 nginx のインストール 起動確認と公開確認 ドキュメントルート変更 HTTPS 化と www ありなし統一 後半の PHP、404、ログ、rewrite は、必要になったときに読む応用設定として残しています。 nginx をインストールして最初の公開確認をする アプリケーションインストール前のおまじない 初回実行時は時間がかかる場合があります。 以下のコマンドでパッケージ情報を更新・アップグレードします。 sudo apt-get update sudo apt-get upgrade nginx のインストール 次のコマンドで nginx をインストールします。 sudo apt install -y nginx インストール確認 以下のコマンドで nginx のバージョンが表示されれば、インストールは成功です。バージョン番号は環境によって異なるため、出力例と完全一致する必要はありません。 nginx -v # 出力例: nginx version: nginx/1.xx.x (Ubuntu) nginx の起動と公開確認 起動確認 nginx のインストールと同時にウェブサーバーは自動起動されます。 起動状況は以下のコマンドで確認できます。 sudo systemctl status nginx 出力例: ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2022-10-20 15:15:44 JST; 53s ago Docs: man:nginx(8) Process: 36839 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Process: 36840 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Main PID: 36934 (nginx) Tasks: 3 (limit: 1033) Memory: 7.0M CPU: 40ms CGroup: /system.slice/nginx.service ├─36934 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; ├─36937 nginx: worker process └─36938 nginx: worker process 自動起動設定 起動・有効化: ...

公開: 2025年3月15日 · 更新: 2026年4月19日 · Toshihiko Arai
クロスバイクのシングルスピード化への道

クロスバイクのシングルスピード化への道

クロスバイクをシングルスピード化!シンプルな走りで80kmも楽々完走 ピストバイクとは無縁だった私が、シングルスピードというシンプルな世界に興味を持った。調べていくうちに、その無駄を削ぎ落とした考え方に惹かれたのだ。以前の クロスバイクの軽量化10kg台→8kg台 の流れもあり、挑戦する価値は十分にあると感じた。 最初に結論を書くと、クロスバイクのシングルスピード化は「古いクロスバイクを軽く、静かに、シンプルに乗りたい人」にはかなり相性がいい。一方で、激坂を楽に登りたい人や、細かくケイデンスを合わせたい人には向かない。 この記事でわかること クロスバイクをシングルスピード化するのに必要なパーツ 実際に選んだギア比とチェーンライン調整の考え方 80km、110km、山手線一周57kmを走って感じたメリット 既存のクロスバイクをベースにカスタムするのが向いている人 先に結論だけ知りたい人向け 最小構成は4点 : チェーンリング、シングルスピード変換キット、1/8チェーン、チェーンテンショナー まず試しやすいギア比 : 私はフロント38T × リア17Tから始めた 実走の印象 : 変速の手間が消え、車体が軽くなり、街乗りから長距離までかなり快適 注意点 : エンド幅、チェーンライン、チェーン幅の相性確認は必須 今回使った主なパーツ パーツ 用途 記事内リンク チェーンリング 38T 104BCD Mutte MTB レース バイク シングル フロントをシングル化 38T化で巡航しやすくなった シングルスピード変換キット リアを単速化 コグとスペーサーでチェーンライン調整 シマノ チェーン(内装ハブ&シングルスピード) CN-NX10 1/8 114L 1/8チェーン化 コグとの相性が良かった チェーンテンショナー シングルスピード チェーン張り調整 ディレイラー撤去時に必要 上の4点が揃えば、まずは「変速付きクロスバイクをシングルスピード化して走る」ところまでは持っていける。以下で実際の交換内容と、使ってみて分かった注意点を書いていく。 シングルスピード化の手順 私が行った作業は以下の通り。 フロントギアをシングルギアへ交換 リアのカセットスプロケットを外し、スペーサーとコグを取り付ける リアディレイラーを外し、チェーンテンショナーを装着 シフトレバーを取り外し、ブレーキレバーのみの構成に チェーンを1/8へ変更 各パーツの交換方法については、サイクルベースあさひのサイトやYouTube動画が非常に参考になった。 カートリッジBB&クランクの着脱 チェーンの交換方法 スプロケット交換 ここでは全体の流れを説明し、細かな交換手順は省略する。 ...

公開: 2025年2月10日 · 更新: 2026年4月16日 · Toshihiko Arai
クロスバイクの軽量化10kg台→8kg台【TREK FX7.4】

クロスバイクの軽量化10kg台→8kg台【TREK FX7.4】

はじめに この記事では、10年来愛用してきた TREK FX7.4 を、オーバーホールを兼ねて軽量化した記録をまとめます。実測 10.25kg だった車体を、パーツ交換とフロントシングル化で 8.8kg まで軽くしました。 きっかけは 鎌倉へサイクリング したときの輪行です。自転車を持ち上げて移動すると、車体重量の差がそのまま疲れやすさに出ます。登山を始めて装備重量を意識するようになったこともあり、クロスバイクでも軽さを見直すことにしました。 TREK FX7.4 の公称重量は 10.55kg だが、パーツの変更により実測値は 10.25kg だった。今回の軽量化の結果、9kg台を下回る 8.8kg まで軽くすることに成功したので、その過程を紹介する。 先に要点 大きく効いたのは、サドル、シートポスト、グリップ、ペダル、フロントシングル化です カーボン部品は軽い一方で、締め付けや滑り対策に気を使います ホイール交換はエンド幅などの相性確認が必要で、この記事の構成では少し難ありでした 軽量化は安全に関わるので、無理な加工や不安のある固定は避け、必要なら自転車店で確認する前提で進めます 軽量化を進めるにあたって、以下のようなポイントに注目した。 サドル・シートポストの軽量化 :軽量カーボン製品へ変更。 ホイール・タイヤの変更 :ホイールの交換とクイックレリーズの見直し。 ハンドル周りの調整 :グリップ、ハンドル、ステムの交換。 ペダルの変更 :より軽量なモデルへ。 フロントギアのシングル化 :ディレイラーを廃止し、構成をシンプル化。 サドルをTIOGAへ交換(-93g) サドルの変更は、軽量化だけでなく見た目の美しさも向上させる。 モデル名 重量 Bontrager H1 307g TIOGA スパイダーツインテール2 214g 軽量で美しいデザインが魅力のサドル。カーボン製で軽量だが、振動が直接伝わりやすいためお尻が痛くなるかなと思ったが、全然そんなことはない。付属の滑り止めゴムパッドも付いているが、外した状態で100km越えも全く問題なかった。もちろん レーサーパンツ の着用も必要ない。 シートポストをカーボンへ交換(-131g) モデル名 重量 Bontrager Nebula 321g ROADNADO フルカーボン 190g ROADNADO フルカーボン ※カット済み 154g ROADNADO フルカーボンで検索 ...

公開: 2025年1月31日 · 更新: 2026年4月29日 · Toshihiko Arai
荒川付近で見られる野鳥〜岩渕水門から浮間公園あたり〜2025年の記録

荒川付近で見られる野鳥〜岩渕水門から浮間公園あたり〜2025年の記録

はじめに 関東の荒川、 岩渕水門 から浮間公園あたりで撮影した野鳥の記録です。写真はすべて2025年1月以降、この一年未満のあいだに撮影したものです。 このあたりは水辺、草地、木立が近い距離にまとまっていて、散歩やサイクリングの途中でも観察しやすい場所です。モズやジョウビタキのような小鳥、カワセミ、カモ類、サギ類まで、季節ごとに見える顔ぶれが変わります。 野鳥に興味を持つと、それまで雑音だった鳴き声が、意味を持ちはじめます。 「いま鳴いたのは誰だろう」と立ち止まり、 姿を探し、双眼鏡を向け、 やがて写真に残したくなる。 荒川の土手を歩く時間は、そんな小さな発見の連続です。 モズ ちょうどヒヨドリくらいの大きさだろうか。モズは肉食で、嘴がタカのように少し曲がっている。口の下に髭が伸びている。上の写真はモズのメス。モズのオスは、下の写真のように、過眼線(かがんせん)が黒く濃くなっている。 ジョウビタキ 浮間公園あたりの荒川サイクリングロード沿いの木々の中に、ジョウビタキのメスを発見。 頭は銀白色で、顔は黒く、お腹は鮮やかなオレンジ色をしているのがオスである。 オナガ 浮間公園で撮影。その名の通り尾がだいぶ長いため、大きく見える。からだ自体の大きさはヒヨドリくらいだろうか。 エナガ 浮間公園あたりの荒川サイクリングロード沿いの木々の中に、エナガの群れを発見。とても小さく、木の枝をすばしっこく移動する。 メジロ はじめスズメかと思ったが、よく観察するとメジロだった。すばしっこく自由に動き回る。警戒心も非常に強いためシャッターチャンスが難しいが、録画した動画から画像を抜き取って、なんとか写真化に成功。葉っぱと同化して保護色になっているため、遠目からは目立たない。 改めて動画を見返すと、葉っぱを食べ漁っている幼虫をて探している様子。 ガビチョウ はじめメジロかと思ったが、メジロよりも少し大きく単独で行動しており、メジロよりも落ち着いている様子。図鑑で調べるとガビチョウらしい。中国に生息している鳥だが、数十年ほど前から野生化し、日本で繁殖しまっているようだ。 シジュウカラ ッピィーッピィーッピィーッピィーと鳴くシジュウカラ。特徴的な鳴き声なので、その存在には気づきやすい。胸のネクタイ模様も特徴的。 カワセミ ...

公開: 2025年1月23日 · 更新: 2026年5月3日 · Toshihiko Arai
Anker Solix PS30 Portable Solar Panel ソーラーパネルレビュー

Anker Solix PS30 Portable Solar Panel ソーラーパネルレビュー

この記事は、防災対策として購入した Anker Solix PS30 Portable Solar Panel を、冬の窓越しと屋外で実際に使ってみた記録です。 30W・約960g・折りたたむとA4に近いサイズなので、停電時の予備電源、登山・旅行で荷物に忍ばせるサブ電源、日常のスマホ・モバイルバッテリー充電のどれに向くのかを、実体験ベースで整理しました。先に結論を書いておくと、 常時携帯して歩きながら使うよりは、晴れた日に据え置きで使うのが現実的 という印象です。 特徴は以下のとおりです。 合計で30W出力のソーラーパネル 最大15W出力のUSB-Cポートと最大12W出力のUSB-Aポートを搭載 モバイルバッテリーやスマホを2台同時に充電可能 持ち運びに便利なコンパクトサイズに折りたためる 使用上の注意(実体験ベース) カラビナホールがあるのでリュックなどにぶら下げながら充電できそうに見えますが、自分が試した範囲では、直射日光がしっかり当たっていないと充電が安定しませんでした。リュックにぶら下げて街中を歩く想定だと、 太陽光を常に背中側へ受け続ける向きをキープしないといけない ので、現実には難しい場面が多そうです。 また、光量が足りないときは充電モードの起動と切断を短い間隔で繰り返すことがありました。デバイスへの負荷がどの程度かはケースバイケースだと思いますが、 「歩きながら持続的に充電する用途」というよりは「日当たりの良い場所に置いて据え置きで使う用途」のほうが安心 という感覚です。 もし最初から据え置きでがっつり発電したい場合は、より出力の大きい Anker Solix PS100 Portable Solar Panel ソーラーパネル 100W 防塵防水IP67対応 折り畳み式 のような上位モデルも選択肢です。ただし PS100 はポータブル電源(ポタ電)への充電が前提で、本体も4.6kg前後と重め。 登山やちょっとした旅行で気軽に持ち出すには大きすぎる ので、用途で住み分けるのが現実的かなと思います。 その点、 Anker Solix PS30 Portable Solar Panel は 約960g・折りたたみ時はA4に近いサイズ で、防災袋・登山ザック・旅行カバンに入れておきやすいのが大きな利点です。 充電速度(冬の窓越しで試した実例) 肝心の充電速度ですが、TORRAS の10000mAhモバイルバッテリーで試してみました。バッテリーを使い切った状態からスタートして、写真のように窓枠にパネルを引っ掛けて、 冬の晴れた日に7:30〜15:30の約8時間、太陽の光に当てっぱなしにする という条件です。 結果は モバイルバッテリーのインジケーターが3メモリまで点灯する程度 まで回復しました。表示上の目安なので正確な mAh は出せませんが、感覚的には6000mAh前後は充電できていそうな印象です。スモークがかった窓越しでもここまで充電できたので、 同じ時間でも屋外で直射日光に当てれば、もう少し多めに見込める可能性は高そう です。逆に、曇りの日や日照時間が短い時期は素直にこれより減ると考えておくとよさそうです。 iPhone 15 Pro のバッテリー容量は約3,274mAh とされているので、 「スマホを1日使った分を、晴れた日のソーラーで取り戻す」用途なら現実的なライン という肌感です。動画撮影を多めにする日や、複数台同時充電したい日は、これだけで賄うというより、モバイルバッテリーと組み合わせて運用するのが安心です。 Anker Solix PS30 Portable Solar Panel はスリムなので、必要に応じて2枚3枚と並べても置き場所に困りにくいのも嬉しいところです。 ...

公開: 2025年1月9日 · 更新: 2026年6月2日 · Toshihiko Arai
裏高尾・奥高尾探訪:高尾周辺の自然を巡る登山記

裏高尾・奥高尾探訪:高尾周辺の自然を巡る登山記

JR高尾駅、高尾山、城山、小仏峠、相模湖駅、藤野駅、陣馬山、景信山を歩いた高尾周辺の登山記録です。この記事では、3本の山行を距離、所要時間、のぼり・くだり、当日の写真と動画でまとめています。 軽めに高尾から相模湖へ抜けるなら 2024/12/07 のコース、陣馬山を含めて歩きたいなら 2024/12/21 のコース、富士見台・小下沢・景信山までしっかり歩きたいなら 2025/01/11 のコースが読みどころです。最後のコースは距離も獲得標高も大きめなので、日帰り登山に慣れてきた方向けの記録として読んでください。 JR高尾駅→高尾山→城山→小仏峠→JR相模湖駅(2024/12/07) 動画を再生 項目 値 出発 9時33分(JR高尾駅) 到着 14時04分(JR相模湖駅) タイム 4時間31分 距離 15.2km のぼり 948m くだり 920m YAMAP 活動データ https://yamap.com/activities/36430287 JR藤野駅→陣馬山→JR相模湖駅(2024/12/21) 動画を再生 項目 値 8時00分 出発(JR藤野駅) 10時20分 陣馬山頂 14時03分 到着(JR相模湖駅) タイム 6時間3分 距離 12.8km のぼり 853m くだり 871m ...

公開: 2024年12月28日 · 更新: 2026年5月1日 · Toshihiko Arai
東京サバイブ|ビクトリノックスで日常のミニマル化

東京サバイブ|ビクトリノックスで日常のミニマル化

はじめに この記事は、3000円未満で買える VICTORINOX クラシック SD を、日常の文房具・登山・旅行の3シーンで兼用してみた記録です。 ハサミ・ナイフ・つめやすり・マイナスドライバー・ピンセット・爪楊枝までひとまとめにできるので、ペン立てや文房具ケース、登山の小物入れ、旅行ポーチを同時に小さくできます。後半では追加購入した VICTORINOX ネイルクリッパーも紹介します。 私には縁がないと思っていたマルチツール。しかし、最近趣味にしている登山の入門書籍にVICTORINOX(ビクトリノックス)のマルチツールが紹介されており、興味を持つことになった。見た目のかっこよさから高価なものだと思い込んでいたが、価格帯はピンからキリまでのようで、今回購入したツールなんかは3000円未満で買える。この性能と美しいデザインを考えると驚くほど低価格だ。 登山だけに使うのはもったいないと思い、日常生活でも活用してみることにした。所持していたハサミやカッター、ヤスリなどをビクトリノックスに置き換えることで、断捨離を実践だ。 東京サバイブ 登山やキャンプ、旅行のためだけに道具を揃えるのはあまり好きではない。なぜなら趣味のためだけに荷物置き場が増えるからだ。だからレジャーしていない時でもそれらの道具を日常的に使いたいと思っている。 登山ウェアを普段着にしたり、防寒具としてシェラフを布団代わりにしたりと。デイキャンプ用の電気式クーラーボックスを冷蔵庫代わりに使っているほどだ。 (この工夫で食材管理がしやすくなり、食品ロスが減り電気代も劇的に安くなったので、どこかの記事で紹介できたらと思う) こうした生活スタイルを私は 「東京サバイブ」 と勝手に呼んで楽しんでいる。 今回は、日常的に使用する文房具をビクトリノックスに代替してみた。以下では、購入したビクトリノックスのマルチツールの魅力を紹介する。 ハサミ 日常生活での用途には十分。確かに小さくて使いづらい面もあるが、このミニマルサイズの魅力は絶大だ。紙の封を切るにもワンカットずつ進む感覚が楽しい。「ハサミで切っている」行為自体を再発見させてくれる。このハサミにすっかり慣れた頃、普通のハサミを使った際にはきっとあまりの使いやすさに感動することだろう。 向く用途は、封筒・タグ・薬の個包装・荷札の紐など、長くても数センチで切り終わるもの。逆に厚手の段ボールや髪を整える用途には向かないので、家用のハサミと完全に置き換えるというよりは、外出時と作業机上の常備に使うのが現実的です。 ナイフ ペーパーナイフやカッターの代用として使用可能。鋭い切れ味で、木材も綺麗に切れそうだ。ただし、開閉時には手を切らないように注意が必要。鉛筆などの木材も綺麗に削れそうな鋭さがある。 なお、日本では刃体6cm超のナイフを正当な理由なく持ち歩くと銃刀法に触れる可能性があります。クラシック SD のナイフは6cm未満ですが、登山・キャンプ・釣りなど用途がはっきりしている場面で使い、街中での常時携帯は避けるのが無難です。また、機内持ち込み手荷物には入れられないので、飛行機を使う旅行では預け入れ荷物に回します。 つめやすり 爪のささくれを整えるのに便利。登山や野外で手作業する際には重宝しそうだ。頻繁に日常で使えば爪切りが不要になるかもしれない。このツールにさらに爪切りが備わっているものもあるが、短時間の登山やキャンプではマルチツールに付属のやすりで十分だろう。 ビクトリノックスのミニマルな魅力にすっかりハマってしまって、爪切りも別途購入している。こちらは旅行はもちろん、日常の爪切りとして代替する。 ネイルクリッパー単体は刃が短く、機内持ち込み手荷物にも入れられるので、登山・出張・旅行ポーチに常備しやすいのが利点です。ただし爪を切る力はフルサイズ爪切りより弱いので、爪が厚い・硬い方は家用のしっかりした爪切りと併用するのが向いています。 ドライバー ヤスリの先端がマイナスドライバーになっている。写真の通り、プラスドライバーのネジも開けられる。頑丈な構造で、使用中に軸が曲がる心配はなさそう。 ピンセットと爪楊枝 しばらく使ってから気づいたが、なんとピンセットと爪楊枝も備わっていた。ピンセットはトゲ抜きに、爪楊枝は野外での食事に便利だ。爪楊枝はプラスチック製で衛生面に気をつければ何度も使える。 小型化と軽量化に成功 今までお世話になったハサミやカッター、爪切りなどは、このビクトリノックスに置き換えることで断捨離できた。ビクトリノックスはベルトにぶら下げられるので、工具を探す煩わしさがなくなり、文房具ケースもいらなくなったわけだ。 ビクトリノックスのマルチツール(21g)と追加購入した爪切り(11g)を合わせても32g。圧倒的な小型化と軽量化の実現に成功だ。もちろんビクトリノックスのおかげである。 モノと自分はイコールではない 最近熟読している書籍『僕たちにモノはもう必要ない』では、モノへの執着を捨てることを提唱している。私のビクトリノックスで代替した行為は、もしかしたらモノへの執着かもしれない。 また、中田敦彦氏のYouTube大学でミニマリストに関する動画を見たとき、「ヴィトンのバッグを持っていれば、自分はヴィトンになれた気がする」や「米津玄師のマニアックな曲を知っている俺はもうほぼ米津!」という面白い解説があった。解説には笑ったが、要は 自分が持っているモノで自分の価値が高まったわけではない のだ。 書籍でも述べられていたが「人は自分が持っているモノで自分の価値を表現できると思いがち」なことに注意しなければならない。 だから間違っても「ビクトリノックスを持っている俺はかっこいい」などと思うべきではないのだ。もちろん、ビクトリノックスがかっこいいのは私にとっては事実。そして、このツールに触れている時間は純粋に楽しい。 関連記事 裏高尾・奥高尾探訪:高尾周辺の自然を巡る登山記 … ビクトリノックスを最初に連れて行った登山フィールド。日帰り装備の参考に コンロをやめてOD缶・CB缶で自炊する。限られた火力で暮らすことで、資源への感覚をリセット … キャンプ道具を日常に取り込む「東京サバイブ」の延長 Anker Solix PS30 Portable Solar Panel ソーラーパネルレビュー … 防災・旅行で兼用しやすい小型ガジェットの記録 関連アイテムをAmazonで探す VICTORINOX クラシック SDをAmazonで探す VICTORINOX ネイルクリッパーをAmazonで探す ぼくたちに、もうモノは必要ない。をAmazonで探す

公開: 2024年12月28日 · 更新: 2026年6月1日 · Toshihiko Arai

はじめての Spring Boot 〜 JavaでWebアプリケーション

はじめに Spring Boot を使って Java の Web アプリケーションを構築する方法を解説します。仕事で Spring Boot を使うことがあったので、全体像を把握したくて学習してみました。 この記事では、IntelliJ IDEA を利用してプロジェクトを作成し、MySQL データベースとの連携、そして MyBatis を使ったデータ操作を実現します。最後に、取得したデータを Thymeleaf を使ってブラウザに表示します。 開発環境の準備 まずは IntelliJ IDEA を使って Spring Boot プロジェクトを新規作成します。 新規プロジェクトの作成 IntelliJ IDEA の「新規プロジェクト作成」から Spring Boot を選択します。 次のように設定を行います: 言語:Java ビルドシステム:Gradle Groovy JDK:JetBrains Runtime 17.0.11 次の画面で必要なモジュールを選択します。今回は次の依存パッケージを選択しました。 Lombok Spring Web Thymeleaf MyBatis Framework MySQL Driver データベースの用意 次に、MySQL データベースに接続するための準備を行います。 テーブル作成 MySQL に以下のテーブルを作成しました。 CREATE DATABASE hellodb; USE hellodb; CREATE TABLE user ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); デモデータを追加: ...

公開: 2024年11月30日 · 更新: 2026年5月23日 · Toshihiko Arai

iOSアプリ開発でSQLiteを使う FMDB

iOSアプリ開発でSQLiteを使う FMDB はじめに iOSアプリ開発で、SQLiteを使ってデータ管理する方法を調べてみました。SQLiteをそのまま使うよりは、SQLiteをラッパーしたFMDBライブラリを使うとより便利です。そちらもご紹介いたします。 iOSアプリ開発ではじめてSQLiteを使う libsqlite3.tbdをプロジェクトに追加 libsqlite3.tbdをプロジェクトに追加します。 Xcodeのプロジェクトナビゲータでプロジェクト名を選択し、「Build Phases」タブに移動します。「Link Binary With Libraries」セクションで、+ボタンを押して、libsqlite3.tbdを追加します。 ソースコード // // ViewController.swift // SampleSqlite // // Created by Toshihiko Arai on 2024/10/11. // import UIKit import SQLite3 // 日本語文字を登録するために必要な定数 let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self) class ViewController: UIViewController { var db: OpaquePointer? override func viewDidLoad() { super.viewDidLoad() // データベースの準備 if let databasePath = createDatabase() { openDatabase(path: databasePath) createTable() insertData(name: "空条承太郎", age: 40) insertData(name: "空条徐倫", age: 17) fetchData() } } // データベースのパスを取得して作成 func createDatabase() -> String? { let fileURL = try? FileManager.default .url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) .appendingPathComponent("sample.sqlite") return fileURL?.path } // データベースのオープン func openDatabase(path: String) { if sqlite3_open(path, &db) != SQLITE_OK { print("データベースを開くことができません") } } // テーブルの作成 func createTable() { let createTableString = """ CREATE TABLE IF NOT EXISTS Person( Id INTEGER PRIMARY KEY AUTOINCREMENT, Name CHAR(255), Age INTEGER); """ var createTableStatement: OpaquePointer? if sqlite3_prepare_v2(db, createTableString, -1, &createTableStatement, nil) == SQLITE_OK { if sqlite3_step(createTableStatement) == SQLITE_DONE { print("テーブルの作成に成功しました") } else { print("テーブルの作成に失敗しました") } } else { print("テーブル作成の準備に失敗しました") } sqlite3_finalize(createTableStatement) } // データの挿入 func insertData(name: String, age: Int32) { let insertStatementString = "INSERT INTO Person (Name, Age) VALUES (?, ?);" var insertStatement: OpaquePointer? if sqlite3_prepare_v2(db, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK { sqlite3_bind_text(insertStatement, 1, name, -1, SQLITE_TRANSIENT) sqlite3_bind_int(insertStatement, 2, age) if sqlite3_step(insertStatement) == SQLITE_DONE { print("データの挿入に成功しました") } else { print("データの挿入に失敗しました") } } else { print("挿入ステートメントの準備に失敗しました") } sqlite3_finalize(insertStatement) } // データの取得 func fetchData() { let queryStatementString = "SELECT * FROM Person;" var queryStatement: OpaquePointer? if sqlite3_prepare_v2(db, queryStatementString, -1, &queryStatement, nil) == SQLITE_OK { while sqlite3_step(queryStatement) == SQLITE_ROW { let id = sqlite3_column_int(queryStatement, 0) let name = String(cString: sqlite3_column_text(queryStatement, 1)) let age = sqlite3_column_int(queryStatement, 2) print("Query Result:") print("ID: \(id), Name: \(name), Age: \(age)") } } else { print("クエリの準備に失敗しました") } sqlite3_finalize(queryStatement) } } SQLiteのデータ型 SQLiteには4つの基本的なストレージクラス(データ型)があります。 ...

公開: 2024年10月11日 · 更新: 2026年2月25日 · Toshihiko Arai