Total Pageviews

2020/03/08

[Java] [Spring] [JDBC] [Oracle] How to call stored procedure - example 1

Assume I have a stored procedure as bellows:
create or replace PACKAGE PACKAGE1 AS 
     PROCEDURE TEST_HELLO 
    (
      I_NAME IN VARCHAR2,
      outParam1 OUT VARCHAR2,
      o_return_code OUT INT
    );
END PACKAGE1;

create or replace PACKAGE BODY PACKAGE1
AS
   PROCEDURE TEST_HELLO 
    (
      I_NAME IN VARCHAR2,
      outParam1 OUT VARCHAR2,
      o_return_code OUT INT
    ) AS 
    BEGIN
      outParam1 := 'Hello World! ' || I_NAME;
      DBMS_OUTPUT.put_line (outParam1);
      o_return_code := 0;
    END TEST_HELLO;
END PACKAGE1;


Step1. Create a custom repository interface:
package com.example.jpa.repository.custom;

import java.util.Map;

public interface EmployeeRepositoryCustom {
    Map<String, Object> sayHello(String name);
}


Step2. Create a custom implementation class:
package com.example.jpa.repository.impl;

import com.example.jpa.entity.Employee;
import com.example.jpa.repository.custom.EmployeeRepositoryCustom;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;

import java.util.Map;

@Slf4j
public class EmployeeRepositoryImpl implements EmployeeRepositoryCustom {

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;
    
    @Override
    public Map<String, Object> sayHello(String name) {
        SimpleJdbcCall jdbcCall
                = new SimpleJdbcCall(jdbcTemplate.getJdbcTemplate().getDataSource())
                .withCatalogName("PACKAGE1")
                .withProcedureName("TEST_HELLO");

        Map<String, Object> output = jdbcCall.execute(name);
        output.entrySet().forEach(entry -> log.debug("key = {}, value = {}", entry.getKey(), entry.getValue()));

        return output;
    }
}


Step3. Create an repository interface
package com.example.jpa.repository;

import com.example.jpa.entity.Employee;
import com.example.jpa.repository.custom.EmployeeRepositoryCustom;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface EmployeeRepository extends CrudRepository<Employee, String>, EmployeeRepositoryCustom {
}


Step4. Create a test case:
package com.example.jpa;

import com.example.jpa.entity.Employee;
import com.example.jpa.repository.EmployeeRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@SpringBootTest
@Slf4j
public class TestEmployeeRepository {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Test
    public void testSayHello() {
        String name = "Albert Kuo";
        Map<String, Object> output = employeeRepository.sayHello(name);

        String message = (String) output.get("OUTPARAM1");
        int returnCode = ((BigDecimal) output.get("O_RETURN_CODE")).intValue();
        log.debug("message = {}, returnCode = {}", message, returnCode);

        Assert.assertEquals(0, returnCode);
        Assert.assertEquals("Hello World! " + name, message);
    }

}


Step5. Check result:
[           main] c.e.j.r.impl.EmployeeRepositoryImpl      : key = OUTPARAM1, value = Hello World! Albert Kuo
[           main] c.e.j.r.impl.EmployeeRepositoryImpl      : key = O_RETURN_CODE, value = 0
[           main] com.example.jpa.TestEmployeeRepository   : message = Hello World! Albert Kuo, returnCode = 0


2020/03/07

[Java] [IntelliJ] [JPA] Cannot resolve table 'xxxx'

Problem
As I create entity class in my JPA project in IntelliJ, it complained cannot resolve table 'Product' as following:


How-To
Step1. Configure database connection





Step2. Assign Datasource






Step3. Check result



2020/03/06

[Java] [IntelliJ] Generate Entity Class from Database

1. Created test project using Spring Boot

2. Right clicked the project and “Add Framework Support” and select “JavaEE Persistence(2.0)” and chose some settings and clicked "OK"


3. View  => Tool Windows => Database, and connected to my local database (i.e. Oracle). 





4. View  => Tool Windows => Persistence, right clicked project and go to “Generated Persistence Mapping” and go to click the “By Database Schema”.



5. Select table and generate entity class(es).






2020/03/05

[Java] [Freemarker] How to ignore certain white-space

Problem
Here is my original ftl file:
<#if employees??>
<#list employees as e>
    ${e_index + 1}. ${e.name?right_pad(10)} - 
    <#switch e.gender>
        <#case "M">男<#break>
        <#case "F">女<#break>
        <#default>No matching gender found.
    </#switch>
</#list>
<#else>
No data found.
</#if>

But it had unexpected outcome:
    1. Albert     -
男    2. Mandy      -
女    3. Mia        -
女    4. Eric       -
男


