ข้ามไปที่เนื้อหาหลัก

EJB development ด้วย Glassfish Server -- Part 3 EJB3Unit ( Unit Testing EJB3 Modules )

ตัวอย่าง EJB3Unit


ไปดู doc และ ตัวอย่างได้จาก Ejb3Unit homepage
หรือ
download Ejb3UnitSampleProject-2.0.0-RC-1.zip

how to import existing project in eclipse



วิธี1 จะก็อป jar ไฟล์เข้าโปรเจคเองก็ได้
วิธี2 จะ Properties > Java Build Path > libraries > Add External JARs ก็ได้
โดยโหลดจาก ejb3unit-jars.zip

extract ไฟล์ก่อนแล้วค่อย add นะ ย้ำ


จากนั้นลองรัน
Run As -> [Junit icon] Execute all ejb3 unit tests.

มันจะรัน 31 tests ผ่านโดยไม่มี errors




สร้าง new project เพื่อ test EJBs ของคุณ

ejbunit สร้าง on top of Junit ( ใช้ javaSE )

ไม่ต้อง export ก่อนรันเทส ejbunit จะ simulate environment

ทำ Part 2 ให้ work ก่อน

เพราะว่านี่จะทำต่อจาก Part 2 ( Eclipse/EJB/GlassFish/JPA )

ตอนนี้ก็มี Project titan-ejb ที่มี EJB module targeted for GlassFish

- มี entities Cabin, Customer, และ Phone

- มี stateless session bean ชื่อว่า TravelAgentBean และมี remote interface


- สร้าง new Java project ชื่อ titan-tests

add the external JARs for Ejb3Unit ให้เรียบร้อย


- บอก Eclipse ให้ reference unit test project (titan-tests) ไปยัง EJB module project (titan-ejb)

ทำให้สามารถเข้าถึง source classes ใน EJB module project ได้


add the titan-ejb project ไปยัง "Java Build Path" ในแท็บ "Projects"

และ add the titan-ejb project ใน "Project References"

สร้าง entity unit test

- เทส Phone entity ก่อนละกัน

ก่อนอื่น เราต้อง override equals() กับ hashCode() ในคลาส Phone
เพราะ detached entity ต้อง"เท่ากับ" และสร้าง hash code เดียวกันกับ attached version

กลับไปเพิ่ม code เพื่อ override the methods ที่คลาส Phone ใน titan-ejb project

@Override
public boolean equals(Object other) {
if (other != null && other instanceof Phone) {
final Phone that = (Phone) other;
final EqualsBuilder builder = new EqualsBuilder();
builder.append(this.id, that.id);
builder.append(this.number, that.number);
return builder.isEquals();
}
return false;
}
@Override
public int hashCode() {
final HashCodeBuilder builder = new HashCodeBuilder();
builder.append(this.id);
builder.append(this.number);
return builder.toHashCode();
}

โค้ดที่เราเพิ่มไป มันใช้คลาส EqualsBuilder ( อยู่ใน commons-lang-2.4.jar : Apache Commons Lang library และอยู่ในไฟล์ ejb3unit-jars.zip ที่โหลดมาตะกี้ ) add มันใส่ build path ด้วย


ตอนนี้ titan-ejb project มี commons-lang-2.4.jar แต่ dependency มันจะไม่โดนแพ็คไปกับ EJB JAR file ตอน deploy ขึ้น application server (จะเจอ errors ประมาณว่า "class not found" ตอนรันบน application server)
สำหรับ GlassFish, ให้ก็อบ JAR file ที่ต้องใช้ไปที่ glassfish/domains/domain1/lib/ext/ (assuming your domain is domain1) มันจะ available สำหรับทุกๆ components ที่ deployed ไปยัง domain1.


กลับมายัง titan-tests project เพิ่ม class PhoneTest ( package com.titan.entitytests )
public class PhoneTest extends BaseEntityFixture<Phone> {
public PhoneTest() {
super(Phone.class);
}
}

คลาสนี้ แค่ใช้ default behavior ของคลาส BaseEntityFixture เพื่อเทสคลาส Phone

