<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3030476649588243638</id><updated>2026-08-09T01:08:26.289-07:00</updated><category term="java"/><category term="java script"/><category term="javaserver faces"/><category term="spring  framework"/><category term="jquery"/><category term="oracle sql"/><category term="android"/><category term="ubuntu server"/><category term="JPA(Java Persistence API)"/><category term="css"/><category term="primefaces"/><category term="linux command"/><category term="other"/><category term="algorithm"/><category term="windows command"/><category term="less"/><category term="linux"/><category term="json"/><category term="windows"/><category term="html"/><category term="maven"/><category term="oracle"/><category term="solidworks"/><category term="c/c++"/><category term="glassfish server"/><category term="it security"/><category term="jasper report"/><category term="jsp(JavaServer Pages)"/><category term="scanning"/><category term="javascript"/><category term="mysql"/><category term="php"/><category term="backtrack"/><category term="database"/><category term="elastic search"/><category term="git"/><category term="oauth"/><category term="spring mvc"/><category term="assembly"/><category term="blogger"/><category term="google map api"/><category term="orientDB"/><category term="spoofing"/><category term="AI(Artificial Intelligence)"/><category term="angularjs"/><category term="development"/><category term="google chrome"/><category term="hadoop"/><category term="interface"/><category term="mongodb"/><category term="network"/><category term="nodejs"/><category term="phishing"/><category term="requirejs"/><category term="solve problem"/><category term="unit test"/><category term="vmware"/><category term="weather api"/><category term="windows registry"/><title type='text'>nascent</title><subtitle type='html'>เรียนรู้สู่การเป็นผู้สร้าง software</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>444</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-2009853845795431045</id><published>2019-07-30T20:15:00.000-07:00</published><updated>2019-07-30T20:17:16.114-07:00</updated><title type='text'>ตัวอย่างการเขียน Java Spring-boot Reactive (WebFlux) </title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0QKfGvzCQX45LhAwATA8QJPexcQgCG05T_dwt7wnGQolHhvC60LZsG8JJGPG9PJeBObRMuP_NH4wRl_RVXHThx0uUXfeNGcUIwQLoGW6iEvnZzqVB4WEa1gjJ5ShN0R-F8qHI9C-LfJnE/s1600/reactive_spring.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;198&quot; data-original-width=&quot;648&quot; height=&quot;193&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0QKfGvzCQX45LhAwATA8QJPexcQgCG05T_dwt7wnGQolHhvC60LZsG8JJGPG9PJeBObRMuP_NH4wRl_RVXHThx0uUXfeNGcUIwQLoGW6iEvnZzqVB4WEa1gjJ5ShN0R-F8qHI9C-LfJnE/s640/reactive_spring.png&quot; style=&quot;border: none;&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
ผมได้ทำตัวอย่างการเขียน Java Spring-boot WebFlux ซึ่งเป็นการเขียน Spring-boot แบบ Non-Blocking I/O หรือ Asynchronous หากใครสนใจสามารถเข้าไปศึกษาได้ที่&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #24292e; font-family: , &amp;quot;blinkmacsystemfont&amp;quot; , &amp;quot;segoe ui&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif , &amp;quot;apple color emoji&amp;quot; , &amp;quot;segoe ui emoji&amp;quot; , &amp;quot;segoe ui symbol&amp;quot;; font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;a href=&quot;https://github.com/jittagornp/spring-boot-webflux-example&quot;&gt;https://github.com/jittagornp/spring-boot-webflux-example&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #24292e; font-family: , &amp;quot;blinkmacsystemfont&amp;quot; , &amp;quot;segoe ui&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif , &amp;quot;apple color emoji&amp;quot; , &amp;quot;segoe ui emoji&amp;quot; , &amp;quot;segoe ui symbol&amp;quot;; font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/2009853845795431045/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2019/07/java-spring-boot-reactive-webflux.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/2009853845795431045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/2009853845795431045'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2019/07/java-spring-boot-reactive-webflux.html' title='ตัวอย่างการเขียน Java Spring-boot Reactive (WebFlux) '/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0QKfGvzCQX45LhAwATA8QJPexcQgCG05T_dwt7wnGQolHhvC60LZsG8JJGPG9PJeBObRMuP_NH4wRl_RVXHThx0uUXfeNGcUIwQLoGW6iEvnZzqVB4WEa1gjJ5ShN0R-F8qHI9C-LfJnE/s72-c/reactive_spring.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-1832593753696123363</id><published>2019-06-12T19:58:00.001-07:00</published><updated>2020-01-20T17:53:55.957-08:00</updated><title type='text'>ถึงคนอ่าน Blog และผู้ติดตามทุกคนน่ะครับ</title><content type='html'>&lt;div&gt;
&lt;div&gt;
Blog นี้ผมไม่ได้เขียนมาซักระยะนึงแล้ว&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
จริง ๆ ต้องเรียกว่านานมาก ๆ เลยแหล่ะ (เกือบ 4 ปีได้ ฮ่าๆๆๆ)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
ตอนนี้ผมย้ายไปเขียนบน platform อื่น ๆ&lt;/div&gt;
&lt;div&gt;
หลัง ๆ มาก็มี เขียนบ้าง ไม่ได้เขียนบ้าง&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
เพราะมีหน้าที่รับผิดชอบที่เยอะขึ้น เลยไม่ค่อยได้มีเวลาเขียน Blog ครับ&lt;/div&gt;
&lt;div&gt;
บวกกับตอนนี้มีความสนใจ เรื่องใดเรื่องนึงเป็นพิเศษ เลยไม่ได้มีเวลามาทำตรงนี้&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
ถ้าผู้อ่าน เพื่อน ๆ พี่ ๆ น้อง ๆ คนไหนยังอยากติดตามอยู่ สามารถติดตามได้ตาม link นี้ครับ&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;Jittagornp.me&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;https://www.jittagornp.me/&quot;&gt;https://www.jittagornp.me/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
ขอบคุณครับ&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/1832593753696123363/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2019/06/blog.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/1832593753696123363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/1832593753696123363'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2019/06/blog.html' title='ถึงคนอ่าน Blog และผู้ติดตามทุกคนน่ะครับ'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-6569197068514763430</id><published>2015-05-25T02:17:00.002-07:00</published><updated>2015-05-25T02:35:51.651-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>maven ทำ jar file ให้ double click run program ได้ : java</title><content type='html'>ในที่นี้ผมจะยกตัวอย่างด้วย Netbeans IDE น่ะครับ&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
1. สร้าง maven project เป็น Java Application&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3qrcBRAeIRDp6LWemf1Lz9__cDHIIMmR2ojG94k-TFRz9Zrhq7JHuqQg8j3zba3ZwnLbKmXM77649h3dqFallWwM47bAY8zJzdgcjlY-I77hUp09N9b-lwF2Rgkjp-y4dzZRsqxIYuct8/s1600/5-25-2015+3-56-29+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;350&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3qrcBRAeIRDp6LWemf1Lz9__cDHIIMmR2ojG94k-TFRz9Zrhq7JHuqQg8j3zba3ZwnLbKmXM77649h3dqFallWwM47bAY8zJzdgcjlY-I77hUp09N9b-lwF2Rgkjp-y4dzZRsqxIYuct8/s640/5-25-2015+3-56-29+PM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;Maven --&amp;gt; Java Application&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnX6yMV6H6gE7Q4-t3PZUJ24_7SXwAr6UXklw03S5rvPkURB5iVRNRVVNl94rr7kHUYGVjesVrLO3hMwngKWISQGLR32-vX0SL_gBpVY3az5_Tz1U2mioEZY6wN29chLhylKgp_MOVO9FO/s1600/5-25-2015+3-57-27+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;536&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnX6yMV6H6gE7Q4-t3PZUJ24_7SXwAr6UXklw03S5rvPkURB5iVRNRVVNl94rr7kHUYGVjesVrLO3hMwngKWISQGLR32-vX0SL_gBpVY3az5_Tz1U2mioEZY6wN29chLhylKgp_MOVO9FO/s640/5-25-2015+3-57-27+PM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
ตั้งชื่อ project กำหนด location, GroupId, Version และ Package&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAkquUXF-ELWt1jh9RuYmtJKqnTX3Izv8q_uEigiGdHyGpI2uZHII9zGz_p8tLb6vSgI2un_nWpURws298Q8IsP4Z0PZnwPPQcAMqBfim2WTj25LKtJtLjtTPuMb_iF2kKN6YA1BLenYux/s1600/5-25-2015+3-58-40+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;536&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAkquUXF-ELWt1jh9RuYmtJKqnTX3Izv8q_uEigiGdHyGpI2uZHII9zGz_p8tLb6vSgI2un_nWpURws298Q8IsP4Z0PZnwPPQcAMqBfim2WTj25LKtJtLjtTPuMb_iF2kKN6YA1BLenYux/s640/5-25-2015+3-58-40+PM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
2. สร้าง main class ที่จะ run program&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaE3QUv_TpH1tBhtTTWzR7f0bvsrqUziriJSjo_cldajPEDhVeZ6Fur114zfH1UP2LxYxejs1SDrlm7ga1tB_ZmlK0qNo682izAYl2ENCJbMv1C7gp14lGSkYk-q_VebLv3uUa0P5EoRQZ/s1600/5-25-2015+3-59-12+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;528&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaE3QUv_TpH1tBhtTTWzR7f0bvsrqUziriJSjo_cldajPEDhVeZ6Fur114zfH1UP2LxYxejs1SDrlm7ga1tB_ZmlK0qNo682izAYl2ENCJbMv1C7gp14lGSkYk-q_VebLv3uUa0P5EoRQZ/s640/5-25-2015+3-59-12+PM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8cLpmtjznUcI1wq3ewCguNdcrPrYZPKAYMoUXdxZsFieTogQv4Phl6DySuZmof2u-5UIWQK0hT4VejG62IzzgYFO8aAcESF-QjW5LvGrJGE_RPwGu0mAcxUfOZ6OYhQrM0eHawuCADj8A/s1600/5-25-2015+3-59-49+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;452&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8cLpmtjznUcI1wq3ewCguNdcrPrYZPKAYMoUXdxZsFieTogQv4Phl6DySuZmof2u-5UIWQK0hT4VejG62IzzgYFO8aAcESF-QjW5LvGrJGE_RPwGu0mAcxUfOZ6OYhQrM0eHawuCADj8A/s640/5-25-2015+3-59-49+PM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
เขียน code &amp;nbsp;ในที่นี้ให้ show message dialog ง่ายๆ ที่มีคำว่า Hello World!&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih81MLE8VRjJDDoE7806eHIrIX4DORulWePbbGIAQEkVIaASGoNuX0NHB3Z3PjQQBqH9szh9a6zbqpW7TzFD4Km-SAqtzEvADGJ1CNU3ac0kW63B4-JgbzlJvoDn3kyOd3D8yNhCXqhG9Q/s1600/5-25-2015+4-04-30+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;368&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih81MLE8VRjJDDoE7806eHIrIX4DORulWePbbGIAQEkVIaASGoNuX0NHB3Z3PjQQBqH9szh9a6zbqpW7TzFD4Km-SAqtzEvADGJ1CNU3ac0kW63B4-JgbzlJvoDn3kyOd3D8yNhCXqhG9Q/s640/5-25-2015+4-04-30+PM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
3. config pom.xml โดยการเพิ่ม &amp;nbsp;plugins สำหรับ pack jar file ลงไป&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGSlHMmZ50djB4f-x3J29hqzDHFqSblhd23Bu0PzLSDlwMC3jB4xQTd0N7JnrJwW-nt5HVkLQtmhn35WM72mLYvUxGI2hsX8C8WTMZLYHyGoBvgHRsDO7NAIBK5_9y9JSK_l9hDgC64WFC/s1600/5-25-2015+4-04-54+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGSlHMmZ50djB4f-x3J29hqzDHFqSblhd23Bu0PzLSDlwMC3jB4xQTd0N7JnrJwW-nt5HVkLQtmhn35WM72mLYvUxGI2hsX8C8WTMZLYHyGoBvgHRsDO7NAIBK5_9y9JSK_l9hDgC64WFC/s640/5-25-2015+4-04-54+PM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;u&gt;&lt;span style=&quot;color: red;&quot;&gt;***** อย่าลืมกำหนด main class ด้วย (สังเกตบรรทัดที่ 29 ในรูป)&lt;/span&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjq1LLMIEzaundBKX3yQ9SB75nOx5GHkVGMKAKsSFZ6v2nOaQ8ugsZ-K-CV-qgb4vG7zm1-H2F-Ms_nUovua9bv67YOEGX4S0PeoYdGxYj9KVf9cKPRg6MUgsvAhDGGqXZOwYAje8xeh7H/s1600/5-25-2015+4-05-55+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;428&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjq1LLMIEzaundBKX3yQ9SB75nOx5GHkVGMKAKsSFZ6v2nOaQ8ugsZ-K-CV-qgb4vG7zm1-H2F-Ms_nUovua9bv67YOEGX4S0PeoYdGxYj9KVf9cKPRg6MUgsvAhDGGqXZOwYAje8xeh7H/s640/5-25-2015+4-05-55+PM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush : xml&quot;&gt;&amp;lt;project&amp;gt;
    ....
    ....
    ....
    &amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;maven-shade-plugin&amp;lt;/artifactId&amp;gt;
                &amp;lt;version&amp;gt;2.0&amp;lt;/version&amp;gt;
                &amp;lt;executions&amp;gt;
                    &amp;lt;execution&amp;gt;
                        &amp;lt;phase&amp;gt;package&amp;lt;/phase&amp;gt;
                        &amp;lt;goals&amp;gt;
                            &amp;lt;goal&amp;gt;shade&amp;lt;/goal&amp;gt;
                        &amp;lt;/goals&amp;gt;
                        &amp;lt;configuration&amp;gt;
                            &amp;lt;transformers&amp;gt;
                                &amp;lt;transformer implementation=&quot;org.apache.maven.plugins.shade.resource.ManifestResourceTransformer&quot;&amp;gt;
                                    &amp;lt;mainClass&amp;gt;com.pamarin.runjar.App&amp;lt;/mainClass&amp;gt; &lt;!-- your main class --&gt;
                                &amp;lt;/transformer&amp;gt;
                            &amp;lt;/transformers&amp;gt;
                        &amp;lt;/configuration&amp;gt;
                    &amp;lt;/execution&amp;gt;
                &amp;lt;/executions&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;
