我個人是較推崇 JPA的,不過有些情況下,或是架構設計上,會需要純SQL的方式進行,但是像教科書介紹的方式進行,在實務上很難看到,太難用、程式太醜、修改太複雜等等都是要克服的問題,不可能期望所有開發者都是同一高等級的,JDBCTemplate某程度簡化了使用SQL的繁雜度,若是需要大量的純SQL時,JDBCTemplate絕對是首選,也會介紹JDBCTemplate如增刪修查方式、Connection Pool設定及帳密加密的方式等等。
pom.xml 說明
Github code(louisz.springboot.example5)
參考連結:
http://blog.didispace.com/springbootdata1/
https://www.ricston.com/blog/encrypting-properties-in-spring-boot-with-jasypt-spring-boot/
https://github.com/ulisesbocchio/jasypt-spring-boot
- 預先準備項目:請先下載並安裝 PostgreSQL,並建立一個DB(louisz)及Table(users),DDL如下:。
CREATE DATABASE louisz WITH OWNER = louisz ENCODING = 'UTF8' LC_COLLATE = 'Chinese (Traditional)_Taiwan.950' LC_CTYPE = 'Chinese (Traditional)_Taiwan.950' TABLESPACE = pg_default CONNECTION LIMIT = -1; CREATE TABLE public.users ( id integer NOT NULL, name character varying COLLATE pg_catalog."default", email character varying COLLATE pg_catalog."default", mobilenumber character varying COLLATE pg_catalog."default", CONSTRAINT user_pkey PRIMARY KEY (id) ) WITH ( OIDS = FALSE ) TABLESPACE pg_default;
學習目的:使用自訂屬性設定檔、屬性一些進階的使用。
學習時數:3.5hr
教學影片:
spring-boot-starter-web:配置 Web Project所需的函式庫。 spring-boot-starter-test:配置 unit or mock test 所需的函式庫。 spring-boot-starter-actuator:配置監控spring boot所需的函式庫,後續spring cloud會使用到,所以一開就導入。 spring-boot-starter-jdbc:配置使用jdbc所需的函式庫。 postgresql:配置postgresql連接Driver所需的函式庫。 jasypt-spring-boot-starter:加解密所需的函式庫。example5.properties JDBC設定檔說明
#DB設定資訊 #PostgreSQL JDBC URL spring.datasource.url= jdbc:postgresql://localhost:5432/louisz #DB使用者帳號 spring.datasource.username=louisz #DB使用者密碼已經加過密的,請使用自己產生的 spring.datasource.password=ENC(xOSgfOF9jzB8jpYSB1O+4jEobziG16pA)產生亂碼值的指令
java -cp ~/.m2/repository/org/jasypt/jasypt/1.9.2/jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="contactspassword" password=supersecretz algorithm=PBEWithMD5AndDES input:需要加密的資訊 password:壓密KEY,可以自己定義 結果應該像是這樣,OUTPUT就是被加密過後的值 ----ENVIRONMENT----------------- Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 24.45-b08 ----ARGUMENTS------------------- algorithm: PBEWithMD5AndDES input: contactspassword password: supersecretz ----OUTPUT---------------------- XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=
程式碼說明
- Example5.java
package louisz.springboot.example5;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;
/**
* Louisz Spring boot introduce ex.5
*
*/
@SpringBootApplication
@PropertySource(name = "EncryptedProperties", value = "classpath:example5.properties")//針對需加解密的設定檔檔名及位置
public class Example5 {
/**
* 程式執行起點
*
* @param args
*/
public static void main(String[] args) {
SpringApplication.run(Example5.class, args);
}
}
- UserService.java
package louisz.springboot.example5; import java.util.List; import louisz.springboot.example3.User; public interface UserService { /** * 新增一筆User資料 * * @param User */ void merge(User user); /** * 刪除傳入相同姓名的資料 * * @param name */ void deleteByName(String name); /** * 查詢所有資料,並回傳List物件 */ ListlistAll(); /** * 查詢特定id資料,並回該User Object */ User findById(Long id); /** * 删除所有用户 */ void deleteAllUsers(); /** * 依據傳入的id,依據傳入的User物件,更新資料表中相同id的資料 * * @param id * @param user */ void updateUser(Long id, User user); }
- UserServiceImpl.java
package louisz.springboot.example5; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import louisz.springboot.example3.User; @Service public class UserServiceImpl implements UserService { @Autowired private JdbcTemplate jdbcTemplate; @Override public void merge(User user) { jdbcTemplate.update("insert into users(id,name,email,mobilenumber) values(?, ?,?,?)", user.getId(), user.getName(), user.getEmail(), user.getMobilenumber()); } @Override public void deleteByName(String name) { jdbcTemplate.update("delete from users where name = ?", name); } @Override public ListlistAll() { return jdbcTemplate.query("select * from users", new BeanPropertyRowMapper(User.class)); } @Override public void deleteAllUsers() { jdbcTemplate.update("delete from users "); } @Override public void updateUser(Long id, User user) { jdbcTemplate.update("update users set name = ? where id = ?", user.getName(), id); } @Override public User findById(Long id) { return (User)jdbcTemplate.queryForObject( "select * from users where id = ?", new Object[] { id }, new BeanPropertyRowMapper(User.class)); } }
- TestUserServiceImpl.java
package louisz.springboot.example5; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.test.context.junit4.SpringRunner; import louisz.springboot.example3.User; //spring boot 1.4以後的方式 @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class TestUserServiceImpl { @Autowired private UserService userSerivce;// 注入UserService // interface,實際instance會呼叫UserServiceImpl物件 @Before public void setUp() { // 先清除所有資料 userSerivce.deleteAllUsers(); } @Test public void test() throws Exception { /* * 進行單元測試,先規劃相關情境 */ User user1 = new User(); user1.setId(1l); user1.setEmail("louisz6ster@gmail.com"); user1.setName("user1"); user1.setMobilenumber("0912345678"); User user2 = new User(); user2.setId(2l); user2.setEmail("louisz6ster@gmail.com"); user2.setName("user2"); user2.setMobilenumber("0912345678"); User user3 = new User(); user3.setId(3l); user3.setEmail("louisz6ster@gmail.com"); user3.setName("user3"); user3.setMobilenumber("0912345678"); // 新增三個User資料 userSerivce.merge(user1); userSerivce.merge(user2); userSerivce.merge(user3); // 查詢全部資料筆數是否吻合,確認新增成功 Assert.assertEquals(3, userSerivce.listAll().size()); // 刪除資料 userSerivce.deleteByName("user1"); userSerivce.deleteByName("user2"); // 查詢全部資料筆數是否吻合,確認刪除成功 Assert.assertEquals(1, userSerivce.listAll().size()); //更新User3姓名跟email user3.setName("Jessie"); userSerivce.updateUser(user3.getId(), user3); //查詢資料表中User3的資料是否更新成功 User newUser3 = userSerivce.findById(user3.getId()); Assert.assertEquals(user3.getName(), newUser3.getName()); } }單元測試看結果,執行時請加上-Djasypt.encryptor.password=supersecretz
Github code(louisz.springboot.example5)
參考連結:
http://blog.didispace.com/springbootdata1/
https://www.ricston.com/blog/encrypting-properties-in-spring-boot-with-jasypt-spring-boot/
https://github.com/ulisesbocchio/jasypt-spring-boot
留言
張貼留言