รันได้ละ คลิกขวา Run As -> JUnit Test จะมี 5/5 tests pass

testNothing() ซึ่งเป็น คลาสที่ inherit มา แล้วก็ 4 คลาสที่สร้างขึ้น

Configure Ejb3Unit

โดยใช้ ejb3unit.properties configuration file

New -> Source Folder ชื่อ "resources" ที่ level บนสุดของ titan-tests project
เพิ่ม file ejb3unit.properties


ejb3unit.inMemoryTest=true
ejb3unit.show_sql=true

## values are create-drop, create, update ##
ejb3unit.schema.update=create-drop

โค้ดนี้บอก Ejb3Unit ว่าให้จำลอง database ใน memory เพื่อแสดง SQL queries ที่ส่งไปยัง database บน console ( ไม่ต้องต่อกับ database จริง, ถ้าอยากต่อ database จริง ก็ config ในนี้แหละ ดูวิธีจาก Ejb3Unit documentation )

และ drop and create necessary tables สำหรับ entites ทุกครั้งที่ Ejb3Unit starts up

Unit testing entities manually

Ejb3Unit สนับสนุน automated test entities ที่เป็นแบบ one-to-many bidirectional associations ( เทสโดยใช้คลาส BaseEntityFixture )

แต่ไม่ support automated เทส entities ที่เป็นแบบ unidirectional associations ( ไปใช้คลาส PojoFixture แทน )


Mapping Customer-to-Phone ของเราเป็น one-to-many unidirectional เราจึงไม่สามารถใช้ BaseEntityFixture สำหรับคลาส Customer


เริ่มจาก สร้าง hashCode() และ equals() ในคลาส Customer


@Override
public boolean equals(Object other) {
if (other != null && other instanceof Customer) {
final Customer that = (Customer) other;
final EqualsBuilder builder = new EqualsBuilder();
builder.append(this.firstName, that.firstName);
builder.append(this.lastName, that.lastName);
builder.append(this.id, that.id);
return builder.isEquals();
}
return false;
}
@Override
public int hashCode() {
final HashCodeBuilder builder = new HashCodeBuilder();
builder.append(this.firstName);
builder.append(this.lastName);
builder.append(this.id);
return builder.toHashCode();
}

และสร้าง test class ตามนี้


public class CustomerTest extends PoJoFixture {

private static final Class[] USED_ENTITIES = { Customer.class, Phone.class };

public CustomerTest() {
super( USED_ENTITIES );
}

public void testGetEntityManager() {
assertNotNull(this.getEntityManager());
}

public void testWriteCustomer() {
List<Customer> customers = generateTestCustomers();

// persist the graph and load it again
List<Customer> persisted = persist(customers);
List<Customer> allFromDB = findAll(Customer.class);

// assert the persisted graph and the loaded are equal
assertCollectionsEqual(persisted, allFromDB);
}

private List<Customer> generateTestCustomers() {
final List<Customer> customers = new ArrayList<Customer>();
Customer customer = new Customer();
customer.setFirstName( "Matthew" );
customer.setLastName( "Dailey" );
customer.addPhoneNumber( "+66851234567" );
customers.add( customer );
return customers;
}

// Manually delete customers with the entity manager so that
// the delete cascades to the dependent phone numbers.
private void deleteCustomers() {
EntityManager em = getEntityManager();
List<Customer> customers = findAll(Customer.class);
for ( Customer customer : customers ) {
em.remove( customer );
}
}

@Override
public void setUp() throws Exception {
super.setUp();
deleteCustomers();
deleteAll(Phone.class);
}

@Override
public void tearDown() throws Exception {
deleteCustomers();
deleteAll(Phone.class);
super.tearDown();
}
}
เหมือนเดิม คลิกขวา Run As -> JUnit Test
ปล. ต้องไปเพิ่ม method addPhoneNumber เข้า คลาส Customer เพื่อให้มันเรียก
customer.addPhoneNumber( "+66851234567" );
ได้ด้วย

Unit testing session beans ========================================