4. Clean and Build project 1 ครั้ง เพื่อ load dependencies และ pack jar&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTL-IP0Qu0_tk67Cg7za-Kz1Ub-1Re3F1xJq7D62li5eRaBW_RM0PX6xVoCzH6nof_w068ZIcRMnEPNJcPghyphenhyphenikFQMsLFHlrtHiluYBdAD4NBc5VYekzV43NpXDuG1THmo82RY6OYsTp9L/s1600/5-25-2015+4-06-08+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;494&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTL-IP0Qu0_tk67Cg7za-Kz1Ub-1Re3F1xJq7D62li5eRaBW_RM0PX6xVoCzH6nof_w068ZIcRMnEPNJcPghyphenhyphenikFQMsLFHlrtHiluYBdAD4NBc5VYekzV43NpXDuG1THmo82RY6OYsTp9L/s640/5-25-2015+4-06-08+PM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
5. เข้าไปที่ project directory&lt;span style=&quot;color: red;&quot;&gt;&lt;u&gt;/target&lt;/u&gt;&lt;/span&gt; &amp;nbsp;แล้ว double click .jar file เพื่อ run program&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIn_s2_Tqo-ZupV5hD_KOzzXpk4kWFuvx6Lta420mIvfrjGQTd_dLochlgvKIGB0vkm7egRndO__Ax4_ZDHxhtKJwDokbIG8in4JEWq1i-kWXBNIcZ2NJGiyxq57Gp7eFFNqRNpmNxF6Ua/s1600/5-25-2015+4-07-39+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIn_s2_Tqo-ZupV5hD_KOzzXpk4kWFuvx6Lta420mIvfrjGQTd_dLochlgvKIGB0vkm7egRndO__Ax4_ZDHxhtKJwDokbIG8in4JEWq1i-kWXBNIcZ2NJGiyxq57Gp7eFFNqRNpmNxF6Ua/s640/5-25-2015+4-07-39+PM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;
หวังว่าจะเป็นประโยชน์สำหรับทุกคนที่เข้ามาอ่านน่ะครับ&lt;br /&gt;
&lt;br /&gt;
# ขออภัยสำหรับรูปภาพด้วย &amp;nbsp;เนื่องจากจอผมเป็นจอความละเอียดสูง &amp;nbsp;ตัวหนังสือบางตัวอาจจะดูค่อนข้างเล็กครับ :)&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/6569197068514763430/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/05/maven-jar-file-double-click-run-program.html#comment-form' title='3 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/6569197068514763430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/6569197068514763430'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/05/maven-jar-file-double-click-run-program.html' title='maven ทำ jar file ให้ double click run program ได้ : java'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3qrcBRAeIRDp6LWemf1Lz9__cDHIIMmR2ojG94k-TFRz9Zrhq7JHuqQg8j3zba3ZwnLbKmXM77649h3dqFallWwM47bAY8zJzdgcjlY-I77hUp09N9b-lwF2Rgkjp-y4dzZRsqxIYuct8/s72-c/5-25-2015+3-56-29+PM.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-8615369208679499660</id><published>2015-05-24T02:28:00.002-07:00</published><updated>2015-05-24T04:44:59.972-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>ฝึก recursive ด้วยโจทย์ความน่าจะเป็น</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBgTyFK-Ee8ZzVNdReBl2f7W2IkvpSP0zFmcaSH6wzwZNfogkqRIz8ulMMeK-M__byz8VFV7JdGdc6I221L3Rh1FkN68rBYQ-gckiRHYGfcMIBbnRhYksoZ_YJ6ZGB8taoDLKZCF7pwkC0/s1600/2000px-Dice_Distribution_%2528bar%2529.svg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;300&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBgTyFK-Ee8ZzVNdReBl2f7W2IkvpSP0zFmcaSH6wzwZNfogkqRIz8ulMMeK-M__byz8VFV7JdGdc6I221L3Rh1FkN68rBYQ-gckiRHYGfcMIBbnRhYksoZ_YJ6ZGB8taoDLKZCF7pwkC0/s400/2000px-Dice_Distribution_%2528bar%2529.svg.png&quot; style=&quot;border: none;&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; โจทย์นี้เป็นโจทย์ที่ผมใช้ฝึกวิธีคิด &amp;nbsp;การแก้ปัญหา &amp;nbsp;ซึ่งอาจมีคนคิด &amp;nbsp;หรือสร้าง tools สำเร็จรูปเอาไว้แล้ว &amp;nbsp;บางคนมาเห็นโพสต์นี้ อาจจะคิดว่าทำไมไม่ใช้เครื่องมือที่คนอื่นทำไว้แล้วล่ะ &amp;nbsp;จะมามัวเสียเวลาสร้างเองทำไม &amp;nbsp;ของคนอื่นอาจจะดีกว่าด้วยซ้ำ&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ครับ!!! ผมเคยได้ยินประโยคแบบนี้มานักต่อนักล่ะ &amp;nbsp;บางคนบอกว่าผมไม่รู้จักใช้เครื่องมือให้เกิดประโยชน์&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; คุณกำลังเข้าใจผิดกับคำว่า &amp;nbsp;&quot;การเลือกใช้เครื่องมือ&quot; &amp;nbsp;กับ &amp;nbsp;&quot;การฝึกทักษะการแก้ปัญหา&quot;&lt;br /&gt;
ที่ผมเขียนเอง เพราะผมต้องการฝึก skill เพื่อให้เกิดความคล่องตัว เมื่อเราเจอโจทย์ปัญหาลักษณะนี้ &amp;nbsp;เราจะแก้มันได้รึเปล่า ลองใช้ความคิดของเราดูสิ&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; skill&amp;nbsp;มันส่งต่อผ่านประสบการณ์กันไม่ได้&amp;nbsp; ต่อให้มีคนพยายามเล่าประสบการณ์ทั้งชีวิตของเขาให้คุณฟัง &amp;nbsp;คุณก็ทำแบบเขาไม่ได้ คุณต้องฝึก ฝึก ฝึก ลงมือทำด้วยตัวคุณเองครับ&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;ปัญหา&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; โดยทั่วไป การหาความน่าจะเป็นหรือความเป็นไปได้ของสมาชิกทั้งหมดภายในเซต S ซึ่งมีสมาชิกจำนวน n ตัว&lt;br /&gt;
คุณจะต้องวนลูปทั้งหมด n รอบ และลึก n ชั้น ถึงจะได้ค่าทั้งหมดออกมา &amp;nbsp;เช่น&lt;br /&gt;
&lt;br /&gt;
S = {&#39;A&#39;, &#39;B&#39;, &#39;C&#39;}&lt;br /&gt;
n = 3 ตัว&lt;br /&gt;
จำนวนความเป็นไปได้ทั้งหมดคือ 3 x 3 x 3 = 27 ค่า&lt;br /&gt;
&lt;br /&gt;
การเขียนโปรแกรมแบบง่ายๆ จะได้
&lt;br /&gt;
&lt;pre class=&quot;brush : js&quot;&gt;for (var i = 0; i &amp;lt; S.lenght; i++){
    for (var j = 0; j &amp;lt; S.lenght; j++){
        for (var k = 0; k &amp;lt; S.lenght; k++){
               print(S[i] + &#39;,&#39; + S[j] + &#39;,&#39; + S[k]);
        }
    }
}

A,A,A
A,A,B
A,A,C
A,B,A
A,B,B
...
...
...
C,B,C
C,C,A
C,C,B
C,C,C
&lt;/pre&gt;
&lt;u&gt;แล้วถ้าเขาต้องการให้คุณเขียน code ที่รองรับ S ที่มี size ขนาดใดก็ได้ คุณจะเขียนยังไง?&lt;/u&gt;&lt;br /&gt;
แน่นอน loop ใช้ไม่ได้ล่ะ  เพราะมัน fixed ตายตัว&lt;br /&gt;
แล้วอะไรที่เราเอามาใช้แทน loop ได้  แถมยังเป็นแบบ dynamic อีก &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;คำตอบคือ Recursive ครับ&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
code&lt;br /&gt;
&lt;pre class=&quot;brush : js&quot;&gt;function probabilityWalking(topElement, elements, index, callback){
    if (index &amp;lt; 0) {
        callback(topElement);
        return;
    }     

    for (var i=0; i &amp;lt; elements.length; i++) {
        probabilityWalking(
            (topElement ? (topElement + &#39;,&#39;) : topElement) + elements[i],
            elements,
            index - 1,
            callback 
        );
    }
}
&lt;/pre&gt;
using
&lt;br /&gt;
&lt;pre class=&quot;brush : js&quot;&gt;probabilityWalking(&#39;&#39;, [&#39;A&#39;, &#39;B&#39;], 1, function(el){
     console.log(el);     
});

A,A
A,B
B,A
B,B
&lt;/pre&gt;
&lt;pre class=&quot;brush : js&quot;&gt;probabilityWalking(&#39;&#39;, [&#39;A&#39;, &#39;B&#39;, &#39;C&#39;], 2, function(el){
     console.log(el);     
});

A,A,A
A,A,B
A,A,C
A,B,A
A,B,B
...
...
...
C,B,C
C,C,A
C,C,B
C,C,C
&lt;/pre&gt;
ตอนนี้ code เราสามารถหาความเป็นไปได้ทั้งหมดของ S ขนาดเท่าใดก็ได้ แล้วครับ :)&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;การนำแนวคิดไปประยุกต์ใช้&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
maven dependencies
&lt;br /&gt;
&lt;pre class=&quot;brush : xml&quot;&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.commons&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;commons-lang3&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;3.1&amp;lt;/version&amp;gt;
    &amp;lt;type&amp;gt;jar&amp;lt;/type&amp;gt;
&amp;lt;/dependency&amp;gt;

&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;4.10&amp;lt;/version&amp;gt;
    &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
Probability.java
&lt;br /&gt;
&lt;pre class=&quot;brush : java&quot;&gt;package com.blogspot.na5cent.learning;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;

/**
 * @author redcrow
 */
public class Probability {

    private static interface Callback {

        void call(String element);
    }

    private final List&amp;lt;String&amp;gt; elements;
    private boolean distinct = false;
    private boolean unique = false;
    private Integer size;
    private Set&amp;lt;String&amp;gt; signatures;

    private Probability(List&amp;lt;String&amp;gt; elements) {
        this.elements = elements;
    }

    public static Probability ofElements(String... elements) {
        return ofElements(Arrays.asList(elements));
    }

    public static Probability ofElements(List&amp;lt;String&amp;gt; elements) {
        return new Probability(elements);
    }

    public Probability size(int size) {
        this.size = size;
        return this;
    }

    public Probability distinct() {
        this.distinct = true;
        return this;
    }

    public Probability unique() {
        this.unique = true;
        return this;
    }

    private Set&amp;lt;String&amp;gt; getSignatures() {
        if (signatures == null) {
            signatures = new HashSet&amp;lt;&amp;gt;();
        }

        return signatures;
    }

    private boolean contains(String str, String target) {
        if (!str.isEmpty()) {
            String[] els = StringUtils.split(str, &quot;:&quot;);
            for (String el : els) {
                if (el.equals(target)) {
                    return true;
                }
            }
        }

        return false;
    }

    private String findSignature(String str) {
        String[] els = StringUtils.split(str, &quot;:&quot;);
        Arrays.sort(els);
        return StringUtils.join(els, &quot;:&quot;);
    }

    private boolean has(String element) {
        String signature = findSignature(element);
        if (getSignatures().contains(signature)) {
            return true;
        }

        getSignatures().add(signature);
        return false;
    }

    private void walking(String topElement, List&amp;lt;String&amp;gt; elements, int index, Callback callback) {
        if (index &amp;lt; 0) {
            if (unique &amp;amp;&amp;amp; has(topElement)) {
                return;
            }

            callback.call(topElement);
            return;
        }

        for (String element : elements) {
            if (distinct &amp;amp;&amp;amp; contains(topElement, element)) {
                continue;
            }

            walking(
                    (topElement.isEmpty() ? topElement : topElement + &quot;:&quot;) + element,
                    elements,
                    index - 1,
                    callback
            );
        }
    }

    public List&amp;lt;String&amp;gt; find() {
        if (size == null) {
            size = elements.size();
        }

        final List&amp;lt;String&amp;gt; results = new ArrayList&amp;lt;&amp;gt;();
        walking(&quot;&quot;, elements, size - 1, new Callback() {

            @Override
            public void call(String element) {
                results.add(element);
            }
        });

        return results;
    }
}
&lt;/pre&gt;
&lt;br /&gt;
ลองดูวิธีการเรียกใช้และผลลัพธ์ที่ Test&lt;br /&gt;
&lt;br /&gt;
ProbabilityTest.java
&lt;br /&gt;
&lt;pre class=&quot;brush : java&quot;&gt;package com.blogspot.na5cent.learning;

import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 * @author redcrow
 */
public class ProbabilityTest {

    @Test
    public void allOf2ElementsSize2() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;)
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:A&quot;,
                &quot;A:B&quot;,
                &quot;B:A&quot;,
                &quot;B:B&quot;
        );

        assertEquals(probs, results);
    }

    @Test
    public void allOf3ElementsSize3() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;)
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:A:A&quot;,
                &quot;A:A:B&quot;,
                &quot;A:A:C&quot;,
                &quot;A:B:A&quot;,
                &quot;A:B:B&quot;,
                &quot;A:B:C&quot;,
                &quot;A:C:A&quot;,
                &quot;A:C:B&quot;,
                &quot;A:C:C&quot;,
                &quot;B:A:A&quot;,
                &quot;B:A:B&quot;,
                &quot;B:A:C&quot;,
                &quot;B:B:A&quot;,
                &quot;B:B:B&quot;,
                &quot;B:B:C&quot;,
                &quot;B:C:A&quot;,
                &quot;B:C:B&quot;,
                &quot;B:C:C&quot;,
                &quot;C:A:A&quot;,
                &quot;C:A:B&quot;,
                &quot;C:A:C&quot;,
                &quot;C:B:A&quot;,
                &quot;C:B:B&quot;,
                &quot;C:B:C&quot;,
                &quot;C:C:A&quot;,
                &quot;C:C:B&quot;,
                &quot;C:C:C&quot;
        );

        assertEquals(probs, results);
    }

    @Test
    public void distinctOf2ElementsSize2() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;)
                .distinct() //ตัด A:A กับ B:B ออก เพราะ A กับ B ซ้ำกัน 2 ตัว
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:B&quot;,
                &quot;B:A&quot;
        );

        assertEquals(probs, results);
    }

    @Test
    public void distinctOf3ElementsSize3() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;)
                .distinct()
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:B:C&quot;,
                &quot;A:C:B&quot;,
                &quot;B:A:C&quot;,
                &quot;B:C:A&quot;,
                &quot;C:A:B&quot;,
                &quot;C:B:A&quot;
        );

        assertEquals(probs, results);
    }

    @Test
    public void distinctOf4ElementsSize2() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;)
                .distinct()
                .size(2)
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:B&quot;,
                &quot;A:C&quot;,
                &quot;A:D&quot;,
                &quot;B:A&quot;,
                &quot;B:C&quot;,
                &quot;B:D&quot;,
                &quot;C:A&quot;,
                &quot;C:B&quot;,
                &quot;C:D&quot;,
                &quot;D:A&quot;,
                &quot;D:B&quot;,
                &quot;D:C&quot;
        );

        assertEquals(probs, results);
    }

    @Test
    public void uniqueOf2ElementsSize2() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;)
                .unique()
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:A&quot;,
                &quot;A:B&quot;,
                &quot;B:B&quot;
        );

        assertEquals(probs, results);
    }

    @Test
    public void uniqueOf3ElementsSize3() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;)
                .unique()
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:A:A&quot;,
                &quot;A:A:B&quot;,
                &quot;A:A:C&quot;,
                &quot;A:B:B&quot;,
                &quot;A:B:C&quot;,
                &quot;A:C:C&quot;,
                &quot;B:B:B&quot;,
                &quot;B:B:C&quot;,
                &quot;B:C:C&quot;,
                &quot;C:C:C&quot;
        );

        assertEquals(probs, results);
    }

    @Test
    public void uniqueAndDistinctOf2ElementsSize2() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;)
                .distinct() //ตัด A:A กับ B:B ออก เพราะ A กับ B ซ้ำกัน 2 ตัว
                .unique() //A:B กับ B:A ถือเป็นตัวเดียวกัน แค่สลับตำแหน่ง
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:B&quot;
        );

        assertEquals(probs, results);
    }

    @Test
    public void uniqueAndDistinctOf3ElementsSize3() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;)
                .distinct()
                .unique()
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:B:C&quot;
        );

        assertEquals(probs, results);
    }

    @Test
    public void uniqueAndDistinctOf3ElementsSize2() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;)
                .distinct()
                .unique()
                .size(2)
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:B&quot;,
                &quot;A:C&quot;,
                &quot;B:C&quot;
        );

        assertEquals(probs, results);
    }

    @Test
    public void uniqueAndDistinctOf4ElementsSize2() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;)
                .distinct()
                .unique()
                .size(2)
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:B&quot;,
                &quot;A:C&quot;,
                &quot;A:D&quot;,
                &quot;B:C&quot;,
                &quot;B:D&quot;,
                &quot;C:D&quot;
        );

        assertEquals(probs, results);
    }

    @Test
    public void uniqueAndDistinctOf4ElementsSize3() {
        List&amp;lt;String&amp;gt; probs = Probability
                .ofElements(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;)
                .distinct()
                .unique()
                .size(3)
                .find();

        List&amp;lt;String&amp;gt; results = Arrays.asList(
                &quot;A:B:C&quot;,
                &quot;A:B:D&quot;,
                &quot;A:C:D&quot;,
                &quot;B:C:D&quot;
        );

        assertEquals(probs, results);
    }
}
&lt;/pre&gt;
code นี้เป็นส่วนนึงของโจทย์ที่ผมกำลังแก้อยู่ครับ  โจทย์มีอยู่ว่า
&lt;br /&gt;
&lt;br /&gt;
ให้เขียนโปรแกรมเพื่อหาสมการทั้งหมดที่เป็นไปได้ โดยให้เรา&lt;br /&gt;
1. ใส่คำตอบที่อยากจะได้ลงไป&lt;br /&gt;
2. ใส่ตัวเลขอะไรก็ได้ กี่ตัวก็ได้ลงไป (ในที่นี้คือ S)&lt;br /&gt;
3. ใส่ operators&amp;nbsp;+ หรือ - หรือ * หรือ / ลงไปกี่ตัวก็ได้ ใน 4 ตัวนี้&lt;br /&gt;
แล้วให้โปรแกรมคืนค่าสมการที่เกิดจากการป้อน input ข้อ 1- 3 ทั้งหมดออกมาครับ&lt;br /&gt;
&lt;br /&gt;
น่าสนุกน่ะ &lt;br /&gt;
ตอนนี้ผมเหลือเงื่อนไขวงเล็บทั้งหมดที่เป็นไปได้ &amp;nbsp;ตามจำนวนสมาชิกใน S ครับ&lt;br /&gt;
ยังคิดไม่ออก ฮ่าๆๆๆ&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/8615369208679499660/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/05/recursive.html#comment-form' title='1 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/8615369208679499660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/8615369208679499660'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/05/recursive.html' title='ฝึก recursive ด้วยโจทย์ความน่าจะเป็น'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBgTyFK-Ee8ZzVNdReBl2f7W2IkvpSP0zFmcaSH6wzwZNfogkqRIz8ulMMeK-M__byz8VFV7JdGdc6I221L3Rh1FkN68rBYQ-gckiRHYGfcMIBbnRhYksoZ_YJ6ZGB8taoDLKZCF7pwkC0/s72-c/2000px-Dice_Distribution_%2528bar%2529.svg.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-7913809419808453017</id><published>2015-04-18T09:05:00.003-07:00</published><updated>2015-04-19T20:18:35.852-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="angularjs"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><title type='text'>angularjs enumeration : javascript</title><content type='html'>Enum Factory
&lt;pre class=&quot;brush : js&quot;&gt;
var mapApp = ...