How-To
Making use of #rt to ignore all railing white-space and add one enter at the end of switch. The updated ftl file looks like:
<#if employees??>
<#list employees as e>
    <#-- using <#rt> (for right trim) to ignore all 
         trailing white-space in this line. -->
    ${e_index + 1}. ${e.name?right_pad(10)} - <#rt>
    <#switch e.gender>
        <#case "M">男<#break>
        <#case "F">女<#break>
        <#default>No matching gender found.
    </#switch>
    <#-- 多按一個 enter 才會換行 -->

</#list>
<#else>
No data found.
</#if>



Check the result:
    1. Albert     - 男
    2. Mandy      - 女
    3. Mia        - 女
    4. Eric       - 男



Reference
[1] https://freemarker.apache.org/docs/ref_directive_t.html

2020/03/04

[Java] [Freemarker] Using macro to reuse common template fragments

When you find yourself copy-pasting common parts between templates a lot, you should probably use macros.

Assume I create a utils.ftl in /resources/ftl/common as bellows:
<#macro myPage>
    <html>
    <head>
        <title>${title}</title>
    </head>
    <body>
    <h1>${title}</h1>

    <#-- This processes the enclosed content:  -->
    <#nested>

    </body>
    </html>
</#macro>

<#macro otherExample p1 p2>
    <p>The parameters were: ${p1}, ${p2}</p>
</#macro>

helloWorld.ftl will looks like:
<#-- import common template fragments -->
<#import "common/utils.ftl" as u>

<@u.myPage>
    <p>${example.name} by ${example.developer}</p>
    <#-- Just another example of using a macro: -->
    <@u.otherExample p1="Albert" p2="Mandy" />

    <#if systems??>
    <ul>
        <#list systems as system>
            <li>${system_index + 1}. ${system.name} from ${system.developer}</li>
        </#list>
    </ul>
    <#else>
    No data found!
    </#if>

</@u.myPage>

Test case:
package com.esb.batch;

import com.esb.batch.exception.FtlException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.Builder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class FtlTest {

    private Configuration cfg;

    @Before
    public void init() {
        cfg = new Configuration();
        // 設定到 classpath 讀取 ftl file
        cfg.setClassForTemplateLoading(this.getClass(), "/");
    }

    @Test
    public void testHelloWorld() {
        try (Writer file = new FileWriter(new File("C:/ftl_helloWorld.html"));) {
            Template template = cfg.getTemplate("ftl/helloWorld.ftl");

            Map<String, Object> data = new HashMap<>();
            data.put("title", "Freemarker Example");
            data.put("example", ValueExampleObject.builder().name("Java Object").developer("Albert").build());

            List<ValueExampleObject> systems = new ArrayList<>();
            systems.add(ValueExampleObject.builder().name("Android").developer("Google").build());
            systems.add(ValueExampleObject.builder().name("iOS").developer("Apple").build());
            systems.add(ValueExampleObject.builder().name("Ubuntu").developer("Canonical").build());
            systems.add(ValueExampleObject.builder().name("Windows").developer("Microsoft").build());
            data.put("systems", systems);

            template.process(data, file);
        } catch (IOException | TemplateException e) {
            throw new FtlException("fail to generate file from ftl file : " + e.getMessage(), e);
        }
    }

    @Getter
    @Builder
    public static class ValueExampleObject {
        private String name;
        private String developer;
    }

}

Check the result:
<html>

<head>
    <title>Freemarker Example</title>
</head>

<body>
    <h1>Freemarker Example</h1>

    <p>Java Object by Albert</p>
    <p>The parameters were: Albert, Mandy</p>

    <ul>
        <li>1. Android from Google</li>
        <li>2. iOS from Apple</li>
        <li>3. Ubuntu from Canonical</li>
        <li>4. Windows from Microsoft</li>
    </ul>

</body>

</html>

2020/03/03

[Oracle] How to export package and package body into sql file?

Step1. Make sure you select both (package and package body), and click export


Step2. Assign export destination and click next


Step3. Click Complete


Step4. Check result








2020/03/02

[閱讀筆記] 正義:一場思辨之旅 (3/3)

  1. 分配正義的四種不同理論