Ejb3Unit เทส session beans ได้มากมายมาก ดูจากตัวอย่างที่โหลดมาได้ ( DIFieldSessionBeanTest.java )

ตอนนี้เราจะเทส TravelAgentBean


เพิ่ม functionality ไปยัง TravelAgentRemote interface:


@Remote
public interface TravelAgentRemote {
public void createCabin( Cabin cabin );
public Cabin findCabin( int id );
public List<Cabin> getAllCabins(); //
public int createCustomer( Customer customer );
public Collection<Phone> phoneNumbersForCust( int id );
public EntityManager getEm(); //
}

เราจะ test dependency injection ของ entity manager ที่ initialization timeand each of the methods. นี่คือวิธี implement method ใหม่ :


public EntityManager getEm() {
return this.manager;
}

@SuppressWarnings("unchecked")
public List<Cabin> getAllCabins() {
Query query = manager.createQuery( "SELECT c FROM Cabin c" );
return Collections.checkedList( query.getResultList(), Cabin.class );
}

ใน ejb-tests project, สร้างคลาส TravelAgentBeanTest ( package com.titan.sessionbeantests )


public class TravelAgentBeanTest extends BaseSessionBeanFixture<Travelagentbean> {

private static final Class[] usedBeans = { Cabin.class }; // Entity ที่เกี่ยวข้อง ต้องใส่ลงไปให้หมด ( ไม่งั้นจะเจอ java.lang.IllegalArgumentException: Unknown entity: หรือไม่ก็ EntityManager could not be initialized to load the enities [com.midterm.domain.Cm, com.midterm.domain.BidInvitation]. Cause: org.ejb3unit.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: com.midterm.domain.BidInvitation.bids[com.midterm.domain.Bid] )
private static final CSVInitialDataSet<Cabin> CSV_SET =
new CSVInitialDataSet<Cabin>( Cabin.class, "testCabins.csv", "id", "name",
"deckLevel", "shipId", "bedCount" );
public TravelAgentBeanTest() {
// super(sessionBeanToTest, introspector, usedEntityBeans, initialData)
super( TravelAgentBean.class, usedBeans, new CabinEntityInitialDataSet(), CSV_SET ); //
}
public void testDependencyInjection() {
final TravelAgentBean toTest = this.getBeanToTest();
assertNotNull(toTest);
assertNotNull(toTest.getEm());
}
public void testLoadData() {
final TravelAgentBean travelAgentBean = this.getBeanToTest();
assertNotNull(travelAgentBean);
List<Cabin> cabins = travelAgentBean.getAllCabins();
assertNotNull(cabins);
System.out.println( "cabins has " + cabins.size() + " entries" );
assertEquals( 6, cabins.size() );
assertEquals( cabins.get(0), new Cabin( 1, "Cabin 8", 1 ));
assertEquals( cabins.get(1), new Cabin( 2, "Cabin 12", 1 ));
}
public static class CabinEntityInitialDataSet extends EntityInitialDataSet<Cabin> {
public CabinEntityInitialDataSet() {
super(Cabin.class);
}
public void create() {
this.add( new Cabin( 1, "Cabin 8", 1 ));
this.add( new Cabin( 2, "Cabin 12", 1 ));
}
}
}

นี่เป็น dependency injection test สองวิธีที่จะสร้าง entity test fixtures
วิธี1 โหลดจาก resources/testCabins.csv ( resources เป็น sources folder )
วิธี2 manually adding entities โดยใช้คลาส EntityInitialDataSet
ตัวอย่างข้างบนใส่ initial data ทั้งสองวิธี

ในไฟล์ csv ใส่อะไรประมาณนี้ลงไป

100,"Cabin 345",1,1,2
101,"Cabin 346",1,1,3
102,"Cabin 347",2,1,2
103,"Cabin 348",2,1,3

