Joget DX 8 Stable Released
The stable release for Joget DX 8 is now available, with a focus on UX and Governance.
ในบทเรียนนี้เราจะทำตาม guideline for developing a plugin เพื่อพัฒนาปลั๊กอิน JDBC Form Load Binder ของเรา โปรดอ้างอิงบทช่วยสอนนี้ วิธีการพัฒนา Bean Shell Hash Variable และปลั๊กอินที่เกี่ยวข้องกับ JDBC วิธีการพัฒนา JDBC Options Binder เพื่อรายละเอียดเพิ่มเติม
เพื่อวัตถุประสงค์ในการรวมเราต้องการโหลดข้อมูลฟอร์มของเราจากตารางฐานข้อมูลอื่นแทนที่จะเป็นตารางข้อมูล Joget
Joget Workflow ได้จัดทำปลั๊กอินที่เรียกว่า Form Load Binder Plugin. เราสามารถอ้างอิงถึงการเชื่อมต่อเพื่อสนับสนุนในการพัฒนาปลั๊กอิน JDBC และ กำหนดค่า query เพื่อโหลดข้อมูลในแบบฟอร์ม
เพื่อการพัฒนาปลั๊กอิน JDBC Load binder, เราจะต้องมีการตั้งค่าการเชื่อมต่อ JDBC และ query ที่กำหนดเองเพื่อเติมข้อมูลแบบฟอร์มตาม primary key หรือ foreign key (เพื่อ Grid).
query ควรจะสนับสนุน syntax เพื่อการอ้างอิงถึง primary key (เพื่อ Form/Section) หรือ foreign key (เพื่อ Grid element)
ตัวอย่าง:
คอลัมน์ที่ดึงข้อมูลทั้งหมดจะถูกแมปอัตโนมัติกับฟิลด์ที่มีชื่อคอลัมน์เท่ากับฟิลด์ ID
เราสามารถอ้างถึงการดำเนินการของอื่น ๆ ที่มีอยู่ Form Load Binder plugins. แหล่งข้อมูลเริ่มต้นของ Joget สามารถเรียกดูได้ AppUtil.getApplicationContext().getBean("setupDataSource").
เราจำเป็นต้องให้ซอร์สโค้ด Joget Workflow ของเราพร้อมและสร้างโดยทำตาม this guideline.
บทช่วยสอนต่อไปนี้จัดทำขึ้นด้วย Macbook Pro และ Joget Source Code version 5.0.0. โปรดอ้างอิงถึง แนวทางสำหรับการพัฒนาปลั๊กอิน สำหรับคำสั่งแพลตฟอร์มอื่น ๆ
สมมติว่าไดเรกทอรีโฟลเดอร์ของเรามีดังนี้
- Home - joget - plugins - jw-community -5.0.0
ไดเรกทอรี "ปลั๊กอิน" คือโฟลเดอร์ที่เราจะสร้างและจัดเก็บปลั๊กอินทั้งหมดของเราและไดเรกทอรี "jw-community" เป็นที่เก็บซอร์สโค้ด Joget Workflow
เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างโครงการ maven ในไดเรกทอรี "ปลั๊กอิน"
cd joget/plugins/ ~/joget/jw-community/5.0.0/wflow-plugin-archetype/create-plugin.sh org.joget.tutorial jdbc_load_binder 5.0.0
จากนั้น the shell script จะขอให้เราป้อนปลั๊กอินสำหรับรุ่นของคุณและขอให้เรายืนยันก่อนสร้างโครงการ maven
Define value for property 'version': 1.0-SNAPSHOT: : 5.0.0 [INFO] Using property: package = org.joget.tutorial Confirm properties configuration: groupId: org.joget.tutorial artifactId: jdbc_load_binder version: 5.0.0 package: org.joget.tutorial Y: : y
เราควรได้รับข้อความ "BUILD SUCCESS" ที่ปรากฏในเครื่องของเราและโฟลเดอร์ "jdbc_load_binder" ที่สร้างในโฟลเดอร์ "ปลั๊กอิน"
เปิดโครงการ maven ด้วย IDE ที่คุณโปรดปราน เราแนะนำให้ใช้ NetBeans.
สร้างคลาส "JdbcLoadBinder" ภายใต้ "org.joget.tutorial" package. จากนั้น extend the class ด้วย org.joget.apps.form.model.FormBinder abstract class.
เพื่อให้มันทำงานเป็น Form Load Binder, เราจำเป็นจะต้องใช้อินเตอร์เฟซ org.joget.apps.form.model.FormLoadBinder. จากนั้นต้องใช้อินเตอร์เฟซ org.joget.apps.form.model.FormLoadElementBinder เพื่อให้ปลั๊กอินนี้แสดงเป็นตัวเลือกในกล่องเลือกโหลด binder และใช้ org.joget.apps.form.model.FormLoadMultiRowElementBinder. อินเตอร์เฟสเพื่อแสดงรายการภายใต้ select box ของ grid element.
โปรดอ้างอิงถึง Form Load Binder Plugin.
เช่นเคยเราต้องใช้ abstract methods ทั้งหมด. เราจะใช้ AppPluginUtil.getMessage method เพื่อสนับสนุน i18n และใช้ตัวแปรคงที่ MESSAGE_PATH เพื่อ message resource bundle directory.
จากนั้นเราต้องทำ UI สำหรับผู้ใช้ผู้ดูแลระบบเพื่อให้อินพุตสำหรับปลั๊กอินของเรา. ใน getPropertyOptions method, เราได้ระบุ ตัวเลือกคุณสมบัติปลั๊กอิน ของเราไว้ที่ "/properties/jdbcLoadBinder.json". ให้เราสร้าง directory "resources/properties" ภายใต้ "jdbc_load_binder/src/main" directory. หลังจากสร้าง directory, เราจะพบไฟล์ชื่อ "jdbcLoadBinder.json" ในโฟลเดอร์ "properties"
ในไฟล์ตัวเลือกคุณสมบัติ เราจะต้องเลือกดังต่อไปนี้ โปรดทราบว่าเราสามารถใช้ syntax "@@message.key@@" ในการสนับสนุน i18n ตัวเลือกคุรสมบัติของเราได้
[{ title : '@@form.jdbcLoadBinder.config@@', properties : [{ name : 'jdbcDatasource', label : '@@form.jdbcLoadBinder.datasource@@', type : 'selectbox', options : [{ value : 'custom', label : '@@form.jdbcLoadBinder.customDatasource@@' },{ value : 'default', label : '@@form.jdbcLoadBinder.defaultDatasource@@' }], value : 'default' },{ name : 'jdbcDriver', label : '@@form.jdbcLoadBinder.driver@@', description : '@@form.jdbcLoadBinder.driver.desc@@', type : 'textfield', value : 'com.mysql.jdbc.Driver', control_field: 'jdbcDatasource', control_value: 'custom', control_use_regex: 'false', required : 'true' },{ name : 'jdbcUrl', label : '@@form.jdbcLoadBinder.url@@', type : 'textfield', value : 'jdbc:mysql://localhost/jwdb?characterEncoding=UTF8', control_field: 'jdbcDatasource', control_value: 'custom', control_use_regex: 'false', required : 'true' },{ name : 'jdbcUser', label : '@@form.jdbcLoadBinder.username@@', type : 'textfield', control_field: 'jdbcDatasource', control_value: 'custom', control_use_regex: 'false', value : 'root', required : 'true' },{ name : 'jdbcPassword', label : '@@form.jdbcLoadBinder.password@@', type : 'password', control_field: 'jdbcDatasource', control_value: 'custom', control_use_regex: 'false', value : '' },{ name : 'sql', label : '@@form.jdbcLoadBinder.sql@@', description : '@@form.jdbcLoadBinder.sql.desc@@', type : 'codeeditor', mode : 'sql', required : 'true' }], buttons : [{ name : 'testConnection', label : '@@form.jdbcLoadBinder.testConnection@@', ajax_url : '[CONTEXT_PATH]/web/json/app[APP_PATH]/plugin/org.joget.tutorial.JdbcLoadBinder/service?action=testConnection', fields : ['jdbcDriver', 'jdbcUrl', 'jdbcUser', 'jdbcPassword'], control_field: 'jdbcDatasource', control_value: 'custom', control_use_regex: 'false' }] }]
เหมือนกับ JDBC Options Binder, เราจะต้องเพิ่มปุ่มเพื่อทำการทดสอบการเชื่อมต่อกับ JDBC. โปรดอ้างอิงถึง วิธีการพัฒนา JDBC Options Binder บนการใช้งาน Web Service Plugin
มื่อเราทำตัวเลือกคุณสมบัติเพื่อรวบรวมอินพุตและบริการเว็บเพื่อทดสอบการเชื่อมต่อ เราสามารถทำงานกับวิธีการหลักของปลั๊กอินซึ่งเป็นวิธีการโหลด
public FormRowSet load(Element element, String primaryKey, FormData formData) { FormRowSet rows = new FormRowSet(); rows.setMultiRow(true); //Check the sql. If require primary key and primary key is null, return empty result. String sql = getPropertyString("sql"); if ((primaryKey == null || primaryKey.isEmpty()) && sql.contains("?")) { return rows; } Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try { DataSource ds = createDataSource(); con = ds.getConnection(); pstmt = con.prepareStatement(sql); //set query parameters if (sql.contains("?") && primaryKey != null && !primaryKey.isEmpty()) { pstmt.setObject(1, primaryKey); } rs = pstmt.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columnsNumber = rsmd.getColumnCount(); // Set retrieved result to Form Row Set while (rs.next()) { FormRow row = new FormRow(); //get the name of each column as field id for (int i = 1; i <= columnsNumber; i++) { String name = rsmd.getColumnName(i); String value = rs.getString(name); if (FormUtil.PROPERTY_ID.equals(name)) { row.setId(value); } else { row.setProperty(name, (value != null)?value:""); } } rows.add(row); } } catch (Exception e) { LogUtil.error(getClassName(), e, ""); } finally { try { if (rs != null) { rs.close(); } if (pstmt != null) { pstmt.close(); } if (con != null) { con.close(); } } catch (Exception e) { LogUtil.error(getClassName(), e, ""); } } return rows; } /** * To creates data source based on setting * @return * @throws Exception */ protected DataSource createDataSource() throws Exception { DataSource ds = null; String datasource = getPropertyString("jdbcDatasource"); if ("default".equals(datasource)) { // use current datasource ds = (DataSource)AppUtil.getApplicationContext().getBean("setupDataSource"); } else { // use custom datasource Properties dsProps = new Properties(); dsProps.put("driverClassName", getPropertyString("jdbcDriver")); dsProps.put("url", getPropertyString("jdbcUrl")); dsProps.put("username", getPropertyString("jdbcUser")); dsProps.put("password", getPropertyString("jdbcPassword")); ds = BasicDataSourceFactory.createDataSource(dsProps); } return ds; }
ปลั๊กอินของเราใช้ dbcp, javax.servlet.http.HttpServletRequest และคลาส javax.servlet.http.HttpServletResponse. ดังนั้นเราต้องเพิ่ม jsp-api และ commons-dbcp library ในไฟล์ POM ของเรา
<!-- Change plugin specific dependencies here --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.3</version> </dependency> <!-- End change plugin specific dependencies here -->
เราใช้ i18n message key ในการ getLabel และ getDescription method. และเรายังใช้ i18n message key ใน properties options definition ของเราด้วยเหมือนกัน ดังนั้นเราต้องสร้างไฟล์ message resource bundle properties สำหรับปลั๊กอินของเรา
สร้าง directory "resources/messages" ภายใต้ "jdbc_load_binder/src/main" directory. จากนั้นสร้างไฟล์ "JdbcLoadBinder.properties" ในโฟลเดอร์. ในไฟล์คุณสมบัติเราต้องเพิ่ม message keys และ label ดังต่อไปนี้
org.joget.tutorial.JdbcLoadBinder.pluginLabel=JDBC Binder org.joget.tutorial.JdbcLoadBinder.pluginDesc=Used to load form data using JDBC form.jdbcLoadBinder.config=Configure JDBC Binder form.jdbcLoadBinder.datasource=Datasource form.jdbcLoadBinder.customDatasource=Custom Datasource form.jdbcLoadBinder.defaultDatasource=Default Datasource form.jdbcLoadBinder.driver=Custom JDBC Driver form.jdbcLoadBinder.driver.desc=Eg. com.mysql.jdbc.Driver (MySQL), oracle.jdbc.driver.OracleDriver (Oracle), com.microsoft.sqlserver.jdbc.SQLServerDriver (Microsoft SQL Server) form.jdbcLoadBinder.url=Custom JDBC URL form.jdbcLoadBinder.username=Custom JDBC Username form.jdbcLoadBinder.password=Custom JDBC Password form.jdbcLoadBinder.sql=SQL SELECT Query form.jdbcLoadBinder.sql.desc=Use question mark (?) in your query to represent primary key or foreign key form.jdbcLoadBinder.testConnection=Test Connection form.jdbcLoadBinder.connectionOk=Database connected form.jdbcLoadBinder.connectionFail=Not able to establish connection.
public void start(BundleContext context) { registrationList = new ArrayList<ServiceRegistration>(); //Register plugin here registrationList.add(context.registerService(JdbcLoadBinder.class.getName(), new JdbcLoadBinder(), null)); }
สร้างปลั๊กอินของเรา เมื่อสร้างสำเร็จเราจะพบว่าไฟล์ "jdbc_load_binder-5.0.0.jar" อยู่ภายใต้ "jdbc_load_binder/target" directory.
จากนั้นให้เราอัพโหลดปลั๊กอิน Manage Plugins. หลังจากอัพโหลดไฟล์ jar ให้ตรวจสอบอีกครั้งว่าปลั๊กอินอัพโหลดถูกต้อง
ให้สร้างแบบฟอร์มเพื่อโหลด "firstName", "lastName" และ "email" จากตาราง dir_user ตามชื่อผู้ใช้เพื่อทดสอบการโหลด
จากนั้นกำหนดค่า load binder ของฟอร์มเพื่อใช้ JDBC Binder และ query ต่อไปนี้
select * from dir_user where username = ?
ให้สร้าง userview และลากองค์ประกอบเมนูแบบฟอร์มเพื่อแสดงแบบฟอร์มของเรา จากนั้นเผยแพร่และทดสอบแบบฟอร์มของเราด้วยพารามิเตอร์ "id"
จากนั้นให้เพิ่มองค์ประกอบตารางและ query เพื่อทดสอบดังต่อไปนี้
select * from dir_group g join dir_user_group ug on ug.groupId = g.id where ug.userId = ?
ตรวจสอบผลลัพธ์ของเราอีกครั้ง
มันได้ผล! โปรดอย่าลืมทดสอบคุณสมบัติอื่น ๆ ของปลั๊กอินด้วย
คูรสามารถดาวน์โหลหด source code จาก jdbc_load_binder_src.zip.
หากต้องการดาวน์โหลด jar ปลั๊กอินที่พร้อมใช้งานโปรดค้นหาได้ที่ http://marketplace.joget.org/.