myApp.factory(&#39;Enumerate&#39;, function () {

    return function (list, fnc) {

        var Enumerate = function (ctx) {
            if (angular.isObject(ctx)) {
                angular.forEach(ctx, function (val, key) {
                    this[key] = val;
                }, this);
            } else if (angular.isString(ctx)) {
                this.name = ctx;
            } else {
                throw new Error(&#39;incorrect arguments.&#39;);
            }
        };

        Enumerate.values = [];

        Enumerate.valueOf = function (ctx) {
            var obj = null;
            angular.forEach(Enumerate.values, function (item) {
                if (item.name === ctx) {
                    obj = item;
                    return false;
                }
            });

            if (!obj) {
                obj = new Enumerate(ctx);
                Enumerate.values.push(obj);
            }

            return obj;
        }

        Enumerate.prototype.toString = function () {
            return this.name;
        };

        fnc &amp;&amp; angular.forEach(fnc, function (val, key) {
            Enumerate.prototype[key] = val;
        });

        angular.forEach(list, function (item) {
            Enumerate[
                    angular.isObject(item)
                    ? item.name
                    : item
            ] = Enumerate.valueOf(item);
        });

        return Enumerate;
    };
});
&lt;/pre&gt;
Using
&lt;pre class=&quot;brush : js&quot;&gt;
myApp..factory(&#39;StandardColumn&#39;, [
    &#39;Enumerate&#39;,
    function (Enumerate) {

        var StandardColumn = function () {

        };

        /* define enum */
        StandardColumn.Format = Enumerate([
            {name: &#39;STRING&#39;, description: &#39;ตัวหนังสือ&#39;},
            {name: &#39;NUMBER&#39;, description: &#39;ตัวเลข&#39;},
            {name: &#39;STUDENT&#39;, description: &#39;นักเรียน&#39;}
        ]);

        StandardColumn.Format.fromDescription = function (desc) {
            var obj = null;
            angular.forEach(StandardColumn.Format.values, function (item) {
                if (item.description === desc) {
                    obj = item;
                    return false;
                }
            })

            return obj;
        };

        StandardColumn.Operation = Enumerate([
            &#39;SUM&#39;,
            &#39;AVERAGE&#39;
        ]);

        StandardColumn.prototype = {
            id: null,
            name: null,
            sequence: 1,
            format: StandardColumn.Format.STRING,
            operation: null,
            operateWith: null
        };

        return StandardColumn;
    }
]);
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/7913809419808453017/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/04/angularjs-enumeration-javascript.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/7913809419808453017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/7913809419808453017'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/04/angularjs-enumeration-javascript.html' title='angularjs enumeration : javascript'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-8936977860098564147</id><published>2015-03-09T18:16:00.002-07:00</published><updated>2015-03-09T18:18:16.999-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>พีระมิต (pyramid) : java</title><content type='html'>วันนี้นั่งแย่งโจทย์น้องฝึกงานเล่นครับ
&lt;br /&gt;
&lt;pre class=&quot;brush : java&quot;&gt;package com.blogspot.na5cent.learning;

import java.util.Scanner;

/**
 * @author redcrow
 */
public class Pyramid {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int size = n * (n + 1) / 2;
        int bigSpace = (n - 1) / 2;

        for (int i = 1; i &amp;lt;= size; i++) {
            int numb = i % n;
            int space = bigSpace - i / n;

            boolean star = numb &amp;gt; space &amp;amp;&amp;amp; numb &amp;lt;= (n - space);
            System.out.print(star ? &quot;*&quot; : &quot; &quot;);
            System.out.print(numb == 0 ? &quot;\n&quot; : &quot;&quot;);
        }
    }
}
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihn1Y8Zfi956CCoejMBwc_ygxat4nPnTJo5B5284NKwDB9jkuHtLgYg-G16l-zKwEUTP0e-Ks6e7lJazNaDNIw97aF-tUd83eUHHNkyEywOEWL3J3CZhDyHmfAX09SMSh4wSS7LplD7oJ3/s1600/3-9-2015+7-35-23+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihn1Y8Zfi956CCoejMBwc_ygxat4nPnTJo5B5284NKwDB9jkuHtLgYg-G16l-zKwEUTP0e-Ks6e7lJazNaDNIw97aF-tUd83eUHHNkyEywOEWL3J3CZhDyHmfAX09SMSh4wSS7LplD7oJ3/s1600/3-9-2015+7-35-23+PM.png&quot; height=&quot;448&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/8936977860098564147/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/03/java.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/8936977860098564147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/8936977860098564147'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/03/java.html' title='พีระมิต (pyramid) : java'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihn1Y8Zfi956CCoejMBwc_ygxat4nPnTJo5B5284NKwDB9jkuHtLgYg-G16l-zKwEUTP0e-Ks6e7lJazNaDNIw97aF-tUd83eUHHNkyEywOEWL3J3CZhDyHmfAX09SMSh4wSS7LplD7oJ3/s72-c/3-9-2015+7-35-23+PM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-9115904408494086724</id><published>2015-03-04T02:45:00.005-08:00</published><updated>2015-03-04T03:20:04.178-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="spring  framework"/><title type='text'>Spring security bypass authen : java</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXnIP6uibYGk3swdsByg3_Zgg1hKj4kK85jt0QPr6ZTvlL6XOvoHi8uzLHvIrnSMmdglJITRHpU_ApEdpMog2TgiaGVPvTua1xux7m1uLke5azhElJK9WdjD6ThptmKhlTuiwaMP-FrbaA/s1600/3-4-2015+6-11-06+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXnIP6uibYGk3swdsByg3_Zgg1hKj4kK85jt0QPr6ZTvlL6XOvoHi8uzLHvIrnSMmdglJITRHpU_ApEdpMog2TgiaGVPvTua1xux7m1uLke5azhElJK9WdjD6ThptmKhlTuiwaMP-FrbaA/s1600/3-4-2015+6-11-06+PM.png&quot; height=&quot;278&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; บางครั้งเราต้องการให้ระบบ bypass authen (กระโดดข้ามการ authen) ด้วย username password&lt;br /&gt;
เราสามารถทำแบบนี้ได้ครับ &amp;nbsp;spring จะไม่ check username password เรา&lt;br /&gt;
เราแค่จับ ข้อมูล user (user details) ยัดเข้าไปใน spring context security เลย&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;ทำไมต้อง bypass&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; เนื่องจากการ authen แบบเดิม &amp;nbsp;เราต้องรู้ username และ clean password เพื่อ authen เข้าใช้งาน&lt;br /&gt;
มันเกิดปัญหาว่า &amp;nbsp;ระบบที่ผมทำ &amp;nbsp;ผมไม่ได้เก็บ password ของผู้ใช้เป็น clean text ไว้ &amp;nbsp;ผมเข้ารหัส password ไว้ตั้งแต่แรก (เพื่อความปลอดภัย) เพราะฉะนั้น &amp;nbsp;ผมจึงใช้วิธี authen แบบเดิมไม่ได้ (authen แบบเดิม &amp;nbsp;จะเอา password มา encrypt check กับ encrypt &amp;nbsp;password ที่มีอยู่ ว่า matches กันมั้ย)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ปัญหาต่อมา &amp;nbsp;คือ &amp;nbsp;ผมทำระบบที่สามารถ login ด้วยบัญชีผู้ใช้ facebook &amp;nbsp;แน่นอนว่ามันไม่มี password &amp;nbsp;เพราะ facebook ใช้ token &amp;nbsp;แล้วผมจะ &amp;nbsp;authen เข้าสู่ระบบที่ผมทำยังไง?&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; คิดอยู่สักพัก &amp;nbsp;ก็เกิดคำถามขึ้นมาในหัว &amp;nbsp;เราสามารถ bypass มันได้มั้ย ? &lt;br /&gt;
ก็เลยเป็นที่มาของบทความวันนี้ครับ&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;User.java
&lt;br /&gt;
&lt;pre class=&quot;brush : java&quot;&gt;...
...
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

public class User implements UserDetails {

    ....
    ....
}
&lt;/pre&gt;
BypassAuthen.java
&lt;br /&gt;
&lt;pre class=&quot;brush : java&quot;&gt;package com.blogspot.na5cent.security;

import com.blogspot.na5cent.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

/**
 * @author redcrow
 */
@Component
public class BypassAuthen {

    public void login(User user) {

        SecurityContext securityContext = SecurityContextHolder.getContext();
        Authentication authentication = new UsernamePasswordAuthenticationToken(
                user,
                null,
                user.getAuthorities()
        );

        securityContext.setAuthentication(authentication);
    }

}
&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/9115904408494086724/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/03/spring-security-bypass-authen.html#comment-form' title='37 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/9115904408494086724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/9115904408494086724'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/03/spring-security-bypass-authen.html' title='Spring security bypass authen : java'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXnIP6uibYGk3swdsByg3_Zgg1hKj4kK85jt0QPr6ZTvlL6XOvoHi8uzLHvIrnSMmdglJITRHpU_ApEdpMog2TgiaGVPvTua1xux7m1uLke5azhElJK9WdjD6ThptmKhlTuiwaMP-FrbaA/s72-c/3-4-2015+6-11-06+PM.png" height="72" width="72"/><thr:total>37</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-9155422427153451463</id><published>2015-02-03T01:19:00.000-08:00</published><updated>2015-02-03T01:51:31.092-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="oracle sql"/><title type='text'>oracle sql order by multiple point string </title><content type='html'>&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;ปัญหา&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
ถ้าเรา order by string แบบธรรมดาๆ &amp;nbsp;เราจะเจอปัญหาแบบนี้&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUh8KsWyA1Pok_4Rgkw7srGXj-etbrjekiFsfqHmtBBQSV8qK2CxpGQFGA30DTsD2ULdrCkRtKgF-wl2vY2_MZEDk8FVVociJFfcv5lNnq11Y1pODnGjyd7NFQaueim3-wJ-0me0LMANPc/s1600/2-3-2015+4-16-32+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUh8KsWyA1Pok_4Rgkw7srGXj-etbrjekiFsfqHmtBBQSV8qK2CxpGQFGA30DTsD2ULdrCkRtKgF-wl2vY2_MZEDk8FVVociJFfcv5lNnq11Y1pODnGjyd7NFQaueim3-wJ-0me0LMANPc/s1600/2-3-2015+4-16-32+PM.png&quot; height=&quot;640&quot; width=&quot;446&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
การ order by string &amp;nbsp;10 จะมาก่อน 2 &amp;nbsp;เพราะรหัส ASCII ของ 1 อยู่ก่อน 2&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;วิธีแก้&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
เปลี่ยนมา order by ด้วย sql function ที่ผมเขียนขึ้นมาใหม่ &amp;nbsp;ได้เป็น&lt;/div&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAPTW3ioYYfXICgVTKDya-7Wm5U5TR20EsHRvpPMD7vo1efM5C8VfGs_5IUq1U7PwbiMPE-Qpp5mhPIxq2PTao6X84f9Lx6dsGI2RS8eIz50Rk3sT2KfUeSG-ryRQh19Vrl5XIef75bVa7/s1600/2-3-2015+4-17-36+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAPTW3ioYYfXICgVTKDya-7Wm5U5TR20EsHRvpPMD7vo1efM5C8VfGs_5IUq1U7PwbiMPE-Qpp5mhPIxq2PTao6X84f9Lx6dsGI2RS8eIz50Rk3sT2KfUeSG-ryRQh19Vrl5XIef75bVa7/s1600/2-3-2015+4-17-36+PM.png&quot; height=&quot;614&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
การแสดงผล &amp;nbsp;ถูกต้อง &amp;nbsp;เพราะเราแปลงมันไปเป็นตัวเลขก่อน&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
PL/SQL สำหรับแปลง multiple point ไปเป็นตัวเลข&lt;/div&gt;
&lt;/div&gt;
&lt;pre class=&quot;brush : sql&quot;&gt;CREATE OR REPLACE PACKAGE converter_pack AS

    FUNCTION pad_string(p_multiple_point VARCHAR2, p_index NUMBER) RETURN VARCHAR2;
  
    FUNCTION multiple_point2number(p_multiple_point VARCHAR2, p_point NUMBER) RETURN NUMBER;
  
END converter_pack;

/* package body */
CREATE OR REPLACE PACKAGE body converter_pack AS

    FUNCTION pad_string( p_multiple_point VARCHAR2, p_index NUMBER) RETURN VARCHAR2 AS
      l_pad VARCHAR2(255);
    BEGIN
      SELECT lpad(regexp_substr (p_multiple_point, &#39;[^.]+&#39;, 1, p_index), 3, &#39;0&#39;)
      INTO l_pad
      FROM dual;
      
      RETURN l_pad;
    END pad_string;
    
    FUNCTION multiple_point2number(p_multiple_point VARCHAR2, p_point NUMBER) RETURN NUMBER AS
      l_temp VARCHAR2(255);
      l_numb VARCHAR2(255);
    BEGIN
      FOR i IN 1..p_point LOOP
        l_temp   := pad_string(p_multiple_point, i);
        IF l_temp = &#39;&#39; OR l_temp IS NULL THEN
          l_temp := &#39;000&#39;;
        END IF;
        l_numb := l_numb || l_temp;
      END LOOP;
      
      RETURN to_number(l_numb);
    END multiple_point2number;

END converter_pack;
&lt;/pre&gt;
การเรียกใช้
&lt;br /&gt;
&lt;pre class=&quot;brush : sql&quot;&gt;select SEQUENCE_ORDER,
       converter_pack.multiple_point2number(SEQUENCE_ORDER, 5) as numb
from MY_TABLE
order by numb
&lt;/pre&gt;
multiple_point2number(p_multiple_point VARCHAR2, p_point NUMBER)

&lt;br /&gt;
&lt;br /&gt;
p_multiple_point คือ String multiple point ที่เราส่งเข้าไป &amp;nbsp;เช่น 1.2.3.4&lt;br /&gt;
p_point คือ จำนวนจุด (.) สูงสุด &amp;nbsp;ที่คิดว่าจะมีใน p_multiple_point &amp;nbsp;ซึ่งของผมคือ 5 (เช่น 1.2.3.4.5.6)</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/9155422427153451463/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/02/oracle-sql-order-by-multiple-point.html#comment-form' title='2 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/9155422427153451463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/9155422427153451463'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/02/oracle-sql-order-by-multiple-point.html' title='oracle sql order by multiple point string '/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUh8KsWyA1Pok_4Rgkw7srGXj-etbrjekiFsfqHmtBBQSV8qK2CxpGQFGA30DTsD2ULdrCkRtKgF-wl2vY2_MZEDk8FVVociJFfcv5lNnq11Y1pODnGjyd7NFQaueim3-wJ-0me0LMANPc/s72-c/2-3-2015+4-16-32+PM.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-2161140942226315579</id><published>2015-02-01T09:46:00.000-08:00</published><updated>2020-01-17T00:26:53.926-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="development"/><title type='text'>ทำความรู้จักกับ JWT (Json Web Token)</title><content type='html'>ย้ายบทความไปไว้ที่&amp;nbsp;&lt;a href=&quot;https://www.jittagornp.me/blog/what-is-jwt/&quot;&gt;https://www.jittagornp.me/blog/what-is-jwt/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/2161140942226315579/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/02/jwt-json-web-token.html#comment-form' title='10 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/2161140942226315579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/2161140942226315579'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/02/jwt-json-web-token.html' title='ทำความรู้จักกับ JWT (Json Web Token)'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-4084683654941969304</id><published>2015-01-29T21:42:00.001-08:00</published><updated>2015-01-29T21:42:33.973-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="oracle sql"/><title type='text'>Oracle SQL แยกหัวข้อ  ออกจากข้อความ</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip6JqY-JaUXF5urXDI_9dARN7-lL-lx5R4pL2T6GwgOLXwqvrPUd2ZwTYPO7vgvQYuvOrM_l0OwZP2YoApmYRx2kSx5K2W5Jcc9QnmQlR7E4maijvHdIaon85Lyvp7gOfwLYV0y8oQ9_Ii/s1600/1-30-2015+12-06-21+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip6JqY-JaUXF5urXDI_9dARN7-lL-lx5R4pL2T6GwgOLXwqvrPUd2ZwTYPO7vgvQYuvOrM_l0OwZP2YoApmYRx2kSx5K2W5Jcc9QnmQlR7E4maijvHdIaon85Lyvp7gOfwLYV0y8oQ9_Ii/s1600/1-30-2015+12-06-21+PM.png&quot; height=&quot;466&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
code
&lt;br /&gt;
&lt;pre class=&quot;brush : sql&quot;&gt;select data.*,
       trim(replace(data.old_name, (numb), &#39;&#39;)) new_name
from(
  select name old_name, 
         regexp_substr(name, &#39;^[0-9ก-ฮ\.]+\)*\s&#39;) numb
  from MY_TABLE
) data
&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/4084683654941969304/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/01/oracle-sql_29.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/4084683654941969304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/4084683654941969304'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/01/oracle-sql_29.html' title='Oracle SQL แยกหัวข้อ  ออกจากข้อความ'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip6JqY-JaUXF5urXDI_9dARN7-lL-lx5R4pL2T6GwgOLXwqvrPUd2ZwTYPO7vgvQYuvOrM_l0OwZP2YoApmYRx2kSx5K2W5Jcc9QnmQlR7E4maijvHdIaon85Lyvp7gOfwLYV0y8oQ9_Ii/s72-c/1-30-2015+12-06-21+PM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-363728414242567890</id><published>2015-01-27T20:00:00.002-08:00</published><updated>2020-01-12T06:10:04.116-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>ทำความรู้จักกับ Java Stream</title><content type='html'>&lt;span style=&quot;background-color: white; color: #666666; font-family: &amp;quot;Trebuchet MS&amp;quot;, Trebuchet, sans-serif; font-size: 13px;&quot;&gt;ทำการย้ายบทความไปไว้ที่&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: white; color: #666666; filter: initial !important; font-family: &amp;quot;Trebuchet MS&amp;quot;, Trebuchet, sans-serif; font-size: 13px;&quot;&gt;
&lt;br style=&quot;filter: initial !important;&quot; /&gt;&lt;div style=&quot;filter: initial !important;&quot;&gt;
&lt;a href=&quot;https://www.jittagornp.me/blog/java-io-stream/&quot;&gt;https://www.jittagornp.me/blog/java-io-stream/&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/363728414242567890/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/01/java-stream.html#comment-form' title='5 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/363728414242567890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/363728414242567890'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/01/java-stream.html' title='ทำความรู้จักกับ Java Stream'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-7400710484875682728</id><published>2015-01-21T20:27:00.001-08:00</published><updated>2015-01-21T21:36:25.029-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="oracle sql"/><title type='text'>แก้ปัญหา multiple values sql IN : oracle</title><content type='html'>คำสั่ง IN เป็นคำสั่งที่ใช้สำหรับตรวจสอบว่า &amp;nbsp;ค่าที่เลือกมานั้น &amp;nbsp;มีอยู่ใน IN หรือไม่ &amp;nbsp;เช่น
&lt;br /&gt;
&lt;pre class=&quot;brush : sql&quot;&gt;...
...
SELECT code
FROM ...
WHERE code IN(&#39;AAA&#39;, &#39;BBB&#39;, &#39;CCC&#39;)
...
...
&lt;/pre&gt;
ซึงเราสามารถตรวจสอบได้เพียง  ครั้งละ 1 ค่าเท่านั้น (single value)&lt;br /&gt;
ในที่นี้ field&amp;nbsp;&lt;i&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;code&lt;/span&gt;&lt;/i&gt; สามารถเป็น &lt;span style=&quot;color: #3d85c6;&quot;&gt;AAA &lt;/span&gt;หรือ &lt;span style=&quot;color: #3d85c6;&quot;&gt;BBB&lt;/span&gt; หรือ &lt;span style=&quot;color: #3d85c6;&quot;&gt;CCC&lt;/span&gt; ได้เท่านั้น (ถึงจะ match กัน)&lt;br /&gt;
ไม่สามารถเป็น multiple values เช่น &lt;span style=&quot;color: #3d85c6;&quot;&gt;&#39;AAA, BBB&#39; &lt;/span&gt;หรือ &lt;span style=&quot;color: #3d85c6;&quot;&gt;&#39;BBB, CCC&#39;&lt;/span&gt; ได้ เพราะมันจะไม่ตรงกับตัวไหนใน IN เลย&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&amp;nbsp;&#39;AAA, BBB&#39; &lt;/span&gt;ไม่ match กับ &lt;span style=&quot;color: #3d85c6;&quot;&gt;&#39;AAA&#39;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&amp;nbsp;&#39;AAA, BBB&#39;&lt;/span&gt; ไม่ match กับ&lt;span style=&quot;color: #3d85c6;&quot;&gt; &#39;BBB&#39;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&amp;nbsp;&#39;AAA, BBB&#39;&lt;/span&gt; ไม่ match กับ &lt;span style=&quot;color: #3d85c6;&quot;&gt;&#39;CCC&#39;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
แล้วถ้าเราต้องการให้มัน match กันละ &amp;nbsp;เราจะทำยังไง?&lt;br /&gt;
เพราะตามความเป็นจริงแล้ว &lt;span style=&quot;color: #3d85c6;&quot;&gt;&amp;nbsp;&#39;AAA, BBB&#39; &lt;/span&gt;มันควรจะ match กับทั้ง &amp;nbsp;&lt;span style=&quot;color: #3d85c6;&quot;&gt;&#39;AAA&#39;&lt;/span&gt; และ&lt;span style=&quot;color: #3d85c6;&quot;&gt; &#39;BBB&#39;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;มาดูแนวคิด&amp;nbsp;&lt;complete id=&quot;goog_1097330214&quot;&gt;+&amp;nbsp;&lt;/complete&gt;วิธีแก้ของผมกันครับ&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
sql IN เป็นคำสั่งที่ใช้ข้อมูลในแต่ละ rows มา IN&lt;br /&gt;
ฉะนั้น &amp;nbsp;เราต้องแปลง &#39;AAA, BBB&#39; ของเราให้ไปเป็น rows ก่อน &amp;nbsp;จากบทความนี้ครับ&amp;nbsp;&lt;a href=&quot;http://na5cent.blogspot.com/2015/01/split-string-to-rows-oracle-sql.html&quot;&gt;Split String to rows : Oracle SQL&lt;/a&gt;&amp;nbsp; ได้ผลลัพดังนี้&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV21yQ6Woz5l-pEC8kYfUSttlYWi-d8IZqL7D1wkJAzN-w8Y0WayXyH_iIYFNYaJRDdOuT2LrmLeTpv-NpNBtUDrUiaib1xsJV29z2ZHOzgukd9CyGh9j9tYZvjN5RM7ZXM__2VlCL9EAT/s1600/1-22-2015+11-42-48+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV21yQ6Woz5l-pEC8kYfUSttlYWi-d8IZqL7D1wkJAzN-w8Y0WayXyH_iIYFNYaJRDdOuT2LrmLeTpv-NpNBtUDrUiaib1xsJV29z2ZHOzgukd9CyGh9j9tYZvjN5RM7ZXM__2VlCL9EAT/s1600/1-22-2015+11-42-48+AM.png&quot; height=&quot;322&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
พอเราได้ rows มาแล้ว &amp;nbsp;เราก็สามารถใช้ sql IN ได้ &lt;br /&gt;
แต่! &amp;nbsp;คำตอบที่ได้ออกมา &amp;nbsp;มันเป็น การลด rows ลงเฉยๆ &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYH1J5ULqYl9hLGRNmddPmq-VZTlCXvsGh9Yix_xhn4jQ6Dex8JxegWbczuMzSe9RyI3RLr9ARP68T1LaPFXQYoqQ5aclr9F0wQtUz0XPua3RzRCovNBvvYS3Oq8bSGSYxcU7YoLyLY7KK/s1600/1-22-2015+11-49-09+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYH1J5ULqYl9hLGRNmddPmq-VZTlCXvsGh9Yix_xhn4jQ6Dex8JxegWbczuMzSe9RyI3RLr9ARP68T1LaPFXQYoqQ5aclr9F0wQtUz0XPua3RzRCovNBvvYS3Oq8bSGSYxcU7YoLyLY7KK/s1600/1-22-2015+11-49-09+AM.png&quot; height=&quot;368&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
จริงๆ ผลลัพธ์ที่เราต้องการคือ ตอบว่า match หรือไม่ match เท่านั้น (ตอบเป็น boolean หรือ 1 กับ 0)&lt;br /&gt;
เราจึงครอบมันด้วยการ count &amp;nbsp;แล้วเช็คว่าถ้า count แล้วมากกว่า 0 ก็แสดงว่า match &amp;nbsp;(ตอบ 1) แต่ถ้าเท่ากับ 0 ก็คือไม่ match (ตอบ 0)&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjmdXI6WI4BkMkSDVp02tDO1nxskjwz30_leUaap_ZeGgnvrpvJDrS11QHhq8B6l3ptXK2Gm7wWzXR996XLKfTtzyhvN0jGD9sG3cvYBzp0fm5mfik0ME5tlUiqEacol5kkNHULNfiyx60/s1600/1-22-2015+11-46-43+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjmdXI6WI4BkMkSDVp02tDO1nxskjwz30_leUaap_ZeGgnvrpvJDrS11QHhq8B6l3ptXK2Gm7wWzXR996XLKfTtzyhvN0jGD9sG3cvYBzp0fm5mfik0ME5tlUiqEacol5kkNHULNfiyx60/s1600/1-22-2015+11-46-43+AM.png&quot; height=&quot;352&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
โอเค &amp;nbsp;แนวคิดนี้ใช้ได้ &amp;nbsp;ท่าทางจะ work &lt;br /&gt;
&lt;u&gt;&lt;b&gt;แต่ก็ยังเจอปัญหาอยู่ดี&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
ตอนนี้ &lt;span style=&quot;color: #3d85c6;&quot;&gt;&#39;AAA, BBB, CCC&#39; &lt;/span&gt;เราเป็น fixed code ถ้าเราต้องการส่งค่านี้มาจากการ select ข้างนอกล่ะ เราจะทำยังไง &amp;nbsp;คำตอบคือ &amp;nbsp;&lt;u&gt;&lt;span style=&quot;color: red;&quot;&gt;ไม่ได้&lt;/span&gt;&lt;/u&gt; &amp;nbsp;เพราะมันมี select count ครอบอยู่ 1 ชั้น &amp;nbsp;ที่กันไม่ให้ select ชั้นนอก &amp;nbsp;ส่ง field select เข้ามาได้ &lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;ชิปหายล่ะ &lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&amp;nbsp;แนวคิดได้ &amp;nbsp;แต่ดันตายที่ select count &amp;nbsp;กั้นอยู่ &amp;nbsp;จะแก้ปัญหานี้ยังไง?&lt;br /&gt;
แนวทางการแก้ปัญหาของผมคือ&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;color: red; font-size: large;&quot;&gt;ทำยังไงก็ได้ &amp;nbsp;ให้ select count มันอยู่ชั้นเดียวกับ &#39;AAA, BBB, CCC&#39; &lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
นั่งคิดอยู่สักพักนึงครับ &amp;nbsp; โอเค &amp;nbsp;ผมเกทล่ะ&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;แนวคิดเดิม &amp;nbsp;แต่เปลี่ยนกรรมวิธีใหม่&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
ใช้ procedure (PL/SQL) เข้ามาช่วย &amp;nbsp;รวบคำสั่ง split row to string ไปไว้ใน sql function ดังนี้&lt;br /&gt;
(&lt;a href=&quot;http://na5cent.blogspot.com/2014/08/define-oracle-plsql-collection-object.html&quot;&gt;define oracle pl/sql collection (object and table) types&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
define type
&lt;br /&gt;
&lt;pre class=&quot;brush :sql&quot;&gt;CREATE OR REPLACE TYPE string_list AS TABLE OF varchar2(255);
&lt;/pre&gt;
write procedure
&lt;br /&gt;
&lt;pre class=&quot;brush : sql&quot;&gt;CREATE OR REPLACE FUNCTION split_string2list(p_string VARCHAR2) RETURN string_list AS
  l_list string_list := string_list();
BEGIN
  FOR rcd IN
  ( 
  SELECT DISTINCT str --reduce duplicate string
     FROM
     (
   SELECT trim(regexp_substr(p_string, &#39;[^,]+&#39;, 1, LEVEL)) str
         FROM dual
         CONNECT BY LEVEL &amp;lt;= regexp_count(p_string, &#39;,&#39;)+1
     )
     WHERE str IS NOT NULL
  )
  LOOP
    l_list.extend();
    l_list(l_list.last) := rcd.str;
  END LOOP;
  
  RETURN l_list;
  
  EXCEPTION WHEN OTHERS THEN
      RETURN NULL;

END split_string2list;
&lt;/pre&gt;
ลองเขียน code select ใหม่&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_EzC2Hjw25FxSkz3cdLqf-2Xi1Q8DkFmmRrGMB8zZC4oohGb2M420nrzZlDPitT8bCMaMrxHtGR7ufzh_3KXfidl9lqaGQaJcFck4w6Jj89M_Q0eXQeq4Ty1LAiRBLnziRRTBmWNo1M6g/s1600/1-22-2015+12-10-54+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_EzC2Hjw25FxSkz3cdLqf-2Xi1Q8DkFmmRrGMB8zZC4oohGb2M420nrzZlDPitT8bCMaMrxHtGR7ufzh_3KXfidl9lqaGQaJcFck4w6Jj89M_Q0eXQeq4Ty1LAiRBLnziRRTBmWNo1M6g/s1600/1-22-2015+12-10-54+PM.png&quot; height=&quot;338&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
ได้ล่ะ สั้นๆ &amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7TPXaEIezMl8Iq258hXZY88lP47v1OPei4bAgIttWBBxOhrAbEAGFMiQnoMlag5VfOpVnRPId6pIHoEFLTwa9IVOIGtMeise4Ck9hpaKnmTNGbrjUdbgpbqKlUdFMSppowIK4YxFmGpEj/s1600/1-22-2015+12-12-43+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7TPXaEIezMl8Iq258hXZY88lP47v1OPei4bAgIttWBBxOhrAbEAGFMiQnoMlag5VfOpVnRPId6pIHoEFLTwa9IVOIGtMeise4Ck9hpaKnmTNGbrjUdbgpbqKlUdFMSppowIK4YxFmGpEj/s1600/1-22-2015+12-12-43+PM.png&quot; height=&quot;310&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
ตอนนี้ไม่มี select count มาครอบมันล่ะ &amp;nbsp;เพราะ count อยู่ใน LEVEL เดียวกัน &amp;nbsp;โอเค &amp;nbsp;แก้ปัญหาได้ล่ะ&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
ต่อไป &amp;nbsp;เราก็สามารถส่ง select field จากข้างนอก &amp;nbsp;เข้ามา check ได้ว่า field นี้ match กับที่อยู่ใน IN หรือไม่ &amp;nbsp;โดยสามารถส่งเข้ามาเป็น multiple values ใน column เดียวได้ครับ&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
หวังว่าบทความนี้จะเป็นประโยชน์สำหรับ developer ทุกคนที่เข้ามาอ่านน่ะครับ :)&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/7400710484875682728/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/01/multiple-values-sql-in-oracle.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/7400710484875682728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/7400710484875682728'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/01/multiple-values-sql-in-oracle.html' title='แก้ปัญหา multiple values sql IN : oracle'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV21yQ6Woz5l-pEC8kYfUSttlYWi-d8IZqL7D1wkJAzN-w8Y0WayXyH_iIYFNYaJRDdOuT2LrmLeTpv-NpNBtUDrUiaib1xsJV29z2ZHOzgukd9CyGh9j9tYZvjN5RM7ZXM__2VlCL9EAT/s72-c/1-22-2015+11-42-48+AM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-605765954836193529</id><published>2015-01-19T04:58:00.000-08:00</published><updated>2015-01-19T05:01:05.184-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="oracle sql"/><title type='text'>Split String to rows : Oracle SQL</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
บางครั้งเราอาจเจอโจทย์ที่ต้องแยก String ออกเป็นหลายๆ rows ครับ&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6bXTrkYEmV_724EGNhVYTi3C6VvEGSmz4NQCAByMZOkwsbPA2h9rnamhyphenhyphenEFWQNJC3omRiGujGdDP2CrZUC2QGdV9Csh4uc-1A4x4wUrIlu1m4UIz_cV6G0bHLleYS09bfmTv2HTLmVsKk/s1600/1-19-2015+7-56-55+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6bXTrkYEmV_724EGNhVYTi3C6VvEGSmz4NQCAByMZOkwsbPA2h9rnamhyphenhyphenEFWQNJC3omRiGujGdDP2CrZUC2QGdV9Csh4uc-1A4x4wUrIlu1m4UIz_cV6G0bHLleYS09bfmTv2HTLmVsKk/s1600/1-19-2015+7-56-55+PM.png&quot; height=&quot;280&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush : sql&quot;&gt;SELECT trim(regexp_substr(&#39;String1,String2,String3&#39;, &#39;[^,]+&#39;, 1, LEVEL)) str_2_tab
FROM dual
CONNECT BY LEVEL &amp;lt;= regexp_count(&#39;String1,String2,String3&#39;, &#39;,&#39;)+1
&lt;/pre&gt;
thank you : &lt;a href=&quot;http://stackoverflow.com/questions/14328621/oracle-10g-splitting-string-into-multiple-rows&quot;&gt;http://stackoverflow.com/questions/14328621/oracle-10g-splitting-string-into-multiple-rows&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/605765954836193529/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/01/split-string-to-rows-oracle-sql.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/605765954836193529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/605765954836193529'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/01/split-string-to-rows-oracle-sql.html' title='Split String to rows : Oracle SQL'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6bXTrkYEmV_724EGNhVYTi3C6VvEGSmz4NQCAByMZOkwsbPA2h9rnamhyphenhyphenEFWQNJC3omRiGujGdDP2CrZUC2QGdV9Csh4uc-1A4x4wUrIlu1m4UIz_cV6G0bHLleYS09bfmTv2HTLmVsKk/s72-c/1-19-2015+7-56-55+PM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-8640411379125881481</id><published>2015-01-09T02:00:00.001-08:00</published><updated>2015-01-12T02:38:42.460-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="oracle sql"/><title type='text'>แก้ปัญหา Oracle SQL LISTAGG not support</title><content type='html'>LISTAGG เป็น aggregate function ที่เอาไว้ join multiple row ให้เป้น single row &amp;nbsp;เช่น&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicJsIvu0xBJuI4Qnq0BkzkElA9WESnnWIhm0yyOR8j1PMS9YOShVGtFsvleZ0mnc0V4SfrS_1lgJa8xaZuuyyKF0k1ffzh101nOuySJll-vTpQqCtljYlxlgugwyri4WBIV6EHbIcL0iEG/s1600/1-9-2015+4-58-53+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicJsIvu0xBJuI4Qnq0BkzkElA9WESnnWIhm0yyOR8j1PMS9YOShVGtFsvleZ0mnc0V4SfrS_1lgJa8xaZuuyyKF0k1ffzh101nOuySJll-vTpQqCtljYlxlgugwyri4WBIV6EHbIcL0iEG/s1600/1-9-2015+4-58-53+PM.png&quot; height=&quot;266&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZxbYVRfODkODRJu9hWDi87LgQZxmpYCE_C2hADjpqmghJxAGw2keyTi7Olzqel181TOb9hFegDxMXtP7vr-_eeB3HYU-_OEKG-0wmQC6C97o5eCleEFMTUn1XpKXHGlfcgZ5gDYKKMALb/s1600/1-9-2015+4-59-28+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZxbYVRfODkODRJu9hWDi87LgQZxmpYCE_C2hADjpqmghJxAGw2keyTi7Olzqel181TOb9hFegDxMXtP7vr-_eeB3HYU-_OEKG-0wmQC6C97o5eCleEFMTUn1XpKXHGlfcgZ5gDYKKMALb/s1600/1-9-2015+4-59-28+PM.png&quot; height=&quot;140&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
ถ้าเรา run SQL นี้ไม่ได้ (เนื่องจาก version ไม่ support)&lt;br /&gt;
&lt;pre class=&quot;brush : sql&quot;&gt;select gp, LISTAGG(name, &#39;, &#39;) WITHIN GROUP (ORDER BY name) name
from(
  select &#39;A&#39; gp, 1 name from dual
  UNION
  select &#39;A&#39; gp, 2 name from dual
  UNION
  select &#39;A&#39; gp, 3 name from dual
  UNION
  select &#39;A&#39; gp, 4 name from dual
   UNION
  select &#39;B&#39; gp, 5 name from dual
  UNION
  select &#39;B&#39; gp, 6 name from dual
  UNION
  select &#39;B&#39; gp, 7 name from dual
  UNION
  select &#39;B&#39; gp, 8 name from dual
)

group by gp
&lt;/pre&gt;
ลอง run แบบนี้ดูครับ
&lt;br /&gt;
&lt;pre class=&quot;brush : sql&quot;&gt;select gp, RTRIM (XMLAGG (XMLELEMENT (e, name || &#39;, &#39;)).EXTRACT (&#39;//text()&#39;), &#39;, &#39;) name
from(
  select &#39;A&#39; gp, 1 name from dual
  UNION
  select &#39;A&#39; gp, 2 name from dual
  UNION
  select &#39;A&#39; gp, 3 name from dual
  UNION
  select &#39;A&#39; gp, 4 name from dual
   UNION
  select &#39;B&#39; gp, 5 name from dual
  UNION
  select &#39;B&#39; gp, 6 name from dual
  UNION
  select &#39;B&#39; gp, 7 name from dual
  UNION
  select &#39;B&#39; gp, 8 name from dual
)

group by gp
&lt;/pre&gt;
ถ้าทำแล้วมันมี string ที่ซ้ำกันแล้วเราต้องการลบตัวที่ซ้ำ  ใช้  ตัวนี้ช่วยครับ
&lt;br /&gt;
&lt;pre class=&quot;brush : sql&quot;&gt;...
... /* replace YOUR_STRING */
...
REGEXP_REPLACE(REGEXP_REPLACE(regexp_replace( YOUR_STRING ,&#39;([^,]+)(, \1)+&#39;, &#39;\1&#39;),&#39;,{2,}&#39;,&#39;,&#39;),&#39;^,|,$&#39;,&#39;&#39;)
...
...
&lt;/pre&gt;
Thank you : &lt;a href=&quot;http://stackoverflow.com/questions/468990/how-can-i-combine-multiple-rows-into-a-comma-delimited-list-in-oracle&quot;&gt;http://stackoverflow.com/questions/468990/how-can-i-combine-multiple-rows-into-a-comma-delimited-list-in-oracle&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/8640411379125881481/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/01/oracle-sql-listagg.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/8640411379125881481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/8640411379125881481'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/01/oracle-sql-listagg.html' title='แก้ปัญหา Oracle SQL LISTAGG not support'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicJsIvu0xBJuI4Qnq0BkzkElA9WESnnWIhm0yyOR8j1PMS9YOShVGtFsvleZ0mnc0V4SfrS_1lgJa8xaZuuyyKF0k1ffzh101nOuySJll-vTpQqCtljYlxlgugwyri4WBIV6EHbIcL0iEG/s72-c/1-9-2015+4-58-53+PM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-8826191486323023195</id><published>2015-01-06T01:25:00.005-08:00</published><updated>2015-01-06T04:12:04.891-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>Excel Object Mapping</title><content type='html'>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; บางครั้งเราอาจเจอโปรเจ็คที่ลูกค้าต้องการ &amp;nbsp;ให้ import ข้อมูลจาก excel เข้าไปในฐานข้อมูล&lt;br /&gt;
แต่มันไม่ได้ง่ายขนาดที่ว่า &amp;nbsp;เอา excel มายัดลงข้อมูลได้เลย &amp;nbsp;เนื่องจากรูปแบบข้อมูลที่แต่ละคนกำหนดมา &amp;nbsp;ไม่เหมือนกัน (วาง column ไม่ตรง &amp;nbsp;pattern ข้อมูลไม่ถูกต้อง) &amp;nbsp;และต้องการให้เรา validate ข้อมูลก่อนนำเข้า &amp;nbsp;จึงเป็นที่มาของการเขียนโปรแกรม เพื่ออ่านข้อมูลจาก excel file ไปเป็น java object &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ทำครั้งแรกครั้งที่ 2 ก็ไม่เท่าไหร่ &amp;nbsp;แต่ทำซ้ำไปซ้ำมา &amp;nbsp;รู้สึกว่า &amp;nbsp;มันเริ่มไม่โอเคล่ะ &amp;nbsp;เขียน code เดิมๆ ไม่ได้ความรู้อะไรใหม่ขึ้นมาเลย &amp;nbsp;เริ่มจะไม่อยากยุ่งกับมันล่ะ &amp;nbsp;ก็เลยคิดว่าทำไมเราไม่เขียนเป็น library ไว้ใช้เลยล่ะ &amp;nbsp;โปรเจ็คหน้า &amp;nbsp;ก็เอาตัวนี้ไปใช้ได้เลย &amp;nbsp;ง่ายๆ &amp;nbsp;สะดวกดี&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ผมจึงตัดสินใจ &amp;nbsp;เขียน lib Excel Object Mapping สำหรับ Map Excel file ไปเป็น Java Object ให้อัตโนมัติครับ &amp;nbsp;โดยเราแค่ตั้งชื่อ excel แถวแรก &amp;nbsp;ให้ตรงตามชื่อ column ใน java class ที่เราต้องการให้ map ไป &amp;nbsp;แค่นี้มันก็ map ให้แล้วครับ&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/jittagornp/excel-object-mapping&quot;&gt;https://github.com/jittagornp/excel-object-mapping&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
อนาคต ผมอาจเพิ่มการ validate ข้อมูลที่ซับซ้อนขึ้นไปอีก &amp;nbsp;เพื่อให้ตอบโจทย์กับสิ่งที่เรากำลังทำอยู่ :)&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/8826191486323023195/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2015/01/excel-object-mapping.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/8826191486323023195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/8826191486323023195'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2015/01/excel-object-mapping.html' title='Excel Object Mapping'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-6823018798701155158</id><published>2014-11-24T04:46:00.000-08:00</published><updated>2014-11-24T22:52:05.903-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="primefaces"/><title type='text'>Primefaces SelectOneRadio change disabled</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN3VgcQfwNGGezOhF80Pcf0fQBqgnVEKAH5raIZPEiH8VU4ZG5O6SPOwVjUk4jW5TKagcTAp7PM604XlHeWUqfgMFlPi1JizsirQipyVs1bX4DLRqi_V2s8sUq1y5xzuixaXAV9cJpHRON/s1600/11-24-2014+7-55-03+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN3VgcQfwNGGezOhF80Pcf0fQBqgnVEKAH5raIZPEiH8VU4ZG5O6SPOwVjUk4jW5TKagcTAp7PM604XlHeWUqfgMFlPi1JizsirQipyVs1bX4DLRqi_V2s8sUq1y5xzuixaXAV9cJpHRON/s1600/11-24-2014+7-55-03+PM.png&quot; height=&quot;98&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPlTMztTdnZWLOcut7Z_8LXggpM-mqZQ4qnWlR1cycA5y7PLzsdEa0A92VAevzhq3IfJ1jGkh56fChMaqP3cSX5_0IV9sjMlf4tXgJ6D223r-TNbzM37a57KjP-wScwoPajua6o0ChqQPM/s1600/11-24-2014+7-54-50+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPlTMztTdnZWLOcut7Z_8LXggpM-mqZQ4qnWlR1cycA5y7PLzsdEa0A92VAevzhq3IfJ1jGkh56fChMaqP3cSX5_0IV9sjMlf4tXgJ6D223r-TNbzM37a57KjP-wScwoPajua6o0ChqQPM/s1600/11-24-2014+7-54-50+PM.png&quot; height=&quot;102&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;js
&lt;br /&gt;
&lt;pre class=&quot;brush : js&quot;&gt;/**
 * @author redcrow
 * create 24/11/2014
 * link http://na5cent.blogspot.com/2014/11/primefaces-selectoneradio-change.html
 */
(function($) {
    $(function() {
        $(&#39;[class*=change-disabled]&#39;).each(function() {
            var $redioChecked = $(this);
            var classes = $redioChecked.attr(&#39;class&#39;).split(&#39; &#39;);
            for (var i = 0; i &amp;lt; classes.length; i++) {
                if (/^(change\-disabled)/.test(classes[i])) {
                    done(
                        $redioChecked.find(&#39;input[type=radio]&#39;),
                        replace(classes[i], /.*\:(.*?)\(.*/),
                        replace(classes[i], /.*\((.*?)\).*/)
                    );
                }
            }
        });

        function replace(str, regEx){
            return str.replace(regEx, function() {
                return arguments[1];
            });
        }

        function disabledChecked(checked, $el) {
            if (checked) {
                $el.addClass(&#39;disabled-item&#39;);
            } else {
                $el.removeClass(&#39;disabled-item&#39;);
            }
        }

        function isDisabled($radioValue, disableValue) {
            var values = disableValue.split(&#39;,&#39;);
            for (var i = 0; i &amp;lt; values.length; i++) {
                if ($.trim($radioValue) === $.trim(values[i])) {
                    return true;
                }
            }

            return false;
        }

        function done($oneRadio, disableValue, classes) {
            var clazz = classes.split(&#39;,&#39;);
            for (var i = 0; i &amp;lt; clazz.length; i++) {
                var $el = $($.trim(clazz[i]));
                disabledChecked(isDisabled(
                        $oneRadio.filter(&#39;:checked&#39;).val(),
                        disableValue
                    ), $el
                );
        
                $oneRadio.on(&#39;change&#39;, function() {
                    disabledChecked(isDisabled(
                            $(this).val(),
                            disableValue
                        ), $el
                    );
                });
            }
        }
    });
})(jQuery);
&lt;/pre&gt;
css
&lt;br /&gt;
&lt;pre class=&quot;brush : css&quot;&gt;.disabled-item{
    position : relative;
    opacity: .30;
    filter: alpha(opacity=30);
}
.disabled-item::after { 
    content: &#39;&#39;; 
    display: inline-block; 
    position: absolute; 
    top: 0; 
    left: 0; 
    right: 0; 
    bottom: 0; 
    pointer-events: all; 
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;ตัวอย่างการใช้งาน&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
xhtml&lt;br /&gt;
&lt;i&gt;กำหนด style class เป็น&amp;nbsp;&lt;span style=&quot;color: #3d85c6;&quot;&gt; change-disabled:true(.clinic-a)&lt;/span&gt;&lt;/i&gt; : disabled target element (.clinic-a) เมื่อค่าตรงตามที่ตั้งไว้ (true) สามารถใส่เป็น multiple value ได้&lt;br /&gt;
&lt;pre class=&quot;brush : xml&quot;&gt;&amp;lt;span&amp;gt;
    &amp;lt;p:selectOneRadio value=&quot;#{auditFormCtrl.auditForm.audit.clinicA}&quot;
                      styleClass=&quot;change-disabled:true(.clinic-a)&quot;&amp;gt;
        &amp;lt;f:selectItem itemValue=&quot;true&quot; itemLabel=&quot;Yes&quot;/&amp;gt;
        &amp;lt;f:selectItem itemValue=&quot;false&quot; itemLabel=&quot;No&quot;/&amp;gt;
    &amp;lt;/p:selectOneRadio&amp;gt;
&amp;lt;/span&amp;gt;
&amp;lt;span class=&quot;clinic-a&quot;&amp;gt;
    วันเดือนปีที่ผู้ป่วยเริ่มมีไข้
    &amp;lt;p:spacer width=&quot;10&quot;/&amp;gt;
    &amp;lt;p:inputText value=&quot;#{auditFormCtrl.auditForm.audit.clinicADate}&quot;
                 styleClass=&quot;ic-calendar&quot;&amp;gt;
        &amp;lt;f:convertDateTime pattern=&quot;dd/MM/yyyy&quot;/&amp;gt;
    &amp;lt;/p:inputText&amp;gt;
&amp;lt;/span&amp;gt;
&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/6823018798701155158/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2014/11/primefaces-selectoneradio-change.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/6823018798701155158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/6823018798701155158'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2014/11/primefaces-selectoneradio-change.html' title='Primefaces SelectOneRadio change disabled'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN3VgcQfwNGGezOhF80Pcf0fQBqgnVEKAH5raIZPEiH8VU4ZG5O6SPOwVjUk4jW5TKagcTAp7PM604XlHeWUqfgMFlPi1JizsirQipyVs1bX4DLRqi_V2s8sUq1y5xzuixaXAV9cJpHRON/s72-c/11-24-2014+7-55-03+PM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-2420670031810180465</id><published>2014-11-22T11:20:00.000-08:00</published><updated>2014-11-22T19:03:14.089-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="glassfish server"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>แก้ปัญหา time zone ด้วยการ set JVM Time Zone : java</title><content type='html'>&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;ปัญหา&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; เนื่องจากผมทำการพัฒนา java web application และได้ทำการเช่า cloud server (VPS : Virtual Private Server) อยู่ที่ต่างประเทศ &amp;nbsp;ปัญหาที่เจอคือเรื่องของเวลา &amp;nbsp;ที่ไม่ตรงกัน &amp;nbsp;ระหว่าง client (browser) และ server &amp;nbsp;ทำให้การบันทึกข้อมูลลง database มีความผิดเพี้ยนไปจากความเป็นจริง&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;วิธีแก้&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ผมลอง search หาข้อมูลเพื่อแก้ไขปัญหาดังกล่าว &amp;nbsp;มีคนนึงแนะนำว่า &amp;nbsp;ลอง set time zone ให้ JVM ดู น่าจะแก้ได้ &amp;nbsp;ผมเลยลองทำตาม &amp;nbsp;ปรากฎว่าได้จริงๆ ครับ &amp;nbsp;ซึ่ง set ค่าให้ JVM ดังนี้&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;i&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt;-Duser.timezone=Asia/Bangkok&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;
&lt;br /&gt;
พอดีผมใช้ Glassfish Web Application Server &amp;nbsp;การ set ค่าเลยค่อนข้างง่าย เพราะมัน set ที่ GUI ได้เลย&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzjVREwbdNfydsU1vPlkSVNk3QS7egOJSl6wMgylpLD-jblE9CzDeThEMFiCQ_eF41mBb8p0QFX4yzbCeL4feh8LH6Osl_iuhCCiItiECklaJTqiUvltdFjl8SGoZaGdas0AQ4bFSV58dH/s1600/11-23-2014+2-14-31+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzjVREwbdNfydsU1vPlkSVNk3QS7egOJSl6wMgylpLD-jblE9CzDeThEMFiCQ_eF41mBb8p0QFX4yzbCeL4feh8LH6Osl_iuhCCiItiECklaJTqiUvltdFjl8SGoZaGdas0AQ4bFSV58dH/s1600/11-23-2014+2-14-31+AM.png&quot; height=&quot;532&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;คำถาม&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; แล้วเราจะรู้ได้ยังไง ว่าเราจะเอาค่า time zone id มาจากไหน&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;คำตอบ&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; วิธีการของผมคือนี่เลยครับ&lt;/div&gt;
&lt;pre class=&quot;brush : java&quot;&gt;for(String tz : TimeZone.getAvailableIDs()){
    LOG.debug(&quot;time zone --&amp;gt; {}&quot;, tz);
}
&lt;/pre&gt;
แค่นี้เราก็ได้ค่า time zone id ทั้งหมดมาแล้วครับ  ซึ่งก็ขึ้นอยู่กับว่า &amp;nbsp;เราจะ set time zone เป็นของอะไร&lt;br /&gt;
ในที่นี้ผมเลือกเป็น&amp;nbsp;&lt;i&gt;Asia/Bangkok&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
thank you :&amp;nbsp;&lt;a href=&quot;http://stackoverflow.com/questions/2493749/how-to-set-a-jvm-timezone-properly&quot;&gt;http://stackoverflow.com/questions/2493749/how-to-set-a-jvm-timezone-properly&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/2420670031810180465/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2014/11/time-zone-set-jvm-time-zone-java.html#comment-form' title='1 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/2420670031810180465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/2420670031810180465'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2014/11/time-zone-set-jvm-time-zone-java.html' title='แก้ปัญหา time zone ด้วยการ set JVM Time Zone : java'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzjVREwbdNfydsU1vPlkSVNk3QS7egOJSl6wMgylpLD-jblE9CzDeThEMFiCQ_eF41mBb8p0QFX4yzbCeL4feh8LH6Osl_iuhCCiItiECklaJTqiUvltdFjl8SGoZaGdas0AQ4bFSV58dH/s72-c/11-23-2014+2-14-31+AM.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-4709817923319397747</id><published>2014-11-21T01:18:00.002-08:00</published><updated>2014-11-21T08:29:27.804-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><title type='text'>BottomScrollFixer : javascript</title><content type='html'>&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVAEUCwrCNhljaLllymhzBtvoO78mMuBHKB64RNiPpHzpcq4ye8tVxRTBtYIbl8nCxfuk2OV_f40btfWG6jn6PKWlaD34unkeQQxpaJ9Bpcj4KghFGty7kawtNal9XPOfj82UHPYEzIYQv/s1600/11-19-2014+5-21-10+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVAEUCwrCNhljaLllymhzBtvoO78mMuBHKB64RNiPpHzpcq4ye8tVxRTBtYIbl8nCxfuk2OV_f40btfWG6jn6PKWlaD34unkeQQxpaJ9Bpcj4KghFGty7kawtNal9XPOfj82UHPYEzIYQv/s1600/11-19-2014+5-21-10+PM.png&quot; height=&quot;640&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; บางที element ของเรา อาจจะยาวมากๆ &amp;nbsp;จนล้นหน้าจอ (window) แล้ว element นั้น &amp;nbsp;ก็เกิด bottom overflow (&lt;i&gt;overflow-x&lt;/i&gt; เป็น &lt;i&gt;scroll&lt;/i&gt; หรือ &lt;i&gt;auto&lt;/i&gt;) ด้วย&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;ปัญหา&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ปัญหาที่เจอก็คือ &amp;nbsp;เราต้องเลื่อน scroll ของ window ลงมาข้างล่างสุดของ element นั้นก่อน &amp;nbsp;เราถึงจะสามารถเลื่อน scroll X ของ element นั้นได้ (เพราะ element มันล้นจอ)&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;วิธีแก้&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ผมเลยทำการเขียน javascript ขึ้นมาเพื่อแก้ปัญหานี้ &amp;nbsp;โดยให้มันทำการคำนวนและ fixed bottom scroll ให้โดยอัตโนมัติ &amp;nbsp;โดยที่เราไม่ต้องเลื่อน window scroll ลงไปข้างล่าง &amp;nbsp;มันจะ fixed ให้ทันทีที่เราเลื่อน scroll ไปถึง element นั้นตามขนาดที่เราได้ fixed ไว้ &amp;nbsp;(&lt;i&gt;withFixedHeight&lt;/i&gt;) โดยไม่จำเป็นต้องเลือนลงไปยังข้างล่างสุดของ element bottom scroll จะเลื่อนตามเราไปเรื่อยๆ &amp;nbsp;จนกว่าจะพ้น element นั้นๆ&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyeqNlua3da6B9BssmJ8_1r1-6DC-1EPWQ4Epx6YBjPQ0bOEht4d2Sp6x-fzvMrlf2dnrF9KTw67cnqSqzqG1NyQEYpxYEqKKntLFWM7-9oEn29oBhYTgReknJ0RBnlUkw7lMediyKp64t/s1600/11-21-2014+4-21-43+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyeqNlua3da6B9BssmJ8_1r1-6DC-1EPWQ4Epx6YBjPQ0bOEht4d2Sp6x-fzvMrlf2dnrF9KTw67cnqSqzqG1NyQEYpxYEqKKntLFWM7-9oEn29oBhYTgReknJ0RBnlUkw7lMediyKp64t/s1600/11-21-2014+4-21-43+PM.png&quot; height=&quot;398&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
BottomScrollFixer.js
&lt;br /&gt;
&lt;pre class=&quot;brush : js&quot;&gt;/**
 * @author redcrow
 * create 21/11/2014
 * link http://na5cent.blogspot.com/2014/11/bottomscrollfixer.html
 * 
 * require jQuery
 */
window.BottomScrollFixer = window.BottomScrollFixer || (function($, win) {

    var $win = $(win);

    var Fixer = function(selector) {
        this.$content = $(selector);
        this.contentHeight = this.$content.height();
        this.error = 0;
        this.fixedHeight = 200;
        this.overflowY = this.$content.css(&#39;overflow-y&#39;);
    };

    Fixer.prototype.withError = function(err) {
        this.error = err;
        return this;
    };

    Fixer.prototype.withFixedHeight = function(height) {
        this.fixedHeight = height;
        return this;
    };

    Fixer.prototype.listen = function() {
        var top = this.$content.offset().top;
        var bottom = this.contentHeight + top;
        var scrollTop = $win.scrollTop();
        var contentTop = $win.height() - this.error;
        var scroll = scrollTop + contentTop;

        var fixed = ((scroll - this.fixedHeight) &amp;gt; top) &amp;amp;&amp;amp; (scroll &amp;lt; bottom);
        this.$content.css(fixed ? {
            &#39;height&#39;: scroll - top,
            &#39;overflow-y&#39;: &#39;hidden&#39;
        } : {
            &#39;height&#39;: &#39;auto&#39;,
            &#39;overflow-y&#39;: this.overflowY
        });

        return this;
    };

    Fixer.fixedElement = function(selector) {
        return new Fixer(selector);
    };

    return Fixer;

})(jQuery, window);
&lt;/pre&gt;
&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;ตัวอย่าง
&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
html
&lt;br /&gt;
&lt;pre class=&quot;brush : xml&quot;&gt;&amp;lt;div id=&quot;myEelementFixer&quot;&amp;gt;
   &amp;lt;div&amp;gt;
       Element นี้ สูง 2,000px และกว้าง 2,000px &amp;lt;br /&amp;gt;
       เมื่อ เลื่อน scroll ไปเท่ากับ 200px (withFixedHeight(200))&amp;lt;br /&amp;gt; 
       มันจะเกิด auto fixed bottom scroll ให้&amp;lt;br /&amp;gt;
       ในกรณีที่มันไม่เกิด auto fixed scroll ลองค่อยๆ เพิ่มค่า withError(error) ดูครับ 
   &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
js
&amp;lt;style&amp;gt;
    #myEelementFixer {
        overflow: auto;
    }
 
    #myEelementFixer &amp;gt; div {
        font-size : 12pt; 
        font-weight : bold;
        padding: 20px; 
        background-color: #fafafa; 
        height: 2000px; 
        width: 2000px;
    }
&amp;lt;/style&amp;gt;
&lt;/pre&gt;
&lt;pre class=&quot;brush : js&quot;&gt;(function($, win, BottomScrollFixer) {
    $(function() {
        var $win = $(win);

        var fixer = BottomScrollFixer
                .fixedElement(&#39;#myEelementFixer&#39;)
                .withFixedHeight(200)
                .listen();

        $win.scroll(function() {
            fixer.listen();
        }).resize(function() {
            fixer.listen();
        });
    });
})(jQuery, window, BottomScrollFixer);
&lt;/pre&gt;
(สังเกต bottom scroll จะเลื่อนตาม)&lt;br /&gt;
&lt;br /&gt;
&lt;div id=&quot;myEelementFixer&quot;&gt;
&lt;div&gt;
Element นี้ สูง 2,000px และกว้าง 2,000px &lt;br /&gt;
เมื่อ เลื่อน scroll ไปเท่ากับ 200px (withFixedHeight(200))&lt;br /&gt;
มันจะเกิด auto fixed bottom scroll ให้&lt;br /&gt;
ในกรณีที่มันไม่เกิด auto fixed scroll ลองค่อยๆ เพิ่มค่า withError(error) ดูครับ 
 &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
    #myEelementFixer {
     overflow: auto;
 }
 
 #myEelementFixer &gt; div {
     font-size : 12pt; 
  font-weight : bold;
  padding: 20px; 
  background-color: #fafafa; 
  height: 2000px; 
  width: 2000px;
 }

  body{
        overflow-x : hidden;
   }
&lt;/style&gt;
&lt;script&gt;
/**
 * @author jittagorn pitakmetagoon
 * create 21/11/2014
 */
window.BottomScrollFixer = window.BottomScrollFixer || (function($, win) {

    var Fixer = function(selector) {
        this.$content = $(selector);
        this.contentHeight = this.$content.height();
        this.error = 0;
        this.fixedHeight = 200;
        this.overflowY = this.$content.css(&#39;overflow-y&#39;);
    };

    Fixer.prototype.withError = function(err) {
        this.error = err;
        return this;
    };

    Fixer.prototype.withFixedHeight = function(height) {
        this.fixedHeight = height;
        return this;
    };

    Fixer.prototype.listen = function() {
        var $win = $(win);
        var top = this.$content.offset().top;
        var bottom = this.contentHeight + top;
        var scrollTop = $win.scrollTop();
        var contentHeight = $win.height() - this.error;
        var scroll = scrollTop + contentHeight;

        if (((scroll - this.fixedHeight) &gt; top) &amp;&amp; (scroll &lt; bottom)) {
            this.$content.css({
                &#39;height&#39;: scroll - top,
                &#39;overflow-y&#39;: &#39;hidden&#39;
            });
        } else {
            this.$content.css({
                &#39;height&#39;: &#39;auto&#39;,
                &#39;overflow-y&#39;: this.overflowY
            });
        }
    };

    Fixer.fixedElement = function(selector) {
        return new Fixer(selector);
    };

    return Fixer;

})(jQuery, window);
&lt;/script&gt;
&lt;script&gt;
(function($, win, BottomScrollFixer) {
    $(function() {
        var $win = $(win);

        var fixer = BottomScrollFixer
                .fixedElement(&#39;#myEelementFixer&#39;)
                .withFixedHeight(200);

        fixer.listen();
        $win.scroll(function() {
            fixer.listen();
        }).resize(function() {
            fixer.listen();
        });
    });
})(jQuery, window, BottomScrollFixer);
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/4709817923319397747/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2014/11/bottomscrollfixer.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/4709817923319397747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/4709817923319397747'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2014/11/bottomscrollfixer.html' title='BottomScrollFixer : javascript'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVAEUCwrCNhljaLllymhzBtvoO78mMuBHKB64RNiPpHzpcq4ye8tVxRTBtYIbl8nCxfuk2OV_f40btfWG6jn6PKWlaD34unkeQQxpaJ9Bpcj4KghFGty7kawtNal9XPOfj82UHPYEzIYQv/s72-c/11-19-2014+5-21-10+PM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-288028684189495051</id><published>2014-11-12T22:41:00.002-08:00</published><updated>2014-11-17T17:33:27.676-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="oracle sql"/><title type='text'>age computation oracle sql </title><content type='html'>code
&lt;br /&gt;
&lt;pre class=&quot;brush : sql&quot;&gt;select trunc(months_between(sysdate,dob)/12) year,
    trunc(mod(months_between(sysdate,dob),12)) month,
    trunc(sysdate-add_months(dob,trunc(months_between(sysdate,dob)/12)*12+trunc(mod(months_between(sysdate,dob),12)))) day
from (
    Select to_date(&#39;15122000&#39;,&#39;DDMMYYYY&#39;) dob 
    from dual
);
&lt;/pre&gt;
output&lt;br /&gt;
year &amp;nbsp; &amp;nbsp; &amp;nbsp;month &amp;nbsp; &amp;nbsp; &amp;nbsp;day&lt;br /&gt;
13 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;10 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 29
</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/288028684189495051/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2014/11/age-computation-oracle-sql.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/288028684189495051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/288028684189495051'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2014/11/age-computation-oracle-sql.html' title='age computation oracle sql '/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-3508396437202560420</id><published>2014-10-22T10:15:00.003-07:00</published><updated>2015-01-12T03:49:13.821-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="linux command"/><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu server"/><title type='text'>เขียน Service Glassfish Server บน Linux Ubuntu</title><content type='html'>&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; server นี้ผมได้ทำการ set GLASSFISH_HOME ไว้ใน $PATH ของ file ~/.bashrc แล้วน่ะครับ &amp;nbsp;จึงทำให้สามารถเรียก asadmin ได้เลย &amp;nbsp;โดยไม่ต้องใช้ path เต็มครับ&lt;br /&gt;
&lt;br /&gt;
1. ไปที่ /etc/init.d/ ด้วยคำสั่ง
&lt;br /&gt;
&lt;pre class=&quot;brush : shell&quot;&gt;$ cd /etc/init.d/
&lt;/pre&gt;
2. สร้าง file service glassfish ด้วยคำสั่ง
&lt;br /&gt;
&lt;pre class=&quot;brush : shell&quot;&gt;$ sudo vi glassfish
&lt;/pre&gt;
3. เขียนชุดคำสั่ง&lt;br /&gt;
&lt;pre class=&quot;brush : shell&quot;&gt;#!/bin/sh
#

# define service function
start(){
    asadmin start-domain &amp;gt;/dev/null  
}

stop(){
    asadmin stop-domain &amp;gt;/dev/null  
}

restart(){
    asadmin restart-domain &amp;gt;/dev/null  
}

#detect service argument
case &quot;$1&quot; in
    start)
        start
    ;;
    stop)
        stop
    ;;
    restart)
        restart
    ;;
*)

echo $&quot;Usage: $0 {start|stop|restart}&quot;
exit 1
esac

exit 0
&lt;/pre&gt;
4. สั่งงาน
&lt;br /&gt;
&lt;pre class=&quot;brush : shell&quot;&gt;$ service glassfish start
&lt;/pre&gt;
หรือ
&lt;br /&gt;
&lt;pre class=&quot;brush : shell&quot;&gt;$ /etc/init.d/glassfish start
&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/3508396437202560420/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2014/10/service-glassfish-server-linux-ubuntu.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/3508396437202560420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/3508396437202560420'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2014/10/service-glassfish-server-linux-ubuntu.html' title='เขียน Service Glassfish Server บน Linux Ubuntu'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-7132486196784053981</id><published>2014-10-22T02:10:00.002-07:00</published><updated>2014-10-22T02:11:54.325-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Mysql Connection utf8</title><content type='html'>ให้เพิ่ม &lt;i&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt;useUnicode=true&amp;amp;characterEncoding=UTF-8&lt;/span&gt;&lt;/i&gt; ต่อท้าย connection&lt;br /&gt;
&lt;pre class=&quot;brush : java&quot;&gt;URL= jdbc:mysql://127.0.0.1:3306/mydatabase?useUnicode=true&amp;amp;characterEncoding=UTF-8
&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/7132486196784053981/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2014/10/mysql-connection-utf8.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/7132486196784053981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/7132486196784053981'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2014/10/mysql-connection-utf8.html' title='Mysql Connection utf8'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-5826425670997647399</id><published>2014-10-21T22:01:00.001-07:00</published><updated>2014-10-21T22:01:05.065-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>concept การเขียนและการวาง architecture java web application ของผม</title><content type='html'>กำลังเขียน...</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/5826425670997647399/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2014/10/concept-architecture-java-web.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/5826425670997647399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/5826425670997647399'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2014/10/concept-architecture-java-web.html' title='concept การเขียนและการวาง architecture java web application ของผม'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-1160554572312053294</id><published>2014-09-29T09:27:00.002-07:00</published><updated>2020-01-17T09:22:19.069-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>WeakHashMap ใน java</title><content type='html'>ย้ายไปไว้ที่&amp;nbsp;&lt;a href=&quot;https://www.jittagornp.me/blog/java-weakhashmap/&quot;&gt;https://www.jittagornp.me/blog/java-weakhashmap/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/1160554572312053294/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2014/09/weakhashmap-java.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/1160554572312053294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/1160554572312053294'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2014/09/weakhashmap-java.html' title='WeakHashMap ใน java'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-7592104237366567384</id><published>2014-09-28T10:11:00.003-07:00</published><updated>2014-09-30T23:07:13.812-07:00</updated><title type='text'>jsf controller view scope ใน spring component  : java</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf9EysrsZTK-RNe8KDRrygmBP_IwVz7dqpDvTFFNVxIy95K5rMf1-I6NQun7pRxYAyzXKgbafrnhyMuSC_3kLP70bqE5VoEz7St8AdzG1B9wZbZZl9JzylV94B1lkGEAMriduSGG9Z9nnI/s1600/view_through_scope_I.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf9EysrsZTK-RNe8KDRrygmBP_IwVz7dqpDvTFFNVxIy95K5rMf1-I6NQun7pRxYAyzXKgbafrnhyMuSC_3kLP70bqE5VoEz7St8AdzG1B9wZbZZl9JzylV94B1lkGEAMriduSGG9Z9nnI/s1600/view_through_scope_I.jpg&quot; height=&quot;300&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;เท้าความ&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ในการเขียน Managed bean หรือ Controller ของ JSF (JavaServer Faces) นั้น จะต้องใช้ &amp;nbsp;annotation &amp;nbsp;@ManagedBean และ annotation Scoped ของ faces อย่างใดอย่างหนึ่งกำหนดไว้เสมอ ได้แก่&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt;@ApplicationScoped&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt;@SessionScoped&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt;@ViewScoped&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt;@RequestScoped&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
ซึ่งเป็นตัวที่บ่งบอกวงจรชีวิตของ managed bean นั้นๆ &amp;nbsp;ว่าจะมีชีวิตอยู่ได้นานเท่าใด&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ต่อมา ผมต้องการเปลี่ยน managed bean ของ jsf ทั้งหมดที่ใช้ @ManagedBean ไปใช้&amp;nbsp;@Component ของ SpringFramework จากที่แต่ก่อน instance ของ managed bean ถูกสร้างขึ้นโดย jsf engine ก็ delegate ไปให้เป็นหน้าที่ของ spring เป็นคนสร้างให้แทน &amp;nbsp;เนื่องจากต้องการให้สามารถ inject service และ component ต่างๆ &amp;nbsp;ได้ง่ายขึ้น เพราะเป็น spring ด้วยกัน&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;ปัญหา&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ปัญหาที่ผมเจอคือ การสร้าง controller ที่เป็น jsf ของ spring จะต้องควบคู่กับ annotation @Scope &amp;nbsp;ซึ่งมี scope ไม่ครบตาม scope เดิมของ jsf &amp;nbsp;คือยังขาด scope ที่เป็น view แล้วเราจะทำยังไงล่ะ &amp;nbsp;เพราะส่วนใหญ่แล้วเราต้องการ scope ที่เป็น view ซ่ะด้วย?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;u&gt;คำตอบ&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ก็สร้างมันขึ้นมาซ่ะสิ&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;วิธีการ&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
1. สร้าง scope ที่เป็น view ของ jsf ให้&amp;nbsp;@Scope&lt;br /&gt;
ในที่นี้ &amp;nbsp;เราจะ custom view scope ขึ้นมาเอง &amp;nbsp;โดยผนวกมันเข้ากับ FacesContext&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush : java&quot;&gt;package com.blogspot.na5cent.spring;

import java.util.Map;

import javax.faces.context.FacesContext;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;

/**
 * @author redcrow
 */
public class ViewScope implements Scope {

    private Map&amp;lt;String, Object&amp;gt; getViewMap() {
        return FacesContext.getCurrentInstance()
                .getViewRoot()
                .getViewMap();
    }

    @Override
    public Object get(String name, ObjectFactory objectFactory) {
        Map&amp;lt;String, Object&amp;gt; viewMap = getViewMap();

        if (viewMap.containsKey(name)) {
            return viewMap.get(name);
        } else {
            Object object = objectFactory.getObject();
            viewMap.put(name, object);

            return object;
        }
    }

    @Override
    public Object remove(String name) {
        return getViewMap().remove(name);
    }

    @Override
    public String getConversationId() {
        return null;
    }

    @Override
    public void registerDestructionCallback(String name, Runnable callback) {
        //Not supported
    }

    @Override
    public Object resolveContextualObject(String key) {
        return null;
    }
}
&lt;/pre&gt;
2. ที่ file applicationContext.xml (ของ spring framework) ให้ add scope เข้าไปใน component
&lt;br /&gt;
&lt;pre class=&quot;brush : xml&quot;&gt;...
...
...
    &amp;lt;bean class=&quot;org.springframework.beans.factory.config.CustomScopeConfigurer&quot;&amp;gt;
        &amp;lt;property name=&quot;scopes&quot;&amp;gt;
            &amp;lt;map&amp;gt;
                &amp;lt;entry key=&quot;view&quot;&amp;gt;
                    &amp;lt;bean class=&quot;com.blogspot.na5cent.spring.ViewScope&quot;/&amp;gt; &amp;lt;!-- ***** --&amp;gt;
                &amp;lt;/entry&amp;gt;
            &amp;lt;/map&amp;gt;
        &amp;lt;/property&amp;gt;
    &amp;lt;/bean&amp;gt;
...
...
...
&lt;/pre&gt;
3. ใช้งาน
&lt;br /&gt;
&lt;pre class=&quot;brush : java&quot;&gt;...
...
...
@Component
@Scope(&quot;view&quot;) //*****
public class TopicIncomeCtrl {

    private static final Logger LOG = LoggerFactory.getLogger(TopicIncomeCtrl.class);
    @Autowired
    private TopicIncomeService service;
    private TopicIncomeLazy lazy;
    private TopicIncome topic;

    @PostConstruct
    public void postContruct() {
        lazy = new TopicIncomeLazy();
    }

    public TopicIncomeLazy getLazy() {
        return lazy;
    }

    public void onCreateTopic() {
        topic = new TopicIncome();
    }

    public TopicIncome getTopic() {
        return topic;
    }

    public void setTopic(TopicIncome topic) {
        this.topic = topic;
    }
    
    public void onAddTopic(){
        service.saveTopic(topic);
    }
}
&lt;/pre&gt;
ก่อนที่จะทำตรงนี้ได้  แนะนำให้อ่าน 2 บทความนี้ก่อนครับ&lt;br /&gt;
&lt;a href=&quot;http://na5cent.blogspot.com/2013/07/jsf-managedbean-can-autowire-spring.html&quot;&gt;http://na5cent.blogspot.com/2013/07/jsf-managedbean-can-autowire-spring.html&lt;/a&gt; &lt;a href=&quot;http://na5cent.blogspot.com/2013/09/spring-session-scope.html&quot;&gt;http://na5cent.blogspot.com/2013/09/spring-session-scope.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
ที่มาของภาพ&amp;nbsp;&lt;a href=&quot;http://www.coyotecanada.ca/view_through_scope_I.jpg&quot;&gt;http://www.coyotecanada.ca/view_through_scope_I.jpg&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/7592104237366567384/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2014/09/jsf-controller-view-scope-spring.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/7592104237366567384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/7592104237366567384'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2014/09/jsf-controller-view-scope-spring.html' title='jsf controller view scope ใน spring component  : java'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf9EysrsZTK-RNe8KDRrygmBP_IwVz7dqpDvTFFNVxIy95K5rMf1-I6NQun7pRxYAyzXKgbafrnhyMuSC_3kLP70bqE5VoEz7St8AdzG1B9wZbZZl9JzylV94B1lkGEAMriduSGG9Z9nnI/s72-c/view_through_scope_I.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3030476649588243638.post-7072357313124560521</id><published>2014-09-23T03:39:00.000-07:00</published><updated>2014-09-23T20:31:31.993-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>wrap http servlet response ด้วย HttpServletResponseWrapper</title><content type='html'>&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;ปัญหา&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; อันนี้เป็นปัญหาที่ผมเจอระหว่างการพัฒนาโปรเจ็คที่ใช้ spring mvc ครับ ซึ่ง view ผมเป็น jsp&lt;br /&gt;
ความต้องการของผมคือ ผมต้องการ parse jsp ไปเป็น html เอง (manual parse) เพราะผมต้องการ return ผลลัพธ์กลับไปเป็น json ซึ่งห่อหุ้ม html (jsp) อีกที &amp;nbsp;ก็เลยได้ลองหาข้อมูลใน google อยู่สักพัก &amp;nbsp;ปรากฏว่ามันไม่น่าจะทำได้ &lt;br /&gt;
&lt;br /&gt;
ทุกปัญหาย่อมมีทางออก!&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;มันก็มีทางออกอยู่ว่า &amp;nbsp;ถ้าอยาก parse template เอง &amp;nbsp;ก็ต้องเปลี่ยนไปเขียน code ที่เป็นพวก template engine แทน jsp เช่น themeleaf, freemarker หรือ velocity อันนี้ได้ชัวร์ 100% &amp;nbsp;แต่ผมไม่อยากเปลี่ยนนี่สิ &amp;nbsp;เพราะผมต้องการ feature บางอย่างของ jsp ที่มีมากกว่า template engine พวกนี้ &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; จนในที่สุด &amp;nbsp;ผมก็พบทางออก &amp;nbsp;ลืมไปเลย &amp;nbsp;ว่ามันมีวิธีนี้อยู่ manual parse ไม่ได้ไม่เป็นไร &amp;nbsp;งั้นห่อหุ่ม (wrap) ผลลัพธ์แทนแล้วกัน &amp;nbsp;ซึ่งเป็นที่มาของบทความนี้ครับ&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;วิธีการ&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPY3IsLN38eB0UhYRDS_Fqf_fzLUvRGiSdr8lxYT08wUmaivZH9ASPowW_KMNmuC_mipu77SHgNX6tOWQhHqXDuWfRsW5UdHpC4sGhViz4iGGf1xOyiYTivwOE7oS2rCoMuwJmUwpCw8_R/s1600/9-23-2014+5-53-11+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPY3IsLN38eB0UhYRDS_Fqf_fzLUvRGiSdr8lxYT08wUmaivZH9ASPowW_KMNmuC_mipu77SHgNX6tOWQhHqXDuWfRsW5UdHpC4sGhViz4iGGf1xOyiYTivwOE7oS2rCoMuwJmUwpCw8_R/s1600/9-23-2014+5-53-11+PM.png&quot; height=&quot;230&quot; style=&quot;border: none;&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ผมแก้ปัญหาการ manual parse ไปเป็นการห่อหุ้ม (wrap) ผลลัพธ์ที่ถูก parse แล้วแทน &amp;nbsp;สรุปก็ยังใช้ jsp เหมือนเดิม &amp;nbsp;แล้วให้ servlet engine parse jsp ให้จนได้ผลลัพธ์ที่เป็น html&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; เราค่อยเอา html นั้นมา wrap ด้วย json ตามที่เราต้องการครับ&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;คำถาม&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; แล้วเราจะ wrap มันยังไง?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;คำตอบ&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wrap ด้วย&amp;nbsp;HttpServletResponseWrapper ผ่าน filter นั่นเอง&lt;br /&gt;
&lt;br /&gt;
มาเขียนกันเลยดีกว่าครับ &amp;nbsp;ซึ่งมีแค่ 2 ขั้นตอนเท่านั้น&lt;br /&gt;
&lt;br /&gt;
1. สร้าง class ที่ extends HttpServletResponseWrapper &amp;nbsp;เพื่อ modify response ที่ถูกส่งกลับมา ให้เป็น String ด้วยการเปลี่ยน PrintWriter ของ HttpServletResponse เดิม &amp;nbsp;ไปเป็น CharArrayWritter (จริงๆ แล้วก็ไม่ได้เปลี่ยนหรอก &amp;nbsp;แค้่ให้ PrintWriter มันเขียนลง CharArrayWritter แทน)&lt;br /&gt;
&lt;br /&gt;
CharResponseWrapper.java
&lt;br /&gt;
&lt;pre class=&quot;brush : java&quot;&gt;package com.blogspot.na5cent.servlet;

import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
 * @author redcrow
 */
public class CharResponseWrapper extends HttpServletResponseWrapper {

    protected CharArrayWriter charWriter;

    protected PrintWriter writer;

    protected boolean getOutputStreamCalled;

    protected boolean getWriterCalled;

    public CharResponseWrapper(HttpServletResponse response) {
        super(response);
        
        charWriter = new CharArrayWriter();
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        if (getWriterCalled) {
            throw new IllegalStateException(&quot;getWriter already called&quot;);
        }

        getOutputStreamCalled = true;
        return super.getOutputStream();
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        if (writer != null) {
            return writer;
        }
        
        if (getOutputStreamCalled) {
            throw new IllegalStateException(&quot;getOutputStream already called&quot;);
        }
        
        getWriterCalled = true;
        writer = new PrintWriter(charWriter);
        return writer;
    }

    @Override
    public String toString() {
        String s = null;

        if (writer != null) {
            s = charWriter.toString();
        }
        
        return s;
    }
}
&lt;/pre&gt;
2. เขียน filter เพื่อเปลี่ยนและ wrap response ด้วย CharResponseWrapper จากข้อ 1 แล้ว manual json ก่อนส่งกลับไปให้ client (browser)&lt;br /&gt;
Jsp2JsonResponseWrapperFilter.java
&lt;br /&gt;
&lt;pre class=&quot;brush : java&quot;&gt;package com.blogspot.na5cent.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.blogspot.na5cent.servlet.CharResponseWrapper;
import com.google.gson.Gson;
import java.util.HashMap;
import java.util.Map;
import java.util.Date;

/**
 * @author redcrow
 */
@WebFilter(urlPatterns = &quot;/*&quot;)
public class Jsp2JsonResponseWrapperFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    private boolean isJsp2JsonRequest(HttpServletRequest request) {
        return request.getRequestURI().contains(&quot;/json/&quot;);
    }

    @Override
    public void doFilter(
            ServletRequest request,
            ServletResponse response,
            FilterChain chain
    ) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        if (!isJsp2JsonRequest(req)) {
            chain.doFilter(request, response);
            return;
        }

        ServletResponse newResponse = new CharResponseWrapper(resp); //*****
        chain.doFilter(request, newResponse);
        String html = newResponse.toString();

        if (html != null) {
            Map&amp;lt;String, Object&amp;gt; map = new HashMap&amp;lt;&amp;gt;();
            map.put(&quot;payload&quot;, html);
            map.put(&quot;timestamp&quot;, new Date().getTime());

            response.getWriter().write(new Gson().toJson(map));
            response.setContentType(&quot;application/json&quot;);
        }
    }

    @Override
    public void destroy() {

    }

}
&lt;/pre&gt;
ถ้า file .jsp เราเป็น
&lt;br /&gt;
&lt;pre class=&quot;brush : xml&quot;&gt;&amp;lt;%@page contentType=&quot;text/html&quot; pageEncoding=&quot;UTF-8&quot;%&amp;gt;

&amp;lt;h1&amp;gt;hello world&amp;lt;/h1&amp;gt;
&lt;/pre&gt;
ผลลัพธ์จะได้เป็น json ดังนี้
&lt;br /&gt;
&lt;pre class=&quot;brush : js&quot;&gt;{&quot;timestamp&quot;:1411477104056,&quot;payload&quot;:&quot;\u003ch1\u003ehello world\u003c/h1\u003e&quot;}
&lt;/pre&gt;
แค่นี้  ผมก็แก้ปัญหาที่ผมต้องการได้แล้วครับ&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;b&gt;เหตุผล&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; แน่นอนว่า ต้องมีคนสงสัยว่าทำไมผมต้องทำแบบนี้&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;u&gt;ตอบ&lt;/u&gt; : &amp;nbsp;เพราะผมต้องการ add additional data ลงไปใน response โดยไม่ให้ส่งผลกระทบต่อ html/jsp เดิมครับ &amp;nbsp;รูปแบบ json เป็นอะไรที่อ่านแล้วเข้าใจง่ายที่สุด และใช้ร่วมกับ javascript ได้ดีที่สุด &amp;nbsp;ผมมองถึงอนาคตที่ต้องมี additional data ต่างๆ อีกมากมาย &amp;nbsp;รวมทั้งต้องการทำให้ response ทุกอย่างที่เป็น ajax มีรูปแบบเป็น json แบบเดี่ยวกันทั้งหมด &amp;nbsp;เพื่อความง่ายในการ manage ครับ &lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://na5cent.blogspot.com/feeds/7072357313124560521/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://na5cent.blogspot.com/2014/09/wrap-http-servlet-response.html#comment-form' title='2 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/7072357313124560521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3030476649588243638/posts/default/7072357313124560521'/><link rel='alternate' type='text/html' href='http://na5cent.blogspot.com/2014/09/wrap-http-servlet-response.html' title='wrap http servlet response ด้วย HttpServletResponseWrapper'/><author><name>jittagornp</name><uri>http://www.blogger.com/profile/13814364224522529707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPY3IsLN38eB0UhYRDS_Fqf_fzLUvRGiSdr8lxYT08wUmaivZH9ASPowW_KMNmuC_mipu77SHgNX6tOWQhHqXDuWfRsW5UdHpC4sGhViz4iGGf1xOyiYTivwOE7oS2rCoMuwJmUwpCw8_R/s72-c/9-23-2014+5-53-11+PM.png" height="72" width="72"/><thr:total>2</thr:total></entry></feed>