แล้วก็เพิ่มเทสลงไป
public void testCreateCabin() {
final TravelAgentBean travelAgentBean = this.getBeanToTest();
// Get list of cabins before we do the create
List<Cabin> cabinsBefore = travelAgentBean.getAllCabins();
assertEquals(6, cabinsBefore.size());
EntityManager manager = travelAgentBean.getEm();
EntityTransaction transaction = manager.getTransaction();
transaction.begin();
for ( int i = 0; i < 10; i++ ) {
Cabin cabin = new Cabin();
cabinsBefore.add( cabin );
cabin.setShipId(3);
cabin.setName("New cabin " + i);
cabin.setDeckLevel(5);
cabin.setBedCount(2);
travelAgentBean.createCabin(cabin);
}
transaction.commit();
List<Cabin> cabinsAfter = travelAgentBean.getAllCabins();
assertEquals(16, cabinsAfter.size());
assertCollectionsEqual(cabinsBefore, cabinsAfter);
}
สังเกตว่า เราสร้าง entity manager transaction manually
ไม่งั้น ในเมธอด getAllCabins() ตอนเรา execute EJB QL query เพื่อ retrieve all persisted Cabins มันจะยัดลง database ไม่ได้

public void testFindCabin() {
final TravelAgentBean travelAgentBean = this.getBeanToTest();
// The cabin with name "Cabin 8" added in the create() method of the initial data
// set should have its ID generated as 118 by the time we get to this test case.
Cabin cabin = travelAgentBean.findCabin(118);
assertEquals(cabin, new Cabin(118, "Cabin 8", 1));
}


ref : mdailey

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

ส่งไปรษณีย์ทีละมากๆ ที่ช่องไปรษณีย์สำหรับธุรกิจ

  ถ้าเราส่งไปรษณีย์ทีละ 10 กล่องขึ้นไป สามารถไปส่งโดยใช้ช่องทางธุรกิจได้ โดยต้องกรอกใบรับฝากรวม ( Receipt for bulk Posting ) เป็นลิสต์รายการให้เขาไปด้วย โดยกรอกพัสดุแต่ละรายการ และ ไปยื่นให้เขาพร้อมกับพัสดุที่จะส่ง วิธีกรอก คือ ให้กรอกพัสดุแบบเดียวกันไว้แผ่นเดียวกัน  เช่น พัสดุ10 กล่อง กล่องขนาดเท่ากัน น้ำหนักเท่ากันหมด กรอกไว้ 1 แผ่น ถ้าน้ำหนักต่างกัน ขนาดกล่องต่างกัน กรอกแยกแผ่นไว้ดีที่สุด ซึ่งใบนี้สามารถไปขอได้ที่ไปรษณีย์ฝ่ายธุรกิจ สามารถนำมาทำใส่ A4 ก็ได้ ขอบคุณคุณพี่ amarin.ch ที่ไปรษณีย์กลาง ( BANGKOK G.P.O. ) มากๆ นะครับ สำหรับคำแนะนำ ขอบคุณที่ช่วยคีย์ให้ทีละรายการสำหรับมือใหม่ที่ยังไม่รู้ว่ามีใบรับฝากรวมอย่างผมด้วยครับ คราวหน้าผมจะทำใบรับฝากรวมไปครับ

[ AI ] IBM granite, NVIDIA robotics, IBM Langflow, watsonx, LMCache, LiteRT, Self driving car, Mamba model, RAG

 IBM granite: Time series from sensor, stock market * Forcast * Anomaly detection - classification high medium risk, data synthesis Embedding AI - 1M params - edge device - small AI Send insight --- NVIDIA * Jackson Thor robotic * Nemo ---- * IBM Langflow : open source * Watsonx (n8n) Enterprise : guardrails / log, tool using policy ----- LMcache : open source KC cache Prompt -> key value (RAGs) Same context ( e.g. same docs) Reduce operating costs CacheGen : make cache cheap to move and store CacheBlend : reuse chunk, not just prefix ---- Google มี framework ที่ optimize AI บน mobile phone นั่นคือ LiteRT : google pytorch Quantisation เท่าไหร่บน device นี้ Model explorer: quantize แล้ว error < 5% XMNpack ใช้ CPU ลดลง Google AI edge portal : benchmark AI on real device ---- Self driving car * Nvidia Alpamayo 2 model * Carla simulation Random forest -> multiple scenarios -> json -> LLM Car talk to mobile phone (cross the road) ----- Mamba model (recursive)  - alte...

