[[FrontPage]] *概要 [#k685ac99] -世界的に使われている言語 -必ずintelliJを使う! *疑問 [#p4443f40] -intelliJの外部ライブラリと、pomで書く依存関係ってどう違うの? -intelliJのMavenのところのdeployとかtestってどうやって使うの? -public static void...のstaticってどういう意味?どういう時に必要なの? -アットマークで指示しているものはなに? -アノテーション・アノテーション型って何? *目次 [#wefd1cec] #contents *バージョン [#la7b3d60] -Javaでいうと7, 8の間はデカかったけど8, 11の差はそうでもない -Java strategyというのがあって、1 version / yearでリリースし、3年に一回安定版のJavaを作るみたいなポリシーがあるらしい。現在8, 11が安定サポート対象 -SPA (Single something somethin)というフロントエンドのReactに代表されるフレームワークがあって楽しい -SDKは下方互換性強い --変更があったとしても安定ソートになっていない仕様のソートで少し順序が違うとかそれくらい *ディレクトリ構造 [#z05ac660] -~/.m2のにインストールされたパッケージが格納されている。 --バージョン管理は複数のパッケージをインストールすることで解決、つまり他のプロジェクトから同じパッケージがアクセスされる。 *Map/Reduce [#t5983331] -map(T -> R) は、 T のデータ型を R のデータ型に1:1の変換です。 ・ flatMap(T -> Stream<R>) は、 T のデータ型から Stream<R> に1:Nの変換です。 *Javadoc [#f1cce302] 大変便利で、クラスの概要やメソッドの概要を記述しておくと、その情報からHTML形式のドキュメントファイルを生成してくれます。Java Platform SEのAPIリファレンスは実際に、この機能を使って生成しています。 *アノテーション [#jb7e3c9b] -自作する場合はjavaファイルを自分でかく必要がある。 -Javaではアノテーションを記述するためにはアノテーション型を使います。 --クラス --インターフェース --メソッド --メンバ変数 --メソッド引数 -例えば、Javaプログラムの単体テスト用ライブラリである「JUnit 4」では、テスト用プログラムにあるアノテーションが付いたメソッドをテスト用メソッドとして実行できます。 --Javaには標準アノテーション型として、java.langパッケージに「Override」「Deprecated」「SuppressWarnings」が定義されています。 *スレッドプール [#la73e576] -Java: スレッドプールというtask queueみたいなのを内側のスレッドで一つ一つ処理していくみたいな方法がある。https://qiita.com/KeithYokoma/items/4e6e9bd4e44aab63424d *Context [#jd65ac88] -The request.setAttribute() sets an attribute in the request scope and is thus only available within the same request/response cycle. The servletContext.setAttribute() --スコープとは、サーブレットやJSPを跨いでデータを共有したい場合に用いる保存領域のこと。 -https://qiita.com/shuyam/items/a9a1be62f52009748844 --共有範囲に応じて以下の3種類がある。 --リクエストスコープ ブラウザからのリクエスト毎に生成されるスコープのこと。次のリクエストが来た場合やブラウザを閉じたり、アプリケーション・サーバーが再起動した場合は原則保持されない。 --セッションスコープ ブラウザを閉じない、あるいはタイムアウトしない限り保持されるスコープ。 --アプリケーションスコープ アプリケーション・サーバーが終了しない限り保持されるスコープ。ブラウザを閉じても保持される。 --サーブレットのdoGetやdoPostメソッド内でスコープに保存し、フォワードメソッドで次に引き渡すと、これら全てのスコープのデータを保持した状態で次のサーブレットに渡せる --req.getsession().getservletcontext() and getservletcontext()はじつは同じもの https://stackoverflow.com/questions/12448826/difference-between-req-getsession-getservletcontext-and-getservletcontext -GAE Standardのセッション管理 --この実装では、App Engine のデータストアと memcache を使用してセッション データを保管する。 --で、どうやってsessionのattiributeを見るの??なくない?? -mvnのPはprofile。pomの中にprofiles/profile/idに指定するところを-Pで指定すると、そのプロファエイルの中に書いてあるdependencyなどが追加でインストールされるなど。複数のプロファイルを読み込むこともできる。 --Dはdefineで、system propertyのレベルなので結構広い範囲で有効。C++での-Dに近いものがあるのでわかりやすいね。 - -DをrequiredProperty()みたいな感じで取得する方法があるらしい。多分これはPOMのpropertiesにあるbigtable.versionみたいなやつを取得する関数で、POIMの設定として強制的に追加するための関数なんじゃないかなあと思っている -Celeniumの自動化をしても結局メンテナンスコストはかかる --画面テストのメンテは実はUnitTestよりコストがたかいので、メンテできないような亮のテストを作ってはならない。 --記録機能はそこまで重要ではなく、それなりのコストが必要になる -guavaというGoogleせいのライブラリがあって、これがC++のbits/std++.hみたいな感じでいろんなデータ構造とか簡単に値チェックするための関数を提供していてうれしいらしい。 *POM [#q24425ae] -依存管理 --Ant --gradle --Maven -MavenはProject Object Model(POM)によるプロジェクト管理ツール -https://kengotoda.gitbooks.io/what-is-maven/primer/build-lifecycle.html -Maven --Javaのビルドツール --Mavenは内部でAntを使用しており、Antで使用できる全ての組込ターゲットを直接使用できる ---Antではオレオレbuild.xmlを書かないといけなかったり、依存JARが多いと全部サイト巡ってダウンロードする必要があるみたいな悲しい感じだった。→プロジェクトのディレクトリ構造にルールを作った。→依存jarは自動ダウンロードするようにした。→また、ビルドも、コンパイルしてテストしてZIPで固めて…をするようにした。 --依存ライブラリ (jar) は自動ダウンロードされる。 --jarはローカルレポジトリと呼ばれるフォルダに保存される。settings.xmlの<localRepository>で設定することが出来る。 -プラグイン --ゴールとは、何らかの成果物。 --プラグインは、「複数のゴール」と「それらのゴールを達成するためのルール」が組み合わさったもの。フェーズとゴールの関係は 1 対多。 --maven [プラグイン]:[ゴール]で、あるプラグインのゴールを生成するプロセスが走る。 --プラグインが省略した場合は、javaプラグインがデフォルトで入る(java:packageとか) --自分でプラグインを作成するためのプロジェクトを作ることもできる -アーティファクト --アーティファクトは、プロジェクトの成果物 = jar -mvm [フェーズ名]とすることで以下ができる。 --clean (一時ファイルの削除) ---targetディレクトリを削除する。 --validate (プロジェクトの状態確認) --compile (プロジェクトのコンパイル) --test-compile (テストコードのコンパイル) --test (ユニットテストの実行) --package (アーティファクトの作成) ---通常targetディレクトリの中にアーティファクトが作成される。 ---例えば、mvm packageと打つと、それに必要なcompile, test-compile, testも走る。 --integration-test (インテグレーションテストの実行) --verify (アーティファクトの検証) --install (アーティファクトをローカルリポジトリに配置) --deploy (アーティファクトをリモートリポジトリに配置) -ビルド・ライフサイクル --「コンパイル→テスト→JAR作成」などのビルドにおける作業の順番を定義したもの --通常defaultライフサイクルというものが使われており、これは[[23個の直鎖状の依存関係>https://kengotoda.gitbooks.io/what-is-maven/primer/build-lifecycle.html]]からなる --cleanは、一時ファイルの再利用のためdefault life cycleには含まれておらず、cleanライフサイクルという別のものに入っている。 -Mavenレポジトリ --JARなどの成果物やJavadocをライブラリを整理してまとめておく場所のこと。他人と共有することもある(リモートレポジトリ)し、そうじゃない(ローカルレポジトリ)こともある。 --ローカルレポジトリ ---デフォルトでは~/.m2/repository ---リモートリポジトリにも公開されていないライブラリを使う場合には、まず mvn install でそのライブラリをプライベートリポジトリにインストールしてやると使えるようになる。 --他のリポジトリからダウンロードしたライブラリを保管したり、installゴールでJARをインストールしたりするために使う --リモートレポジトリ ---プライベートとパブリックがある ---パブリックは、セントラルレポジトリというもの http://search.maven.org/ 例としてこういうのがあるhttps://mvnrepository.com/artifact/com.google.guava/guava mvnrepositoryは便利 ---プライベートリポジトリは、自分でレポジトリを作って、会社内だけに公開とかが出来る。 -バージョン --バージョンにSNAPSHOT修飾子を含めることで、使い手とMavenに対して安定版ではないことを伝える --安定バージョンは数字とドットのみ --他にもga, alpha, betaなどの修飾子がある。 --スナップショットバージョンとリリースバージョンは、<distributionManagement>などを使って違うリモートレポジトリを設定することができる ([[参考>https://kengotoda.gitbooks.io/what-is-maven/deploy/specify-repository.html]]) --セントラルレポジトリには、誰でもライブラリを登録することが出来る http://samuraism.jp/diary/2012/05/03/1336047480000.html --WebDAVでアクセスするので、何らかのプラグインが必要 -デプロイは二つの方法がある --deployフェーズ: プライベートレポジトリに主にSNAPSHOTバージョンを公開 ---mvn deploy --maven-release-pluginプラグイン: 安定バージョンの公開に使う。 ---mvn release:prepare release:perform --権限がないと言われたら、~/.m2/settings.xmlにユーザ名とパスワードを入れないといけないというのがよくあるミス -javacって何 --jarは実はJava Archive、実際には単なるzipに変な情報を足したもの --JARファイルは.javaファイルではなく.classファイルを使用するので、javacコマンドでコンパイルする必要があります。 --jar cvf Test.jar test/で作れて、もうtarみたいなかんじ。 --実際問題jar tvf Test.jarとするとMETA-INFとかが入っているだけなので、実質zip -そもそもjavaって何 -SCM管理下って何 -JARの識別する仕組みとして、groupId, artifactId, versionを特定するようにした。 --ビルドの仕組みもガチガチに決まっている。Default -> Clean -> SIteで、それぞれには9, 3, 4個の手順がある。 --これをライフサイクルの各フェーズという。 --ゴールは、ビルドの個々のタスク、コンパイル、JAR作成、ファイルのコピーなどをする。 --ゴールは全てプラグインが提供する、ゴールは「プラグイン名:ゴール名」compiler:compileみたいな形をしている。 --要するにゴールは「コンパイルしろ」「テスト走らせろ」みたいな一つの行動に相当していて、これはプレでファインド。 -profileという機能があって、これを使うと本番・保守・開発でDBの接続設定を切り替えるとかできる --$M2_HOMEというところにMavenのInstall Directoryがある --.m2にダウンロードしたJARが格納 --java -cpはクラスパスを指定している --java -jar Test.jar Test.jarにメイン・マニフェスト属性がありませんと言われるが、これはmain関数がどのクラスのものなのかがわからないため。これの修正のためには、Main-Class: test.Testというマニフェストを追加すると良い。 --Javaの特徴は、JVM (Java virtual machine)というマシンの上で仮想化されているので、どんな環境でもJavaが動作する -VMが整然とシャットダウンされた場合には、JVMは登録されているシャットダウンフックを実行します。整然としたシャットダウンとは以下のものを指します。 --デーモンでないスレッドが全て終了した --System.exitが呼ばれた --ユーザ割り込みでの停止(Ctrl + C、SIGINT) -GroupId --他の全てのプロジェクトと区別するための名前です。 一般に使われるのは ドメイン名を逆にしたものです。 com.example など。 これをそのままパッケージ名のフォーマットに使うのが一般的です。 -ArtifactId --バージョンを除いた jar ファイルの名前です。 プロジェクト名といったほうがわかりやすいと思います。 たとえば project_a などにします。 -Version --Intellij IDEA だと、 デフォルトで 1.0-SNAPSHOT となっていたりしますが、 フォーマットは決まっていません。 1.0.0 のようにもできます。 --packageはソースファイル内のクラスが所属するパッケージ名を指定するのに用います。 これをソースコードに書くと、mavenでコンパイルしている場合はtargetディレクトリを勝手にほってくれるので便利という感じっぽ。定義上一つのソースに一つしか存在しない。package文を省略すると、クラスは名前無しのパッケージに所属することになる。 --import文はくrスのロードではなく、クラスライブラリ探索のための省略ができるよと言うだけらしい。フルパスで書けば動くは動く。その性質から、当然名前衝突する可能性もあるので、*でimportするのは控えるのが良い。 ---importはusing namespace.hoge;みたいな感じ。「インポート」は決してしていなくて、名前空間の省略に相当している https://style.potepan.com/articles/18139.html intelliJのdependencyでexternal libraryを指定するとは一体どういうこと?jarがあるけど、jarの中には何が入っていて何が出来るの? --しかし、Javaにはパッケージ名の衝突を防ぐ仕組みはなく、インターネットドメイン名(DNSドメイン名)をパッケージ名として利用することを推奨している。 -JavaのdependencyがLogging version 2とLogging version 3のように衝突する場合は、エラーメッセージがちゃんと出るのでどちらかをexcludeで消さないといけない。 -「compile」フェイズでは、maven-compiler-plugin の compile というゴールが実行されます。 --プラグイン:ゴール -intelliJのビルドは、pomがあるところで実行しているっぽい。 -pomのreimportをした --IntelliJでpomを変えたときには、reimportをしないとdependencyなどが反映されないっぽい。。。 -Javaのstatic --static メソッドは、そのものがクラスのインスタンスではなく、クラスに属します。それ以上でもそれ以下でもない Javaのfinal final変数はconstみたいなもの。ぶんかとして 普通の変数と区別するために大文字にすることが多い。 final classは継承付加を表す関数。 ServeletのdoGetとかdoPostとかは当然HTTPリクエストに対応している *デザインパターン [#p3234edb] **Builderパターン [#p03fac5b] Pythonとかだと引数の名前にたいしてf(name="hoge")とかできるけど、Javaではできない。これを解決したいね、というやつ。 基本的には、インスタンスを直接作るのではなく、作ってくれる大工インスタンスを作る時点でビルダーパターンと言える。 Builderを使いたくなる理由 引数が多くなると、順番を正確に覚えておくのが難しくなる。 つまり引数の渡し間違いが発生しやすくなる 任意の値があると、適当な値をわざわざ渡す記述を書く必要がある。 つまり記述量が無駄に多くなる ↑の例でいうと、 ageは任意の値です。任意だけど、コンストラクタに引数として与えなければならない以上記述はしないといけないですね。無駄なことです。 **DAO [#ydfe9698] In computer software, a data access object (DAO) is an object that provides an abstract interface to some type of database or other persistence mechanism. *List [#we4af2e8] -List は ArrayList の上位クラス(List の下位には例として LinkedList などがある) --「これは List インターフェースにある機能だけで充分で、ArrayList 等の独自の機能は必要としていない」ということを明示できる --後で型が変わる場合に変更範囲がより少なくなる --List 型で宣言しておけば、後で必要になった時に ArrayList 以外の型も入れられる --後で機能拡張を行う可能性がある場合、出来るだけ拡張性を高めておくことがより好ましい場合があります。 --List 型で宣言された変数には、必要であれば、ArrayList だけでなく、LinkedList といった他の List インターフェースを継承したオブジェクトを代入出来るようになるため拡張性が広がります。 *サーブレット [#s6ae6a8e] というかJSPでいじる変数ってsessionに書き込まれたAttributeから得る感じなのか…なるほど Datastoreのkindには_ah_SESSIONというのがあって、javaのセッション管理は自動的にここのkindが使われる Javaのdo filterを考えるときには、二つのフィルタがあってそのあいだの順序はweb.xmlで決める(めんどいし順序に依存しないようにfilterを設計するのが大事) chain.doFilteより上が前処理、下が後処理 フィルタ リクエスト・リスポンスの整形をすることができる。生のリクエストは結構汚いので、サーブレットが処理する前後でいろんなデータ正しい状態にするための機能 FilterChainのdoFilterメソッドによって一連の処理が実行されるので、これより前で処理を行うか後ろで処理を行うかで、クライアントからの要求と応答のどちら側でフィルタリングを行うか決定する事ができます。 JSP Standard Tag Library (JSTL) Tutorial - 手順としては、 - pom.xml のproject/properties/bookshelf.storageTypeとかにstringを格納する - this.getServletContext().getInitParameter("bookshelf.storageType");とかで何のデータベースを利用しようとしているのかを確認する - サーブレットのinitでthis.getServletContext().setAttribute("dao", dao);をして初期化 - リクエストが来ると、doGetにプログラムポインタがくる。 - doGetの中で、this.getServletContext().getAttribute("dao");をしてDAOを取得 - ?cursor=%sみたいなやつを、req.getParameter("cursor")で取得する(getAttributeとかはまじで型を限定しないような形になっているっぽい、具体的にはObject型) - サーブレットでreq.setAttribute("var", arr)を何回もして配列や変数を登録。配列はList<T>を突っ込む。 - サーブレットでreq.getRequestDispatcher(jsp).forward(req, resp)をする - jspで${var}が使えるようになっているのでフロントのテンプレートを頑張る。クラスの場合、クラスのメンバ変数には、var.imageURLみたいな感じで親子的にアクセスできる。 JSPファイル Webサーバ上で動くプログラム Javaの中でもウェブサーバでレスポンシブに動くプログラムをサーブレットと言うらしい。 JSPがpythonでやっていたプログラマブルなHTMLに相当している JSPはServlet containerがJavaServletに変換して、その役割で働く Servlet ContainerはServletをspin upしたあと、すぐに落とさない(CGIは寝る)。マシン単体でのスケールアップについて責任を追っているので、マルチスレッド対応している。 サーブレットコンテナとして一番有名なのは「Apache Tomcat」 JavaServer Pages が使われています。これは Java テンプレート エンジンの一種ですが、サーブレットとして実行されます。 getSessionという概念がある。これを使って以下のようにすると、reqにもsessionにもかきこまれるようになるみたい。 req.getSession().setAttribute("cursor", endCursor); req.getSession().setAttribute("page", "list"); *Spring [#vf06e4da] JPAは「Java Persistence (JSR 338)」の略称であり、Java EE標準のO/R MappingおよびDAOの技術仕様です(元々の名称は「Java Persistence API」であり、その略称「JPA」が現在でも一般的に使用されているため、このドキュメントでも「JPA」という名称を使用します)。 ● Entity: 「永続化オブジェクト」を表します。具体的にはデータベースのテーブルと1対1で対応する「Javaのクラス(Entity Class)」およびその「インスタンス(Entity Object)」です。 ちなみに、Java対応統合開発環境の「NetBeans」を使うと、setter/getterメソッドのコードが自動的に生成されるので便利です。 https://builder.japan.zdnet.com/sp_oracle/35067018/ @Entity public class Employee implements Serializable { Serializableはインスタンスをバイト列に変換できますよ、という明示 EntityManagerは実際のEntityの挿入とか削除とか。「persist(新規登録)」、「merge(更新)」、「remove(削除)」、「find(検索)」という4つのメソッドを覚えておけばよい。create, read, update, and delete (CRUD) 「永続性コンテキスト」はエンティティマネージャ内部のエンティティのキャッシュ。 Repositoryはentidy managerと似たもので、CRUDにするためのメソッドを利用できるようになっている。JpaRepositoryを継承しているのと、第一引数にEntityクラス、第二引数にプライマリーキーの型を記述していることがポイントとなります。 Serviceでは、上記のRepositoryを使い、EntityのCRUDを行うメソッドを用意します。今回のような単純なデータ操作なら、パッケージ名をDaoとしてもいいかもしれません。CRUDではなく、もう少し抽象度が高いレベルで行いたい操作をここにかく。そうすることで、Repositoryを使わない実装や抽象化に切り替えることが出来る。 @Service (spring @Transactional (spring) @Autowired 「newしてくれる。@Autowired private MessageRepository repository;」は「private MessageRepository=new MesaageRepository;」と同じ。@Autowiredで、上で作成したRepositoryをインジェクションします。 インジェクションってなに? AOP 何かRESTcontrollerにすると、List型をそのまま返してもいい感じにJSONにしてくれるっぽい。@PathVariable("id") Long id, @Validated @RequestBody Whisky whiskyのようにすると、URLの値がPathVariableとして取得でき、RequestBodyがJSONとEntityから自動的に判定されて入力されるらしい。すごい。 https://dev.classmethod.jp/articles/spring-boot_crud-api/ DI 依存性の注入。Springの中心らしいので勉強。 https://www.shookuro.com/entry/2016/08/09/175801 SpringMVCとBootでは@Component の変わりに @Controller、@Service、@Repository を使用するが、これらは実質的に同じ。 @ComponentでSpringコンテナに管理させるクラスとして宣言している。@Autowired を使用してクラスBのインスタンスを Springで自動的にセットしてもらう。 pringのDIコンテナの利点は大きく2つあります。それは、 https://qiita.com/shuntaro_tamura/items/ba5a2e9b3ba305285edd クラスからnew演算子を消せる インスタンス化を1回で済ませられる(Singleton) です。 〜実装〜 実現する方法は2通りあります。 アノテーションを使う Bean定義ファイルを使う です。 アノテーションベースの方のみ説明書きます。 インスタンス変数(注入先の変数)の前に@Autowiredをつけると、@Componentアノテーションのついたクラスの中から該当するものを探し、newしてインスタンスを突っ込んでくれます! これ、結局JavaのクラスはC++とは違って実体ではなく参照に近いので、毎回毎回クラスを書くたびにnewして辛いので、取り決めがあるものについては自動でnewして入れてくれ〜という気持ちっぽい?Componentアノテによって登録し、Autowiredで呼び出す。 AOPはまだ重要じゃなさそうだしいっか。典型的な処理を特定の条件(呼び出し前とか)に呼び出せるようにするための仕組みっぽい。Pointcut(条件)を満たすメソッドに対し、Advice(共通処理)を走らせることで、各クラスには本質的な処理だけを記述することが可能となるわけです。https://qiita.com/shuntaro_tamura/items/ba5a2e9b3ba305285edd @Beanと書いたメソッドでインスタンス化されたクラスがシングルトンクラスとしてDIコンテナに登録される。任意のクラスで@Autowiredで注入してアクセスできる。 BeanとComponentの差は? Bean=インスタンス化して使用するクラスです。 Spring FrameworkがXML地獄で面倒だが、Bootではアノテーション方式でBeanが設定できるので楽 制御の反転、という用語があるが、これはDIと同義。DIは結局、依存関係が合った時にそれを自動的に解決してインスタンスを作成してくれるもの。DIコンテナ=IoCコンテナ https://ja.wikipedia.org/wiki/%E5%88%B6%E5%BE%A1%E3%81%AE%E5%8F%8D%E8%BB%A2 JavaBeansとSpringのBeanは違う!!! Spring の IoC コンテナによって管理されるオブジェクトを Bean と呼ぶ。JavaBeans とは違う。 Spring の設定とは、すなわち Bean の設定のことを指す。 どのような Bean を定義するか Bean にどのようなプロパティを与えるか Bean をどのように初期化するか Bean をどのように破棄するか どの Bean と Bean をつなげるか といった設定を IoC コンテナに食わせると、IoC コンテナは Bean のオブジェクトツリーを構築し、適切に生成/破棄を行う。(https://software.fujitsu.com/jp/manual/manualfiles/M050000/J2X11190/01/guide05/guide054.html オブジェクトツリーはxmlを見るとよりわかりやすい。@Beanは動的生成にすぎないっぽい。どうやらシングルトンを前計算で木構造状に作り、@Autowiredでは前計算したオブジェクトの参照をメンバ変数に貼り付けているようなイメージ?) Bean のライフサイクルは IoC コンテナによって管理される。デフォルトでは、コンテナの起動時にインスタンス化され、シングルトンとして扱われる。すなわちひとつのオブジェクトが全ての場所で共有される。そしてコンテナの終了とともに、インスタンスも破棄される。 デフォルトで用意されているスコープは以下の通り: singleton シングルトン。デフォルト prototype ApplicationContext.getBean するたびに new する。 Beanによって木構造を作っているらしい。なるほど。 @Component はクラスにつけるアノテーションである。このアノテーションをつけたクラスが、IoC コンテナの管理対象であることを知らせるためのマーカーである。@Component がついたクラスは @Bean による Bean 定義を書かずとも、IoC コンテナの管理対象になる。同じような役割の Bean が大量にある場合には、いちいち @Configuration + @Bean で Bean を定義していくよりも手軽で使いでがある。 Beanはクラスである、と書かれていたのに突然Beanをメソッドにつけるとか言われて混乱している 典型的なコンポーネントとして、3 つのステレオタイプが用意されている: @Controller Web アプリケーションのコントローラクラスであることを表す @Service サービス層のクラスであることを表す(サービス層って何???) @Repository ある DB に、DB 特有・に依存したアクセス方法 (SQL クエリとか) を知らなくともCRUDを行えるようにするためのもの https://terasolunaorg.github.io/guideline/5.0.1.RELEASE/ja/ImplementationAtEachLayer/DomainLayer.html#repository Entity-Service-Repositoryが永続化系のセット。EntiryはDBに書かれるべきデータと等価なもの。Serviceはどういう風にEntityを永続化するかを決める。そのためにServiceはDBごとに定義されたRepositoryを介して、Entityをインフラストラクチャレイヤに送る。インフラストラクチャは、Entityとそれに対して行いたい根源的な操作を実装していて、これはJavaのクラスであるEntityをSQL文に変換して実際にDBにAPIコールすることによって実装する。SQLの場合、エンティティのクラスごとにRepositoryを作らないといけない。でもエンティティのクラスが増えても、サービスは1個だけとかでも全然良い。 Persistence layer : 実際のRDBMS Infrastracture layer : クラス定義と SQL のテーブル定義の差を吸収するためのレイヤ。これを吸収するのはRepositoryImplと呼ばれるもの。 Domain layer = クラスへの代入とオブジェクトの「永続化して!」くらいの雑な指示で DB に書き込めるくらいの抽象度があるレイヤ。Infrastructure layer のおかげでこんなマジカルなことが出来る。 Repositoryを設ける最も重要な目的は、永続先に依存するロジックを、業務ロジックから排除することではないという点である。 最も重要な目的は、業務データへアクセスするための操作をRepositoryへ分離することで、業務ロジック(Service)の実装範囲をビジネスルールに関する実装に専念させるという点である。 結果として、永続先に依存するロジックは業務ロジック(Service)ではなく、Repository側に実装される事になる。 Spring でのデータベース抽象化の勉強をしていたらこんな時間になってしまった… とりあえず Bean がシングルトンを前処理で全部作って参照の木構造を構築することで O(1) でインスタンスにアクセスできてるっぽい?ことと、DB 特有のクエリなどを Infrastructure Layer で吸収して、吸収後の操作はJava のインスタンスをいつでも使えるようにして!くらいの雑な CRUD 操作だけにした状態で Repository としてサービスが使えるようにしとく、みたいなイメージ POJO(Plain Old Java Object)は要するにnewで実体化される普通のオブジェクトのこと printf とテキストデータを送るための配線がないから全部自前で作らないと!みたいな自前世界から来た自作星人なので、ちゃんと諸々が整っているのにびっくりしてしまいます。 概念としては HAL みたいですねという感じで自然だけど、僕の今までの認識ではこういう Repository に相当するものは自前で実装しなければいけないと勘違いしていたので、この辺の労力を全部フレームワークが吸収してくれているというのは非常に助かる of 助かるですね。 DB 特有のクエリなどを Infrastructure Layer で吸収して、吸収後の操作はJava のインスタンスをいつでも使えるようにして!くらいの雑な CRUD 操作だけにした状態で Repository としてサービスが使えるようにしとく、みたいなイメージ Spring でのデータベース抽象化の勉強をしていたらこんな時間になってしまった… とりあえず Bean がシングルトンを前処理で全部作って参照の木構造を構築することで O(1) でインスタンスにアクセスできてるっぽい? https://terasolunaorg.github.io/guideline/5.0.1.RELEASE/ja/ImplementationAtEachLayer/DomainLayer.html#repository このサイトがめちゃくちゃ詳しくSpringについて書いてあってこれを読むだけで強く慣れそう。本革なくとも spring bootは、なぜかmainが何回も呼ばれる。これは期待された動作らしい…きも https://qiita.com/takkii1010/items/0ce1c834d3a73496ccef JSON pathという表記があって、これによってJSONのデータを指定できる。$がroot, ドットがネストのひとつ下に行くこと。 HTTP requests are handled by a controller CommandLineRunnerは、mainとは別に一回呼び出される public CommandLineRunner commandLineRunner(ApplicationContext ctx) { } model.addAttribute("name", name); The value of the name parameter is added to a Model object, ultimately making it accessible to the view template. Spring Boot Devtools To speed up this refresh cycle, Spring Boot offers with a handy module known as spring-boot-devtools. *intelliJ [#pc52e9f9] メソッドのコードや定義の確認のためにはC-bで行ける(Alt-Leftかも) intellliJで、文字列リテラルにs: とかo:とかついているのは、呼び出し元の型がstringかObjectかという違いによるもの というか関数の中の変数としてthisを渡していたりするときも、それがどの方7日がわからなくならないようにbuilder:とかがついている -ショートカット --C-N Navigate class search --CS-Nでnavigate file --C-SpaceでCode completion --A-F7でFind Usage --C-Qでドキュメントを読む --C-Bで宣言を見る --C+F12で現在編集中のファイルへ --S+F6 全変数rename -pom.xmlを変更した場合は、右クリックしてmaven->Reimportをやらないといけない *Jetty [#ydcb2142] -100%Javaで開発されたJava Servletコンテナ/Webサーバである。WebSocketなどのプロトコルもサポートする。Jetty はオープンソース (Apache 2.0 License) でリリースされている。JBoss、Apache Geronimoといった他のプロジェクトでも利用されている。 -単純で効率的な組み込みやすいWebサーバとなるよう意図して開発されている。 -サイズが小さいので、組み込み型 Java アプリケーションにWebサービスを提供するのに適している。 -その一方で、Apache HadoopやGoogle App Engineといった大規模でスケーラビリティが重視されるサービスにおいても採用されている[2]。 --2009年1月、WebtideはJettyのコアコンポーネントをcodehausからEclipse Foundationに移管することを発表した。 --サーブレットの一種でTomcatと双璧をなしているらしい。GAEで採用されているのはびっくりした。 --Tomcatに比べると軽量で、Apache+Tomcatではオーバースペックになっている可能性。TomcatのHTTPサーバ機能は開発者向けで本番環境向けではないが、JettyはHTTPSがついているのでApacheがいらない。あと起動が早い。 -Maven Surefire プラグインはユニットテストの実行のためのもの。JUnitと何が違うの? --JaCoCoはコードカバレッジを測るもの。 *未整理 [#gf6e1d52] -intelliJでJDKを帰るにはProject Structureとかいうのを使えば良い -JavaのMakefileみたいなもの --Mavel, gradle -mavelはlifecycleというものがあるclean, site, deployがデフォルトで、siteはドキュメントを作るためのコマンド。 --その他にもvalidate, comile, test, package, verify, installなどいろいろなコマンドがあって、これらの動きを制御するための情報がpom.xmlに書いてある。 -IDEは適切に選ぶ。 --node.jsとかはIntelliJ Ultimateを使ったり、JavascriptはVSCodeを使うのが良い。 -pom.xmlのbuild as maven projectを押した --あとSDKはデフォルトで走らなかったからreadlink -f $(which java)をしてGoogleのJDKを使った -javaのデフォルトのJDKを調べる方法 --readlink -f $(which java) -caretはキーボードカーソルのこと? -gradle --maven-pom --.m2 -コマンドを走らせるときはものすごく気をつける!!! --そもそもいい加減に走らせない。何をやろうとして走らせているのかを把握して作業する。 -mavenはjavaのビルドツール --javaのPOMとは?pom.xmlというファイルによってビルドできる --A Project Object Model or POM is the fundamental unit of work in Maven. *パッケージ [#m0d8fcd1] **Jsoup [#pd7ca616] -これjsoupのtableの取得方法で面白い --https://qiita.com/suisen/items/a856c06accdab922153c -selectは、対象のタグの範囲全てを「選択」し、その中に入っているElementを全て選択する。Elementは階層的でないタグの最小単位みたいなイメージ? -pを選択したら、inner selectだとhogeから、outer selectならpから選択される <p> hoge <a href="xxx">fuga</a> </p> 深いところにあるタグはこんな感じでスペース区切りで指定する。 これはCSSセレクタと呼ばれていて、class, idなどが予約語となっていて、CSSのスタイルをどこに反映させるかを表現するための表記 https://www.asobou.co.jp/blog/web/css-selectors Elements elm = doc.select("tbody tr"); **Thymeleaf [#yc1caf58] Thymeleaf [[このQiita>https://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html]]が異常に詳しい 要するにビューテンプレートエンジン、Spring Bootでの仕様が推奨。純粋なHTMLとしてテンプレートが記述できてえらい modelにはattributeをセットできる セットしたattibuteをthymeは th:text="${message}"のようにして取得できる。 sliceできる(全ての要素を単一の行として取得)$.arrayObject[0:] 掘れる $.address.streetAddress.street map<string, T> はこんな感じで掘れる $.['firstName'] [[attributeとしてクラスインスタンスを突っ込める>https://qiita.com/opengl-8080/items/eb3bf3b5301bae398cc2#%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E5%8F%82%E7%85%A7]]のはかなり衝撃的…これはすごい。djangoとかってこれできた記憶ない(やったことがないだけの可能性が高い) Viewの中で条件分岐とかforもできる(当たり前)。配列、List, Mapの全部がfor eachできる。つまり、Iterableならなんでも出来る。 また、フラグメントといって、テンプレートのimportもできる。色んな所で使いまわせるね。 Spring Boot のデフォルト設定だと、クラスパス以下の /resources/templates/【Controller の戻り値】.html でテンプレートファイルが探索されるらしいが、探索されない…ファイル名との対応が戻り値でサれているのはおもしろい。上の実装の場合は src/main/resources/templates/hello.html がテンプレートファイルとして利用されることになる→なぜかテンプレートを使ってくれない -> Thymeleafの設定を直接いじったほうが良さそう https://stackoverflow.com/questions/29479403/spring-boot-thymeleaf-load-html-file-from-classpath application.propertiesってなに???src/main/resources/application.propertiesになんか設定が出来るらしい。だれが提供しているどんな設定??? thymeleaf not find template...... https://www.google.com/search?sxsrf=ALeKk01nnQitlgYGwsIS1AeS73HOA4JwiA%3A1589218924922&ei=bI65Xo7uN_OSr7wPoeKh8Ao&q=thymeleaf+not+find+template&oq=thymeleaf+not+find+template&gs_lcp=CgZwc3ktYWIQAzIGCAAQFhAeMgYIABAWEB4yBggAEBYQHjoECAAQRzoECCMQJzoCCAA6BQgAEMsBUKy3AVjF0QFgztIBaAFwAXgAgAGuAYgBoBGSAQQ4LjEymAEAoAEBqgEHZ3dzLXdpeg&sclient=psy-ab&ved=0ahUKEwiO1PXrrazpAhVzyYsBHSFxCK4Q4dUDCAw&uact=5 classpath って何・・・ プロパティ設定方法がいっぱいあるよという話 http://blog.tagbangers.co.jp/2019/07/12/how-spring-deals-with-properties **selenium [#j1342b2d] https://qiita.com/VA_nakatsu/items/0095755dc48ad7e86e2f https://www.selenium.dev/documentation/en/webdriver/browser_manipulation/ これがかなりいい感じ。 Window, Tabは区別せず、WindowHandlerで一意に定める。 linkをクリックして新しいtabを開くみたいな操作は全部future的なので、いちいち新しいウィンドウサイズが2になるのをまったり、コンテンツが全部ロードされるのを待ったりする必要がある。 Elementというのはタグみたいなもの。findElementsはヒットしたもの全部返す。findElementは.get(0)に相当する。 driver.findElement(By.className("btn_next")).click(); // driver.findElements(By.className("btn_next")).get(0).click(); と同じ List<WebElement> elements = driver.findElements(By.className("mv-tile")); https://www.octoparse.jp/tutorial/xpath/ XPathとは? Octoparseでの作用は? driver.findElement(By.xpath("//input[@title='お名前']")).sendKeys("てすと 一郎"); driver.findElement(By.xpath("//input[contains(@title,'タイトルの一部')]")).sendKeys("本文入力"); sendKeysはキーボード入力を送るという意味 ラジオボタンとかもclickで入力することが出来る。 imgをクリックすることも出来る https://qiita.com/VA_nakatsu/items/0095755dc48ad7e86e2f#7-%E3%82%BF%E3%82%B0%E3%81%A7%E6%A4%9C%E7%B4%A2 |