分配正義理論
說明
John Rawls 認為
封建或種姓制度
基於出生背景的固定階級
受到出生背景、社經優勢或先天才華與能力等偶然因素
自由放任主義制度
帶有形式機會平等的自由市場
功績主義制度
帶有公平機會平等的自由市場
平等主義制度
John Rawls 的差異原則
避免所得與財富分配奠基在這些偶然因素上


  1. 成功人士經常忽略自己成功時的偶然面向。我們許多人都很幸遇至少在若干程度上擁有這個社會恰好重視的特質。在資本主義社會裡,擁有創業衝進對你會有所幫助;在官僚社會裡,能與上司和睦相處對你會有所幫助;在大眾民主社會裡,如果你長得上相,善於說出令人難忘的簡短膚淺話語,也會有所幫助;在好興訟的社會中,就讀法學院可能有所幫助,擁有邏輯與推理技巧能夠讓你在法學院入學考試中獲得高分。但是,社會上重視哪些特質,並非是我們造成的結果
  2. 自然分配沒有公不公正的問題;人在社會當中以特定地位出聲也沒有不公正的問題,這些純粹只是自然事實而已。公正與不公正乃是在於制度因應這事實的方式。John Rawls 提議我們因應這些事實的方式,就是同意「分擔彼此的命運」,並且「唯有在有助於公共利益的情況下,才任由自己從自然與社會處境的偶然事實中得利」
  3. 原住民在聯考可以獲得加分是否公平?多元性如果有助於共善,而且沒有人因為仇恨或蔑視而遭到歧視,那麼種族偏袒就沒有侵害任何人的權利。
  1. John Rawls 曾提醒我們:「沒有人應當永有優於別人的先天能力,或是在社會中或得比較好的起跑點。」我們的社會恰好重視我們擁有的長處,也不是我們造成的結果,這種現象只是展現我們的幸運,不是我們的德行。
  2. 雖然大專教育有幫助學生邁向錦繡前程的優點,但其主要目的不是商業性的。因此,若因為父母捐錢幫學校蓋圖書館,子女就獲得免試入學的資格,就是把教育當成單純的消費商品販售,這就是一種墮落。
  1. 人對於榮譽和德行各有不同看法。不論是大學、企業、軍隊、職業,或是整體的政治社群,各種社會制度的適當使命都備受爭議與質疑。所以,為正義和權利尋求一種不受這些爭議影響的基礎,也成了相當誘人的事情。大部分的現代政治哲學正式希望達成此目的。
  2. 亞里斯多德的政治哲學有兩項核心觀念:
兩項核心觀念
說明
正義具有目的性
要界定權力,就必須找出被提出來討論的社會慣例所帶有的目的性(其目標或不可或缺的本質
正義具有榮譽性
推理或爭論,也就是一項慣例的目的,至少有一部分在於推理或爭論這項慣例應該表彰和獎賞哪些德行


  1. 現代的正義理論試圖把公平與權利的問題從關於榮譽、德行與道德應得的爭論當中區分開來。亞里斯多德不認為正義能夠具有這樣的中立性,他認為有關正義的辯論無可避免地必須涉及榮譽、德行,以及美好人生的本質。在他眼中,正義就是給予人們應該擁有的東西,讓每個人得所應得。亞里斯多德對正義的看法
  1. 關於正義與權力的辯論,經常無可避免地必須辯論社會制度的目的、其所分配的財貨,以及其所表彰與獎賞的德行。雖然我們盡量讓法律在這類問題上保持中立,可是若要決定何謂公正,就不能不爭論美好人生的本質。
  2. 美國是否要為黑奴的歷史道歉,日本是否要為慰安婦的歷史道歉?
  1. 在亞里斯多德眼中,政治的目的不僅在於促使經濟交流更加便利和提供共同防衛,也在培養良好人格和公民。因此,關於正義的爭論,必然會是關於美好人生的爭論。在我們能夠探究理想政治制度的本質前,我們必須先決定最值得嚮往的生活方式所具有的本質。只要沒有釐清這點,理想政治制度的本質必定也模糊不清。
  1. 自由主義對「義務」的定義:先天義務、自願義務與團結義務
  1. 在同性婚姻的辯論中,真正的重點不是選擇自由,而是同性結合是否應當受到社群的表彰與承認,那樣的結合是否能夠實現婚姻這種社會制度的目的。以亞里斯多德的觀點來看,是官職位與榮譽的公正分配,重點是社會認可。
  2. 三種看待正義的方式

三種看待正義的方式
說明
❶ 追求效用或福利最大化
  • 功利主義:追求最大多數人的最大幸福
  • 缺陷:
    • 使得正義與權力淪為單純的計算,而不是一種原則
    • 試圖把所有的人類財貨轉換成單一一種價值衡量標準,不理會各種財貨之間的質性差異
❷ 尊重選擇自由
  • 自由放任主義觀點:也許是人在自由市場裡做出的實際選擇
  • 自由平等注意觀點:人在最初平等立場中,想必會做出的假設性選擇
❸ 涉及培養德行與思辨共善
  • 若要達成公正的社會,不可能單純藉著追求效用最大化或確保選擇自由。
  • 要達成公正的社會,我們必須共同推理美好人生的意義,並創造一套公共文化,能夠接納不免會出現的歧見。
  • 有關正義的問題都脫離不了對於榮譽和德行,以及自豪與認可的不同概念。正義不只是分配事物的正確方式,也是關於評價事物的正確方式