อยู่เหงาๆ เราไปเที่ยว - ไหว้พระขอพร ศาลเจ้าแม่ทับทิม (อาม่า), เจริญกรุง, กรุงเทพ; 天后聖母廟, 石龙軍路, 曼谷, 泰国; Thap Thim Chinese Goddess Shrine, Chareon Krung 63 Road, Bangkok, Thailand

天后聖母廟, 石龙軍路, 曼谷, 泰国 ไหว้ศาลเจ้าแม่ทับทิม ขอให้การค้าเจริญรุ่งเรือง ตำนานเจ้าแม่ทับทิมเกิดที่ตำบลตุ้ยบ๊วย เขตบ่นเซียว เกาะไหหลำ มีผู้เฒ่าแซ่พัว เป็นผู้มีความซื่อสัตย์สุจริต ทำงานขยันขันแข็ง ครั้งหนึ่งแกออกไปหาปลา โดยผูกแหเป็นช้อนดักปลา เวลาผ่านไปแกยังหาปลาไม่ได้ คืนนั้นก็ประสบความล้มเหลว เมื่อช้อนแหขึ้นมาทีไรก้อมีแต่ท่อนไม้ ด้วยความโมโหแกเลยขว้างท่อนไม้นั้นออกไปให้ไกล แต่แล้วเมื่อช้อนแหขึ้นมาใหม่ก็ปรากฏท่อนไม้ท่อนเดิมอีก ต่อจากนั้นแกก็ขว้างท่อนไม้ขึ้นฝั่ง และแกก็ฉุก คิดว่าแปลกที่ท่อนไม้ธรรมดาจะสามารถลอยทวนน้ำได้ คงจะเป็นสิ่งวิเศษ และแกก็ได้นำท่อนไม้นั้นขึ้นฝั่ง และเพ่งมองท่อนไม้นั้นพร้อมกับอธิษฐานว่า หากท่อนไม้นี้มีความศักดิ์สิทธิ์ขอให้คืนนี้จับปลาได้มาก เมื่อพ้นจากความจนแล้ว เมื่อขึ้นฝั่งจะนำท่อนไม้นี้แกะสลักเป็นเทวรูปศักดิ์สิทธิและสักการะบูชาเช้าวันไม่ให้ขาด เมื่ออธิษฐานจบแกเอาท่อนไม้นั้นวางบนหัวเรือ ปรากฏว่าช้อนเพียงสองถึงสามครั้งก็ได้ปลาตัวโตเต็มเรือ จึงนำปลาขึ้นฝั่งวันนั้นปลาของแกขายได้ราคา เพราะชาวประมงคนอื่นจับได้น้อยแกจึงมีเงินจับจ่ายใช้สอย และทุกครั้งที่แกออกหาปลา ...

EJB development ด้วย Glassfish Server -- Part 2 ( Create a project )

