วันอังคารที่ 30 กรกฎาคม พ.ศ. 2562
ตัวอย่างการเขียน Java Spring-boot Reactive (WebFlux)
ผมได้ทำตัวอย่างการเขียน Java Spring-boot WebFlux ซึ่งเป็นการเขียน Spring-boot แบบ Non-Blocking I/O หรือ Asynchronous หากใครสนใจสามารถเข้าไปศึกษาได้ที่
https://github.com/jittagornp/spring-boot-webflux-example
วันพุธที่ 12 มิถุนายน พ.ศ. 2562
ถึงคนอ่าน Blog และผู้ติดตามทุกคนน่ะครับ
Blog นี้ผมไม่ได้เขียนมาซักระยะนึงแล้ว
จริง ๆ ต้องเรียกว่านานมาก ๆ เลยแหล่ะ (เกือบ 4 ปีได้ ฮ่าๆๆๆ)
ตอนนี้ผมย้ายไปเขียนบน platform อื่น ๆ
หลัง ๆ มาก็มี เขียนบ้าง ไม่ได้เขียนบ้าง
เพราะมีหน้าที่รับผิดชอบที่เยอะขึ้น เลยไม่ค่อยได้มีเวลาเขียน Blog ครับ
บวกกับตอนนี้มีความสนใจ เรื่องใดเรื่องนึงเป็นพิเศษ เลยไม่ได้มีเวลามาทำตรงนี้
ถ้าผู้อ่าน เพื่อน ๆ พี่ ๆ น้อง ๆ คนไหนยังอยากติดตามอยู่ สามารถติดตามได้ตาม link นี้ครับ
ขอบคุณครับ
วันจันทร์ที่ 25 พฤษภาคม พ.ศ. 2558
maven ทำ jar file ให้ double click run program ได้ : java
วันอาทิตย์ที่ 24 พฤษภาคม พ.ศ. 2558
ฝึก recursive ด้วยโจทย์ความน่าจะเป็น
ครับ!!! ผมเคยได้ยินประโยคแบบนี้มานักต่อนักล่ะ บางคนบอกว่าผมไม่รู้จักใช้เครื่องมือให้เกิดประโยชน์
คุณกำลังเข้าใจผิดกับคำว่า "การเลือกใช้เครื่องมือ" กับ "การฝึกทักษะการแก้ปัญหา"
ที่ผมเขียนเอง เพราะผมต้องการฝึก skill เพื่อให้เกิดความคล่องตัว เมื่อเราเจอโจทย์ปัญหาลักษณะนี้ เราจะแก้มันได้รึเปล่า ลองใช้ความคิดของเราดูสิ
skill มันส่งต่อผ่านประสบการณ์กันไม่ได้ ต่อให้มีคนพยายามเล่าประสบการณ์ทั้งชีวิตของเขาให้คุณฟัง คุณก็ทำแบบเขาไม่ได้ คุณต้องฝึก ฝึก ฝึก ลงมือทำด้วยตัวคุณเองครับ
ปัญหา
โดยทั่วไป การหาความน่าจะเป็นหรือความเป็นไปได้ของสมาชิกทั้งหมดภายในเซต S ซึ่งมีสมาชิกจำนวน n ตัว
คุณจะต้องวนลูปทั้งหมด n รอบ และลึก n ชั้น ถึงจะได้ค่าทั้งหมดออกมา เช่น
S = {'A', 'B', 'C'}
n = 3 ตัว
จำนวนความเป็นไปได้ทั้งหมดคือ 3 x 3 x 3 = 27 ค่า
การเขียนโปรแกรมแบบง่ายๆ จะได้
for (var i = 0; i < S.lenght; i++){
for (var j = 0; j < S.lenght; j++){
for (var k = 0; k < S.lenght; k++){
print(S[i] + ',' + S[j] + ',' + 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
แล้วถ้าเขาต้องการให้คุณเขียน code ที่รองรับ S ที่มี size ขนาดใดก็ได้ คุณจะเขียนยังไง?แน่นอน loop ใช้ไม่ได้ล่ะ เพราะมัน fixed ตายตัว
แล้วอะไรที่เราเอามาใช้แทน loop ได้ แถมยังเป็นแบบ dynamic อีก
คำตอบคือ Recursive ครับ
วันเสาร์ที่ 18 เมษายน พ.ศ. 2558
angularjs enumeration : javascript
Enum Factory
var mapApp = ...
myApp.factory('Enumerate', 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('incorrect arguments.');
}
};
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 && 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;
};
});
Using
myApp..factory('StandardColumn', [
'Enumerate',
function (Enumerate) {
var StandardColumn = function () {
};
/* define enum */
StandardColumn.Format = Enumerate([
{name: 'STRING', description: 'ตัวหนังสือ'},
{name: 'NUMBER', description: 'ตัวเลข'},
{name: 'STUDENT', description: 'นักเรียน'}
]);
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([
'SUM',
'AVERAGE'
]);
StandardColumn.prototype = {
id: null,
name: null,
sequence: 1,
format: StandardColumn.Format.STRING,
operation: null,
operateWith: null
};
return StandardColumn;
}
]);
วันจันทร์ที่ 9 มีนาคม พ.ศ. 2558
พีระมิต (pyramid) : java
วันนี้นั่งแย่งโจทย์น้องฝึกงานเล่นครับ
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 <= size; i++) {
int numb = i % n;
int space = bigSpace - i / n;
boolean star = numb > space && numb <= (n - space);
System.out.print(star ? "*" : " ");
System.out.print(numb == 0 ? "\n" : "");
}
}
}
วันพุธที่ 4 มีนาคม พ.ศ. 2558
Spring security bypass authen : java
เราสามารถทำแบบนี้ได้ครับ spring จะไม่ check username password เรา
เราแค่จับ ข้อมูล user (user details) ยัดเข้าไปใน spring context security เลย
ทำไมต้อง bypass
เนื่องจากการ authen แบบเดิม เราต้องรู้ username และ clean password เพื่อ authen เข้าใช้งาน
มันเกิดปัญหาว่า ระบบที่ผมทำ ผมไม่ได้เก็บ password ของผู้ใช้เป็น clean text ไว้ ผมเข้ารหัส password ไว้ตั้งแต่แรก (เพื่อความปลอดภัย) เพราะฉะนั้น ผมจึงใช้วิธี authen แบบเดิมไม่ได้ (authen แบบเดิม จะเอา password มา encrypt check กับ encrypt password ที่มีอยู่ ว่า matches กันมั้ย)
ปัญหาต่อมา คือ ผมทำระบบที่สามารถ login ด้วยบัญชีผู้ใช้ facebook แน่นอนว่ามันไม่มี password เพราะ facebook ใช้ token แล้วผมจะ authen เข้าสู่ระบบที่ผมทำยังไง?
คิดอยู่สักพัก ก็เกิดคำถามขึ้นมาในหัว เราสามารถ bypass มันได้มั้ย ?
ก็เลยเป็นที่มาของบทความวันนี้ครับ
วันอังคารที่ 3 กุมภาพันธ์ พ.ศ. 2558
oracle sql order by multiple point string
ปัญหา
ถ้าเรา order by string แบบธรรมดาๆ เราจะเจอปัญหาแบบนี้
วิธีแก้
เปลี่ยนมา order by ด้วย sql function ที่ผมเขียนขึ้นมาใหม่ ได้เป็น
ถ้าเรา order by string แบบธรรมดาๆ เราจะเจอปัญหาแบบนี้
การ order by string 10 จะมาก่อน 2 เพราะรหัส ASCII ของ 1 อยู่ก่อน 2
วิธีแก้
เปลี่ยนมา order by ด้วย sql function ที่ผมเขียนขึ้นมาใหม่ ได้เป็น
วันอาทิตย์ที่ 1 กุมภาพันธ์ พ.ศ. 2558
ทำความรู้จักกับ JWT (Json Web Token)
ย้ายบทความไปไว้ที่ https://www.jittagornp.me/blog/what-is-jwt/
วันพฤหัสบดีที่ 29 มกราคม พ.ศ. 2558
Oracle SQL แยกหัวข้อ ออกจากข้อความ
select data.*,
trim(replace(data.old_name, (numb), '')) new_name
from(
select name old_name,
regexp_substr(name, '^[0-9ก-ฮ\.]+\)*\s') numb
from MY_TABLE
) data
วันอังคารที่ 27 มกราคม พ.ศ. 2558
วันพุธที่ 21 มกราคม พ.ศ. 2558
แก้ปัญหา multiple values sql IN : oracle
คำสั่ง IN เป็นคำสั่งที่ใช้สำหรับตรวจสอบว่า ค่าที่เลือกมานั้น มีอยู่ใน IN หรือไม่ เช่น
ในที่นี้ field code สามารถเป็น AAA หรือ BBB หรือ CCC ได้เท่านั้น (ถึงจะ match กัน)
ไม่สามารถเป็น multiple values เช่น 'AAA, BBB' หรือ 'BBB, CCC' ได้ เพราะมันจะไม่ตรงกับตัวไหนใน IN เลย
'AAA, BBB' ไม่ match กับ 'AAA'
'AAA, BBB' ไม่ match กับ 'BBB'
'AAA, BBB' ไม่ match กับ 'CCC'
แล้วถ้าเราต้องการให้มัน match กันละ เราจะทำยังไง?
เพราะตามความเป็นจริงแล้ว 'AAA, BBB' มันควรจะ match กับทั้ง 'AAA' และ 'BBB'
มาดูแนวคิด+ วิธีแก้ของผมกันครับ
...
...
SELECT code
FROM ...
WHERE code IN('AAA', 'BBB', 'CCC')
...
...
ซึงเราสามารถตรวจสอบได้เพียง ครั้งละ 1 ค่าเท่านั้น (single value)ในที่นี้ field code สามารถเป็น AAA หรือ BBB หรือ CCC ได้เท่านั้น (ถึงจะ match กัน)
ไม่สามารถเป็น multiple values เช่น 'AAA, BBB' หรือ 'BBB, CCC' ได้ เพราะมันจะไม่ตรงกับตัวไหนใน IN เลย
'AAA, BBB' ไม่ match กับ 'AAA'
'AAA, BBB' ไม่ match กับ 'BBB'
'AAA, BBB' ไม่ match กับ 'CCC'
แล้วถ้าเราต้องการให้มัน match กันละ เราจะทำยังไง?
เพราะตามความเป็นจริงแล้ว 'AAA, BBB' มันควรจะ match กับทั้ง 'AAA' และ 'BBB'
มาดูแนวคิด
วันจันทร์ที่ 19 มกราคม พ.ศ. 2558
Split String to rows : Oracle SQL
บางครั้งเราอาจเจอโจทย์ที่ต้องแยก String ออกเป็นหลายๆ rows ครับ
SELECT trim(regexp_substr('String1,String2,String3', '[^,]+', 1, LEVEL)) str_2_tab
FROM dual
CONNECT BY LEVEL <= regexp_count('String1,String2,String3', ',')+1
thank you : http://stackoverflow.com/questions/14328621/oracle-10g-splitting-string-into-multiple-rows
วันศุกร์ที่ 9 มกราคม พ.ศ. 2558
แก้ปัญหา Oracle SQL LISTAGG not support
LISTAGG เป็น aggregate function ที่เอาไว้ join multiple row ให้เป้น single row เช่น
ถ้าเรา run SQL นี้ไม่ได้ (เนื่องจาก version ไม่ support)
ถ้าเรา run SQL นี้ไม่ได้ (เนื่องจาก version ไม่ support)
select gp, LISTAGG(name, ', ') WITHIN GROUP (ORDER BY name) name from( select 'A' gp, 1 name from dual UNION select 'A' gp, 2 name from dual UNION select 'A' gp, 3 name from dual UNION select 'A' gp, 4 name from dual UNION select 'B' gp, 5 name from dual UNION select 'B' gp, 6 name from dual UNION select 'B' gp, 7 name from dual UNION select 'B' gp, 8 name from dual ) group by gpลอง run แบบนี้ดูครับ
select gp, RTRIM (XMLAGG (XMLELEMENT (e, name || ', ')).EXTRACT ('//text()'), ', ') name
from(
select 'A' gp, 1 name from dual
UNION
select 'A' gp, 2 name from dual
UNION
select 'A' gp, 3 name from dual
UNION
select 'A' gp, 4 name from dual
UNION
select 'B' gp, 5 name from dual
UNION
select 'B' gp, 6 name from dual
UNION
select 'B' gp, 7 name from dual
UNION
select 'B' gp, 8 name from dual
)
group by gp
ถ้าทำแล้วมันมี string ที่ซ้ำกันแล้วเราต้องการลบตัวที่ซ้ำ ใช้ ตัวนี้ช่วยครับ
...
... /* replace YOUR_STRING */
...
REGEXP_REPLACE(REGEXP_REPLACE(regexp_replace( YOUR_STRING ,'([^,]+)(, \1)+', '\1'),',{2,}',','),'^,|,$','')
...
...
Thank you : http://stackoverflow.com/questions/468990/how-can-i-combine-multiple-rows-into-a-comma-delimited-list-in-oracle
วันอังคารที่ 6 มกราคม พ.ศ. 2558
Excel Object Mapping
บางครั้งเราอาจเจอโปรเจ็คที่ลูกค้าต้องการ ให้ import ข้อมูลจาก excel เข้าไปในฐานข้อมูล
แต่มันไม่ได้ง่ายขนาดที่ว่า เอา excel มายัดลงข้อมูลได้เลย เนื่องจากรูปแบบข้อมูลที่แต่ละคนกำหนดมา ไม่เหมือนกัน (วาง column ไม่ตรง pattern ข้อมูลไม่ถูกต้อง) และต้องการให้เรา validate ข้อมูลก่อนนำเข้า จึงเป็นที่มาของการเขียนโปรแกรม เพื่ออ่านข้อมูลจาก excel file ไปเป็น java object
ทำครั้งแรกครั้งที่ 2 ก็ไม่เท่าไหร่ แต่ทำซ้ำไปซ้ำมา รู้สึกว่า มันเริ่มไม่โอเคล่ะ เขียน code เดิมๆ ไม่ได้ความรู้อะไรใหม่ขึ้นมาเลย เริ่มจะไม่อยากยุ่งกับมันล่ะ ก็เลยคิดว่าทำไมเราไม่เขียนเป็น library ไว้ใช้เลยล่ะ โปรเจ็คหน้า ก็เอาตัวนี้ไปใช้ได้เลย ง่ายๆ สะดวกดี
ผมจึงตัดสินใจ เขียน lib Excel Object Mapping สำหรับ Map Excel file ไปเป็น Java Object ให้อัตโนมัติครับ โดยเราแค่ตั้งชื่อ excel แถวแรก ให้ตรงตามชื่อ column ใน java class ที่เราต้องการให้ map ไป แค่นี้มันก็ map ให้แล้วครับ
https://github.com/jittagornp/excel-object-mapping
อนาคต ผมอาจเพิ่มการ validate ข้อมูลที่ซับซ้อนขึ้นไปอีก เพื่อให้ตอบโจทย์กับสิ่งที่เรากำลังทำอยู่ :)
แต่มันไม่ได้ง่ายขนาดที่ว่า เอา excel มายัดลงข้อมูลได้เลย เนื่องจากรูปแบบข้อมูลที่แต่ละคนกำหนดมา ไม่เหมือนกัน (วาง column ไม่ตรง pattern ข้อมูลไม่ถูกต้อง) และต้องการให้เรา validate ข้อมูลก่อนนำเข้า จึงเป็นที่มาของการเขียนโปรแกรม เพื่ออ่านข้อมูลจาก excel file ไปเป็น java object
ทำครั้งแรกครั้งที่ 2 ก็ไม่เท่าไหร่ แต่ทำซ้ำไปซ้ำมา รู้สึกว่า มันเริ่มไม่โอเคล่ะ เขียน code เดิมๆ ไม่ได้ความรู้อะไรใหม่ขึ้นมาเลย เริ่มจะไม่อยากยุ่งกับมันล่ะ ก็เลยคิดว่าทำไมเราไม่เขียนเป็น library ไว้ใช้เลยล่ะ โปรเจ็คหน้า ก็เอาตัวนี้ไปใช้ได้เลย ง่ายๆ สะดวกดี
ผมจึงตัดสินใจ เขียน lib Excel Object Mapping สำหรับ Map Excel file ไปเป็น Java Object ให้อัตโนมัติครับ โดยเราแค่ตั้งชื่อ excel แถวแรก ให้ตรงตามชื่อ column ใน java class ที่เราต้องการให้ map ไป แค่นี้มันก็ map ให้แล้วครับ
https://github.com/jittagornp/excel-object-mapping
อนาคต ผมอาจเพิ่มการ validate ข้อมูลที่ซับซ้อนขึ้นไปอีก เพื่อให้ตอบโจทย์กับสิ่งที่เรากำลังทำอยู่ :)
วันจันทร์ที่ 24 พฤศจิกายน พ.ศ. 2557
วันเสาร์ที่ 22 พฤศจิกายน พ.ศ. 2557
แก้ปัญหา time zone ด้วยการ set JVM Time Zone : java
ปัญหา
เนื่องจากผมทำการพัฒนา java web application และได้ทำการเช่า cloud server (VPS : Virtual Private Server) อยู่ที่ต่างประเทศ ปัญหาที่เจอคือเรื่องของเวลา ที่ไม่ตรงกัน ระหว่าง client (browser) และ server ทำให้การบันทึกข้อมูลลง database มีความผิดเพี้ยนไปจากความเป็นจริง
วิธีแก้
ผมลอง search หาข้อมูลเพื่อแก้ไขปัญหาดังกล่าว มีคนนึงแนะนำว่า ลอง set time zone ให้ JVM ดู น่าจะแก้ได้ ผมเลยลองทำตาม ปรากฎว่าได้จริงๆ ครับ ซึ่ง set ค่าให้ JVM ดังนี้
เนื่องจากผมทำการพัฒนา java web application และได้ทำการเช่า cloud server (VPS : Virtual Private Server) อยู่ที่ต่างประเทศ ปัญหาที่เจอคือเรื่องของเวลา ที่ไม่ตรงกัน ระหว่าง client (browser) และ server ทำให้การบันทึกข้อมูลลง database มีความผิดเพี้ยนไปจากความเป็นจริง
วิธีแก้
ผมลอง search หาข้อมูลเพื่อแก้ไขปัญหาดังกล่าว มีคนนึงแนะนำว่า ลอง set time zone ให้ JVM ดู น่าจะแก้ได้ ผมเลยลองทำตาม ปรากฎว่าได้จริงๆ ครับ ซึ่ง set ค่าให้ JVM ดังนี้
วันศุกร์ที่ 21 พฤศจิกายน พ.ศ. 2557
BottomScrollFixer : javascript
บางที element ของเรา อาจจะยาวมากๆ จนล้นหน้าจอ (window) แล้ว element นั้น ก็เกิด bottom overflow (overflow-x เป็น scroll หรือ auto) ด้วย
ปัญหา
ปัญหาที่เจอก็คือ เราต้องเลื่อน scroll ของ window ลงมาข้างล่างสุดของ element นั้นก่อน เราถึงจะสามารถเลื่อน scroll X ของ element นั้นได้ (เพราะ element มันล้นจอ)
วิธีแก้
ผมเลยทำการเขียน javascript ขึ้นมาเพื่อแก้ปัญหานี้ โดยให้มันทำการคำนวนและ fixed bottom scroll ให้โดยอัตโนมัติ โดยที่เราไม่ต้องเลื่อน window scroll ลงไปข้างล่าง มันจะ fixed ให้ทันทีที่เราเลื่อน scroll ไปถึง element นั้นตามขนาดที่เราได้ fixed ไว้ (withFixedHeight) โดยไม่จำเป็นต้องเลือนลงไปยังข้างล่างสุดของ element bottom scroll จะเลื่อนตามเราไปเรื่อยๆ จนกว่าจะพ้น element นั้นๆ
ปัญหา
ปัญหาที่เจอก็คือ เราต้องเลื่อน scroll ของ window ลงมาข้างล่างสุดของ element นั้นก่อน เราถึงจะสามารถเลื่อน scroll X ของ element นั้นได้ (เพราะ element มันล้นจอ)
วิธีแก้
ผมเลยทำการเขียน javascript ขึ้นมาเพื่อแก้ปัญหานี้ โดยให้มันทำการคำนวนและ fixed bottom scroll ให้โดยอัตโนมัติ โดยที่เราไม่ต้องเลื่อน window scroll ลงไปข้างล่าง มันจะ fixed ให้ทันทีที่เราเลื่อน scroll ไปถึง element นั้นตามขนาดที่เราได้ fixed ไว้ (withFixedHeight) โดยไม่จำเป็นต้องเลือนลงไปยังข้างล่างสุดของ element bottom scroll จะเลื่อนตามเราไปเรื่อยๆ จนกว่าจะพ้น element นั้นๆ
วันพุธที่ 12 พฤศจิกายน พ.ศ. 2557
age computation oracle sql
code
year month day
13 10 29
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('15122000','DDMMYYYY') dob
from dual
);
outputyear month day
13 10 29
วันพุธที่ 22 ตุลาคม พ.ศ. 2557
เขียน Service Glassfish Server บน Linux Ubuntu
server นี้ผมได้ทำการ set GLASSFISH_HOME ไว้ใน $PATH ของ file ~/.bashrc แล้วน่ะครับ จึงทำให้สามารถเรียก asadmin ได้เลย โดยไม่ต้องใช้ path เต็มครับ
1. ไปที่ /etc/init.d/ ด้วยคำสั่ง
1. ไปที่ /etc/init.d/ ด้วยคำสั่ง
$ cd /etc/init.d/2. สร้าง file service glassfish ด้วยคำสั่ง
$ sudo vi glassfish3. เขียนชุดคำสั่ง
#!/bin/sh
#
# define service function
start(){
asadmin start-domain >/dev/null
}
stop(){
asadmin stop-domain >/dev/null
}
restart(){
asadmin restart-domain >/dev/null
}
#detect service argument
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo $"Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0
4. สั่งงาน
$ service glassfish startหรือ
$ /etc/init.d/glassfish start
สมัครสมาชิก:
บทความ (Atom)