สร้าง project สำหรับ EJB module สร้าง EJB project ชื่อว่า titan-ejb เลือก Target Runtime : Glassfish คลิกขวาที่ Project ติ๊ก JPA facet, และ configure JPA facet ให้ใช้ connection profile ที่สร้างไว้แล้ว >>>>>>>>>>>>>>>>>>> วิธีสร้าง JPA Entity: - คลิกขวาที่ Project Explorer - New->Class ชื่อ com.titan.domain.Cabin implement java.io.Serializable [ Serializable คือ สามารถ convert class to String แล้วส่งไปที่ network ได้ ] วิธีสร้าง implement class บน eclipse มันก็จะสร้างฟังก์ชั่นโบ๋ๆ มาให้ package com.titan.domain; import java.io.Serializable; public class Cabin implements Serializable { } - Add the fields static final long serialVersionUID = 1L; private int id; private String name; private int deckLevel; private int shipId; private int bedCount; - สร้าง getters and setters สำหรับ id, name, deckLevel, shipId, and bedCount. [ ใน eclipse ง่ายมาก ไปที่ Source > Generate setters and getters ( หรือ คลิกขวาตรงที่เขียนโค้ด So...

20 th century boys movie ( 20世紀少年, Nijisseiki Shōnen )

โอ ว้าววว มีภาคโ รงหนังด้วย เห็นเขาว่า ทำเป็น 3 ภาค ภาคแรก ฉาย 30 สิงหาคม 2008 นี้แล้ว ถ่ายใน 7 ประเทศ ซึ่งแน่นอนว่า ต้องมีประเทศไทยด้วยแน่นอน theme song “20th Century Boy” ร้องโดย วงร๊อกอังกฤษ T.Rex ดูหน้าคนเล่นกันดีกว่า casting เอ็นโด เคนจิ แสดงโดย Toshiaki Karasawa โอตโจะ แสดงโดย Etsushi Toyokawa ยูคิจิ แสดงโดย Takako Tokiwa โยชิสึเนะ แสดงโดย Teruyuki Kagawa มารุโอะ แสดงโดย Hidehiko Ishizuka เคโรยอน แสดงโดย Hiroyuki Miyasako ดองกี้ แสดงโดย Katsuhisa Namase ยามาเนะ แสดงโดย Fumiyo Kohinata ฟุคุเบ แสดงโดย Kuranosuke Sasaki มันโจเมะ อินชู แสดงโดย Renji Ishibashi พระเจ้า เอ็นโด คิริโกะ แสดงโดย Hitomi Kuroki มาซาโอะ ทามุระ แสดงโดย ARATA มอนจัง แสดงโดย Takashi Ukaji แม่ของเคนจิ นักแสดงอื่นๆอีก ตัวละคร 300 กว่าตัว Match หน้ากับชื่อ ไม่ถูกกันเลยทีเดียว Nana Katase - Mika Shikishima Chizuru Ikewaki - part-time worker Erika Mirai Moriyama - mangaka Kameda Yu Tokui - convenience store employee Miyako Takeuchi - Setsuko Ichihara Yoriko Doguchi - Mitsuko Kido Kenichi Endo - bloody man Ke...

แนะนำ ยาบำรุงครรภ์ จับซาไท้เป้า หรือ 13 องครักษ์พิทักษ์ครรภ์ ยาจีน บำรุงครรภ์

จับซาไท้เป้า  ยาบำรุงครรภ์ สมุนไพรจีน ช่วงนี้เพื่อนๆ เริ่ม ทยอย แต่งงาน กันแล้ว นะครับ เราเองก็มียาจีนมา นำเสนอ ซึ่งเป็น ยาดี ที่คุณแม่ ของเรา ทาน ตอนคลอดเรา นั่นก็คือ "จับซาไท้เป้า" ยาบำรุงครรภ์ นั่นเอง เงง เงง เงง เงง จับซาไท้เป้า เป็น ยาจีน ซึ่ง ประกอบไปด้วย สมุนไพร จีน 13 อย่างด้วยกัน มี สรรพคุณ เป็น ยาบำรุงครรภ์ บำรุง ทั้งคุณแม่ และ คุณลูก เลย เรียกได้ว่า สรรพคุณ ครบครัน บำรุง คุณแม่ ช่วงตั้งท้อง ช่วยให้ คุณลูก แข็งแรง มีผิวพรรณ สะอาดสะอ้าน ในตอนที่คลอดออกมา จะ คลอดง่าย ตัวจะไม่มีคราบไขมันติดเยอะ จ้า วิธีกินจับซาไท้เป้า ทานตั้งแต่ท้อง 5 เดือนขึ้นไป 2 อาทิตย์ทาน 1 ห่อ ทานจนคลอด ศิริรวมแล้ว ถ้าทาน ครบ dose โดยเริ่มตั้งแต่ 5 เดือน ต้องทานทั้งหมด 10 ห่อ จ้ะ วิธีต้มจับซาไท้เป้า  1 ห่อ ต้มได้ 2 ครั้ง ครั้งแรก ใส่น้ำ 3 ถ้วย ต้มเหลือ 8/10 ถ้วย ครั้งที่ 2 ใส่น้ำ 2.5 ถ้วย ต้มเหลือ 7/10 ถ้วย ซื้อที่ไหนดี หลายๆ คน มักจะมีคำถาม ว่า จับซาไท้เป้า ซื้อที่ไหน  ซึ่งเราเอง แนะนำร้านขาย จับซาไท้เป้า ซึ่งก็คือ ร้าน ขายยา ย่ง เช...

เบื่อๆ ไปเที่ยวสิ รวมที่เที่ยวที่อยากไป เวลาเปิด แล้ว แผนที่

ที่เที่ยว ใน กรุงเทพ ที่น่าไป พิพิธภัณฑ์สยาม ที่อยู่ : กระทรวงพาณิชย์เดิม ใกล้วันโพธิ์ ตรงข้ามโรงเรียนวัดราชบพิตร เวลาทำการ : จันทร์ ปิด อังคาร - พฤหัสบดี 09.30 - 18.00 ศุกร์ 09.30 - 21.00 เสาร์ - อาพิตย์ 09.30 - 19.00 Official Web : คลิก ไปมาแล้ว ตามนี้ หอศิลปวัฒนธรรมแห่งกรุงเทพมหานคร (BMA Contemporary Art Museum) หรือ หอศิลป์กรุงเทพฯ เวลาทำการ : จันทร์ ปิด วันอื่นๆ 10.00 - 21.00 น. Official web : คลิก ไปมาแล้ว ตามนี้ สวนสัตว์ดุสิต หรือ เขาดิน วันก่อนโน้นผ่าน เห็นว่าทำใหม่แล้ว ประตูเข้าอลังการมาก เลยอยากเข้าไปดู เวลาทำการ 08.00-18.00 น. ทุกวัน Official web : คลิก ไปมาแล้ว ตามนี้ วัดสระเกศ ภูเขาทอง เปิดให้เข้าชมตั้งแต่เวลา 07.30 – 17.30 น. น่าจะมีงานวัดช่วงลอยกระทง ( ต้นๆ พ.ย. ) ด้วยนะ น่าไปๆ แผนที่ จ้ะ ไปมาแล้ว ตามนี้ ( แต่ไม่ได้ไปตอนมีงาน ) ตำหนัก โชคชัย 4 และ พระมหาเจดีย์พระพุทธเจ้าหมื่นพระองค์ ที่อยู่ : 4/37 ซอยสุขสันต์ 7 ถนนลาดพร้าว 53 (โชคชัย 4) อ.ลาดพร้าว โทร. 66 2 5140715 , 66 2 5389368 แผนที่ จ้ะ ไปม...

อยู่เหงาๆ เราไปเที่ยว - วัดอรุณราชวราราม ( วัดแจ้ง ) + วัดสระเกศ ( ภูเขาทอง )

เอนทรีนี้เป็นส่วนหนึ่งของ serie ท่องเที่ยว ดูบทความท่องเที่ยว อื่นๆ ของผม ได้ที่  ลิงก์นี้  นะครับ คำเตือน เอ็นทรีนี้รูปเยอะมากกกก ควรปิดบิตก่อนดู ผ่างๆๆ ท่านสามารถรับชมเอนทรีนี้ผ่าน url http://tinyurl.com/goldenMount ได้ด้วย วันนี้ตั้งใจไปวัดอรุณฯ เดินทางทางน้ำเหมือนเดิม แต่คราวนี้นั่งเรือ ธงสีฟ้า ( คราวก่อน นั่งเรือ ธงสีส้ม ) พอถึงท่าสาทร เขาบอกว่า ให้ลงลำที่จอดอยู่ได้เลย เก็บตังในเรือ ก็ งงๆ เดินลงไป เหมือนเดิมครับ ชูชีพอยู่ใต้ที่นั่งของท่าน พอเรือออกสักพัก มีไกด์ มาบรรยาย อ้าว กรำ ขึ้นผิดเรือรึเปล่า นี่มันเรือท่องเที่ยว 150 บาท ไม่ใช่เร๊อะ กะลังอึ้งๆอยู่ แต่พอไกด์พูดไปสักพัก ก็เลยรู้ว่า 150 บาท มันราคาเหมาวัน แล้วก็ได้ความรู้ของท่าเรือ แล้วก็สองข้างทาง เรือธงฟ้านี่มันไปสุดที่ท่าพระอาทิตย์เท่านั้นเองนะ แล้วก็กลับ ตอนไปมีสาวคนนึง ถามว่า จะไปวัดสระเกศ ไปทางไหน ถ้าฟังไม่ผิด คนเก็บตังบนเรือ บอกว่า ท่ามหาราช จากนั้นก็คุยอะไรกันไม่รู้ ไม่ได้ยินแล้วล่ะ เรือธงฟ้า มันใหญ่กว่า น่าหวาดเสียวน้อยกว่า น้ำกระเด็นน้อยกว่า แพงกว่า...

เฉินหลงฟัดในปี 2025 The Shadow's Edge

เริ่มดูเพราะ ฉากในลิฟต์ ที่เด้งมาใน tiktok เลยรู้สึกว่า หนังดูมีอะไรจังวะ  พอดูจริงๆ หนังมีอะไรอย่างที่คิดไว้ แม้ตอนแรกๆ ตอนปล้น อาจจะให้ความรู้สึกเหมือน Now You See Me ไปบ้าง แต่หนังมีความสนุก มีอารมณ์ความรู้สึก  มีการใส่เทคโนโลยีใหม่ๆ อย่าง เทคโนโลยีคล้ายๆกับของ Peter Theil แต่ก็ทำงานร่วมกับคนรุ่นเก่าอย่างเฉินหลงได้อย่างดี มีการสร้างตัวร้ายที่เก่งสมน้ำสมเนื้อ  และ ทิ้งท้ายว่า จะมีภาคต่ออีกต่างหาก ชอบประโยคที่ว่า "นายต้องจบงานเองได้"

กระแส AI อุตสาหกรรมอะไรดีบ้าง

กระแส AI Super Cycle ไม่ได้ส่งผลดีแค่กับคนทำซอฟต์แวร์ แต่กำลัง "ยกแผง" อุตสาหกรรมโครงสร้างพื้นฐาน (Infrastructure) ทั้งหมด โดยเฉพาะ 3 กลุ่มหลัก ดังนี้ครับ: 1. อุตสาหกรรมพลังงาน (Energy & Utilities) AI คือ "จอมเขมือบไฟ" ทำให้บริษัทที่ทำระบบผลิตไฟฟ้าและจัดการพลังงานกลายเป็นพระเอกใหม่ โดยเปลี่ยนจากพลังงานแบบเดิมมาเป็นเทคโนโลยีที่สะอาดและเสถียรมากขึ้น สิ่งที่ดีขึ้น: มีการนำเทคโนโลยี Fuel Cell มาใช้ผลิตไฟฟ้าโดยไม่ผ่านการเผาไหม้ เพื่อตอบโจทย์ Data Center ที่ต้องรัน 24 ชม. ตัวอย่าง: Bloom Energy (BE): ใช้ระบบ Solid-oxide Fuel Cell เปลี่ยนก๊าซเป็นไฟฟ้าให้ Oracle แบบ 100% ในโปรเจกต์ยักษ์ Delta Electronics: กลายเป็นตัวตึงด้านระบบจัดการพลังงานที่กำไรทุบสถิติประวัติศาสตร์ 2. อุตสาหกรรมฮาร์ดแวร์และเซมิคอนดักเตอร์ (Hardware & Supply Chain) เมื่อ AI ต้องประมวลผลมหาศาล อุปกรณ์เบื้องหลังจึงต้อง "อัปเกรด" ขนานใหญ่ จนเกิดสภาวะ "คนขายเป็นใหญ่" (Seller's Market) สิ่งที่ดีขึ้น: ความต้องการชิ้นส่วนเฉพาะทางพุ่งสูงขึ้นอย่างก้าวกระโดด ทั้งแผ่นรองชิป, หน่...