Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

w ໊͓લɿͳ͔΍·ͻΖʢͤͪʣ 
 5XJUUFS͸ʮͤͪʯ w ͓͠͝ͱɿ౎಺๭8FCαʔϏε w झຯɿήʔϜͱ͓ञͱࣗసं w ӈͷࣸਅ͸(8ʹ૸ͬͨඒϲݪ ࣗݾ঺հ

Slide 3

Slide 3 text

͜ͷΑ͏ͳ೰Έ͋Γ·ͤΜ͔ʁ w ΞϓϦέʔγϣϯΛ࣮ߦ͢Δ؀ڥߏஙͷେྔͷखॱ͕͋Δ w ྫ͑͹σʔλϕʔεͷΠϯετʔϧ w ΠϯετʔϧΛ׬ྃޙɺςετΛ࣮ߦ͢Δલʹඞཁͳ࡞ۀ w ςετσʔλͷσʔλͷ౤ೖ w ࠶౓ςετΛ࣮ߦ͢Δ৔߹͸ݩͷঢ়ଶʹ໭͢ w ࣗಈԽ͸ͦͷ͏͍ͪͨ͠Ͱ͢Ͷɾɾɾʢԕ͍໨ʣ

Slide 4

Slide 4 text

͜ͷΑ͏ͳ೰Έ͋Γ·ͤΜ͔ʁ w ෳࡶͳࣄલ४උΛࣗಈԽ͢ΔͨΊɺϏϧυ৬ਓ͕εΫϦϓτΛ࡞੒ w ؤுͬͯߏஙͯ͠΋$*Ͱෆఆظʹ͚͜Δ w ݪҼ͸$*؀ڥͰ͔͠ൃੜ͠ͳ͍ṖͷΤϥʔ w ͦͷ͏ͪΤϥʔʹͳͬͯ΋୭΋ؾʹ͠ͳ͍ɾɾɾ w ৬ਓ͸طʹୀ৬Ͱϝϯςφϯε΋Ͱ͖ͳ͍ɾɾɾ

Slide 5

Slide 5 text

͜ͷΑ͏ͳ೰Έ͋Γ·ͤΜ͔ʁ w ۤ࿑ͯࣗ͠ಈԽ͚ͨ͠ͲσʔλϕʔεΛ࢖ͬͨςετ͕஗࣮ͯ͘ߦʹ਺े ෼ɾɾɾ w ͜͏ͳͬͨΒςετΛฒྻͰ࣮ߦ͢Δ͔͠ͳ͍ʂ w σʔλͷߋ৽λΠϛϯάͰςετ͕ࣦഊɾɾɾ w σʔλϕʔεΛ૿΍ͦ͏ʹ΋ϙʔτ͕ॏෳɾɾɾ

Slide 6

Slide 6 text

5FTUDPOUBJOFSTͰղܾͰ͖Δ͔΋ʁ w 5FTUDPOUBJOFST͸͜Μͳ೰ΈΛղܾͯ͘͠Ε·͢ w ηοτΞοϓ͕ͭΒ͍ˠ+BWBͱ%PDLFS͕Πϯετʔϧ͞Ε͍ͯΕ͹ 0,ʂ w खॱ͕ͭΒ͍ˠςετΫϥε͔Β࢖༻͢ΔίϯςφΛىಈɺޙย෇͚΋ ෆཁ w ฒྻ࣮ߦ͕ͭΒ͍ˠςετΫϥε͝ͱʹσʔλϕʔεΛ༻ҙʂϙʔτ໰୊ ΋؆୯ʹղܾ

Slide 7

Slide 7 text

ຊηογϣϯͷςʔϚ w 5FTUDPOUBJOFSTͷಋೖํ๏͔Β4QSJOH#PPU5FTUͰ࣮ߦ·ͰΛ͝঺հ͠·͢ w ςετର৅͸σʔλϕʔεʢ1PTUHSFTʣΛ࢖ͬͨ8FCΞϓϦέʔγϣϯͰ͢ w ຊεϥΠυͰ͸ιʔείʔυΛஅยతʹష͍ͬͯ·͕͢ɺ(JUIVCͰಈ͘΋ͷ Λެ։͠·͢

Slide 8

Slide 8 text

w 5FTUDPOUBJOFSTͱ͸ʁ w ίϯςφΛىಈ͠Α͏ w 4QSJOH#PPU5FTUͱͷ࿈ܞ ΞδΣϯμ

Slide 9

Slide 9 text

5FTUDPOUBJOFSTͱ͸ʁ

Slide 10

Slide 10 text

5FTUDPOUBJOFSTͱ͸ʁ w +6OJUςετ͔Βܰྔ͔ͭ࢖͍ࣺͯͷ%PDLFSίϯςφΛ࣮ߦ͢ΔϥΠϒϥϦ w ໊લؒҧ͑΍͍͢ͷͰ஫ҙ w 5FTU$POUBJOFSTʢ❌ɿ$͕େจࣈʣɺ5FTUDPOUBJOFSʢ❌ɿT͕ͳ͍ʣ w ͞·͟·ͳ044΍঎༻ϓϩμΫτͷςετͰར༻͞Ε͍ͯ·͢ w σʔλϕʔεΛར༻ͨ݁͠߹ςετʹ࠷ద w ଞʹ΋4FMFOJVNΛར༻ͨ͠6*ड͚ೖΕςετͰ΋࢖͑·͢

Slide 11

Slide 11 text

Կ͕͍͍ͷ͔ʁ w ίϯςφͷ؅ཧͷΈʹಛԽͨ͠ϥΠϒϥϦ w ఏڙ͢Δػೳ͕γϯϓϧͳͷͰಋೖʹ͔͔Δֶशίετ͕গͳ͍ w ެ͕ࣜఏڙ͢ΔϞδϡʔϧͰίϯςφ΋ѻ͍΍͘͢ͳ͍ͬͯ·͢ w Ϟδϡʔϧʹ͍ͭͯ͸ޙ΄Ͳղઆ͠·͢

Slide 12

Slide 12 text

ίϯςφΛىಈ͠Α͏

Slide 13

Slide 13 text

࣮ߦ४උ ඞཁ؀ڥ w %PDLFS🐳 w WҎ্ w 8JOEPXTͷαϙʔτ͸ϕετΤϑΥʔτ w +BWBͷόʔδϣϯʹ͍ͭͯ͸هࡌ͸͋Γ·ͤΜ͕ɺҎ্Ͱ͋Ε͹ಈ͘ͱࢥ͍ ·͢

Slide 14

Slide 14 text

࣮ߦ४උ ϓϩδΣΫτ࡞੒ w ࠓճ͸4QSJOHͷΞϓϦέʔγϣϯͷςετΛ࣮ߦ͢Δͷ͕ΰʔϧͳͷͰɺ 4QSJOH*OJUJBMJ[S͔ΒϓϩδΣΫτΛ࡞੒͠·͢ w 5FTUDPOUBJOFST͸4QSJOH*OJUJBMJ[Sʹొ࿥͞Ε͍ͯ·͢ w σʔλϕʔε͸1PTUHSF42-Λબ୒͠·͢

Slide 15

Slide 15 text

४උ ґଘੑͷ֬ೝ w ϓϩδΣΫτΛੜ੒͢ΔͱQPNYNMʹ5FTUDPOUBJOFSTͷґଘੑ͕ͭೖͬͯ ͍·͢ w ্͸+6OJUͱ૊Έ߹ΘͤΔϥΠϒϥϦɺԼ͸1PTUHSF42-ͷϞδϡʔϧΛఏ ڙ͢ΔϥΠϒϥϦͰ͢ org.testcontainers junit-jupiter test org.testcontainers postgresql test

Slide 16

Slide 16 text

ิ଍ Ϟδϡʔϧʹ͍ͭͯ w ͜͜·ͰԿճ͔ग़͖͍ͯͯΔʮϞδϡʔϧʯʹ͍ͭͯ؆୯ʹઆ໌͠·͢ w 5FTUDPOUBJOFST͸(FOFSJD$POUBJOFSͱ͍͏ίϯςφΛ࣮ߦ͢ΔͨΊͷڞ௨ తͳػೳΛ࣋ͭΫϥεΛఏڙ͠·͢ w (FOFSJD$POUBJOFSΛܧঝͯ͠ಛఆͷίϯςφʹಛԽͨ͠΋ͷΛϞδϡʔϧͱ ݺΜͰ͍·͢

Slide 17

Slide 17 text

ิ଍ ϞδϡʔϧʹͰ͖Δ͜ͱ w Ϟδϡʔϧ͸(FOFSJD$POUBJOFSͷઃఆ߲໨ʹ௥Ճͯ͠ɺ࣮ߦ͢Δίϯςφݻ ༗ͷઃఆΛఏڙ͠·͢ w 1PTUHSFTϞδϡʔϧͰ͋Ε͹σʔλϕʔεͷઃఆ͕௥Ճ͞Ε͍ͯ·͢ (FOFSJD$POUBJOFSͷઃఆ߲໨ 1PTUHSFTϞδϡʔϧͷ௥Ճઃఆ߲໨ ࣮ߦ͢ΔΠϝʔδ σʔλϕʔε໊ ެ։͢Δϙʔτ ઀ଓϢʔβʔ Ϛ΢ϯτ͢ΔϘϦϡʔϜ ύεϫʔυ

Slide 18

Slide 18 text

ิ଍ 5FTUDPOUBJOFS͕ఏڙ͢ΔϞδϡʔϧʢൈਮʣ w 5FTUDPOUBJOFST͕ఏڙ͍ͯ͠ΔϞδϡʔϧʹ͸ҎԼͷΑ͏ͳ΋ͷ͕ἧ͍ͬͯ ·͢ʢ͜ΕͰશྔͰ͸ͳ͍Ͱ͢ʣ w ఏڙ͞Ε͍ͯͳ͍ίϯςφͰ΋ɺཁ๬͕ଟ͚Ε͹Ϟδϡʔϧͱͯ͠ొ࿥͞ΕΔ ͔΋͠Ε·ͤΜ 3%#$ $BTTBOESB $PDLSPBDI%# .Z42- 0SBDMF9& %# .BSJB%# .POHP%# .PDLTFSWFS -PDBM4UBDL 42-4FSWFS 3BCCJU.2 ,BGLB &MBTUJDTFBSDI 4FMFOJVN

Slide 19

Slide 19 text

ίϯςφΛ࣮ߦ͠Α͏ w 5FTUDPOUBJOFSTͰίϯςφΛىಈ͢Δํ๏͸͍͔ͭ͋͘Γ·͢ w ࠓճ͸4QSJOH#PPU5FTUʹ૊ΈࠐΈ΍͍͢ΞϊςʔγϣϯΛར༻ͨ͠ํ๏Λ঺ հ͠·͢

Slide 20

Slide 20 text

ίϯςφΛ࣮ߦ͠Α͏ ςετΫϥε΁ͷΞϊςʔγϣϯͷ෇༩ w ίϯςφΛར༻͢ΔςετΫϥεʹ!5FTUDPOUBJOFSTΞϊςʔγϣϯΛ෇༩ ͠·͢ w 5FTUDPOUBJOFST͸͜ͷΞϊςʔγϣϯ͕͍ͭͨςετΛ࣮ߦ͢Δࡍʹίϯς φΛىಈͯ͘͠Ε·͢ @Testcontainers public class ContainerTest {

Slide 21

Slide 21 text

ίϯςφΛ࣮ߦ͠Α͏ ࣮ߦ͢Δίϯςφͷఆٛ w ࣮ߦ͢ΔίϯςφΛςετΫϥεͷTUBUJDϑΟʔϧυͰఆٛ͠·͢ w ΠϯελϯεॳظԽ࣌ʹίϯςφͷઃఆΛߦ͍·͢ w ࠓճ͸σʔλϕʔε໊ͱ%%-Λఆٛͨ͠42-ϑΝΠϧΛಡΈࠐ·ͤ·͢ w ෳ਺ͷίϯςφΛಉ࣌ʹىಈ͍ͨ͠৔߹͸ϑΟʔϧυΛෳ਺ఆ͍ٛͯͩ͘͠͞ @Container private static PostgreSQLContainer postgresqlContainer = (PostgreSQLContainer)new PostgreSQLContainer("postgres:14.2") .withDatabaseName("todo") .withInitScript("todo.sql");

Slide 22

Slide 22 text

ίϯςφΛ࣮ߦ͠Α͏ ࣮ߦͯ͠ΈΑ͏ w ίϯςφͷఆ͕ٛऴΘͬͨΒςετΛ࣮ߦ͠·͢ w ςετΛ࣮ߦ͢Δͱ࠷ॳʹ5FTUDPOUJBOFST͕ఆٛ͞ΕͨίϯςφΛىಈ͠· ͢ w ͦͷޙɺςετϝιου͕ݺͼग़͞Ε·͢ w ͨͬͨ͜Ε͚ͩ४උͰςετͰར༻͢Δ؀ڥ͕ηοτΞοϓ͞Ε·ͨ͠ @Test void ίϯςφ͕ಈ͍͍ͯΔ͜ͱ() { assertTrue(postgresqlContainer.isRunning()); }

Slide 23

Slide 23 text

ίϯςφΛ࣮ߦ͠Α͏ ىಈͨ͠ίϯςφͷޙ࢝຤ w ىಈͨ͠ίϯςφΛఀࢭͨ͠Γ࡟আͨ͠Γ͢Δॲཧ͸શ෦5FTUDPOUBJOFST͕ ΍ͬͯ͘Ε·͢ w ίϯςφɾϘϦϡʔϜɾωοτϫʔΫͷશͯΛ࡟আͯ͘͠Ε·͢ w ޙ࢝຤͸5FTUDPOUBJOFSTʹ೚ͤͯςετΛॻ͘ͷʹઐ೦͠·͠ΐ͏ w ༨ஊͰ͕͢ίϯςφΛ࡟আͯ͘͠ΕΔͷ͸Ϧϯΰ͕޷͖ͳࢮਆͰ͢ w ϦϡʔΫͱ͍͏໊ͷίϯςφ͕ཪͰ͓૟আͯ͠·͢

Slide 24

Slide 24 text

ίϯςφ࣮ߦͷิ଍ ϩάϨϕϧͷઃఆʢ೚ҙʣ w σϑΥϧτͷϩάϨϕϧͰ͸ɺίϯςφͷ1VMM΍ىಈ࣌ʹϩά͕େྔग़ྗ͞Ε ͯ͠·͍·͢ w ϩά͕ଟ͗͢Δͱײͨ͡৔߹͸5FTUDPOUBJOFSTͷग़ྗϨϕϧΛߜͬͯͩ͘͞ ͍ w ެࣜ)1ʹMPHCBDLUFTUYNM͕ఏڙ͞Ε͍ͯ·͢

Slide 25

Slide 25 text

ίϯςφ࣮ߦͷิ଍ खಈͰͷίϯςφىಈ w ΞϊςʔγϣϯΛར༻͠ͳ͍৔߹ɺOFXͨ͠ίϯςφΠϯελϯεͷTUBSUϝ ιουΛݺͼग़͢͜ͱͰίϯςφΛىಈ͢Δ͜ͱ͕Ͱ͖·͢ w ͜ͷํ๏Ͱىಈͨ͠৔߹Ͱ΋ίϯςφͷޙ࢝຤͸5FTUDPOUBJOFST͕ߦͬͯ͘ Ε·͢ // ࣮ߦ͢Δίϯςφͷఆٛ PostgreSQLContainer postgresqlContainer = (PostgreSQLContainer) new PostgreSQLContainer("postgres:14.2") .withDatabaseName("todo") .withInitScript("todo.sql"); // ىಈ postgresqlContainer.start();

Slide 26

Slide 26 text

ίϯςφ࣮ߦͷิ଍ ˏ$POUBJOFSͷϑΟʔϧυ w ࠓճ͸ˏ$POUBJOFSΛTUBUJDϑΟʔϧυʹઃఆͨͨ͠ΊɺςετΫϥεͰͭ ͷίϯςφ͕༻ҙ͞Ε·͢ w ͜ΕΛTUBUJDͰ͸ͳ͘ΠϯελϯεϑΟʔϧυʹ෇༩ͨ͠৔߹ɺςετϝιο υ͝ͱʹίϯςφ͕༻ҙ͞Ε·͢

Slide 27

Slide 27 text

͜͜·Ͱͷ·ͱΊ w ΞϊςʔγϣϯΛ࢖͏͚ͩͰ؆୯ʹίϯςφΛ૊ΈࠐΊΔ͜ͱΛ঺հ͠·ͨ͠ w ͜ΕͰ4QSJOHͷΞϓϦέʔγϣϯͰར༻͢Δσʔλϕʔεͷ४උ͸੔͍·͠ ͨ w ࣍͸ىಈͨ͠σʔλϕʔεΛ4QSJOH#PPU͔Β࢖͏ํ๏Λ঺հ͠·͢

Slide 28

Slide 28 text

4QSJOH#PPU5FTUͱͷ࿈ܞ

Slide 29

Slide 29 text

ςετ͢ΔΞϓϦέʔγϣϯ w ςετର৅ͷΞϓϦέʔγϣϯͱͯ͠ɺ؆୯ͳ5PEPͷΞϓϦΛར༻͠·͢ w ͜ͷΞϓϦͷ4FSWJDFΫϥεʹରͯ͠ɺ4QSJOH#PPU5FTUΛ࢖ͬͨ݁߹ςετ Λ࣮ߦ͠·͢ @Transactional Todo addTodo(String task) { return repository.save(new Todo(null,task,"Waiting")); }

Slide 30

Slide 30 text

4QSJOH#PPU5FTU ςετ࣮૷ w 5FTUDPOUBJOFSTΛઃఆͨ͠ςετΫϥεʹҎԼͷͭΛ௥Ճ͠·͢ w 4QSJOH#PPU5FTUΞϊςʔγϣϯΛ෇༩͢Δ w 4QSJOHͷΞϓϦʹ5FTUDPOUBJOFSTͰىಈͨ͠σʔλϕʔε΁ͷ઀ଓ৘ใΛ ࢦఆ͢Δ w ςετΫϥεʹςετ͢Δ4FSWJDFΫϥεΛ%*ͯ͠ςετϝιου͔Β࣮ߦ w ࠓ·Ͱͷ4QSJOH#PPUςετʹ੺࿮ͰғͬͨॲཧΛ௥Ճ͢Δ͚ͩͰ͢

Slide 31

Slide 31 text

4QSJOH#PPU5FTU σʔλϕʔεͷ઀ଓఆٛΛઃఆ w σʔλϕʔεͷ઀ଓઃఆ͸ɺ%ZOBNJD1SPQFSUZ4PVSDFΛ෇༩ͨ͠ϝιου ಺Ͱઃఆ͠·͢ w ઀ଓ৘ใ͸શͯίϯςφΠϯελϯε͔ΒऔಘՄೳͰ͢ w ༨ஊͰ͕͢͜ͷΞϊςʔγϣϯ͸4QSJOH͕5FTUDPOUBJOFSTͷͨΊʹ༻ҙͨ͠ ΋ͷͰ͢ @DynamicPropertySource static void jdbcProperties(DynamicPropertyRegistry registry) { registry.add("spring.datasource.url", postgresqlContainer::getJdbcUrl); registry.add("spring.datasource.username", postgresqlContainer::getUsername); registry.add("spring.datasource.password", postgresqlContainer::getPassword); }

Slide 32

Slide 32 text

4QSJOH#PPU5FTU ςετ࣮ߦ w ςετϝιουͰ4QSJOHͷαʔϏεΫϥεΛݺͼग़͢ςετΛهड़͠·͢ w ςετΛىಈ͢Δͱίϯςφͷσʔλϕʔεͱ4QSJOH͕ىಈ͠ɺςετϝι ου಺ͷॲཧ͕͓͜ͳΘΕ·͢ w ͜ΕͰσʔλϕʔεΛ༻͍ͨΞϓϦέʔγϣϯͷ݁߹ςετ͕ߦ͑·ͨ͠ @Autowired private TodoService service; @Test @Order(1) void addTodo() { String task = "🐱ʹ͝൧Λ΋Β͏"; Todo todo = service.addTodo(task); assertEquals(task, todo.task()); assertEquals("Waiting", todo.status()); }

Slide 33

Slide 33 text

4QSJOH#PPU5FTUิ଍ &YUFOTJPOΫϥεͰͷ࣮ߦ w ࠓճ͸ΞϊςʔγϣϯΛ༻͍ͨγϯϓϧͳํ๏Λ঺հ͠·ͨ͠ w Ξϊςʔγϣϯͷ৔߹͸֤ΫϥεͰίϯςφͷఆٛΛߦ͏ඞཁ͕͋Γ·͕͢ɺ ͜ͷఆٛΛ+6OJUͷ&YUFOTJPOΛ༻͍ͯू໿͢Δํ๏΋͋Γ·͢ w (JUIVCʹαϯϓϧͷίʔυ͕͋Γ·͢ͷͰࢀরͯ͠Έ͍ͯͩ͘͞ public class PostgresExtension implements BeforeAllCallback, AfterAllCallback { private PostgreSQLContainer> postgresqlContainer; @Override public void beforeAll(ExtensionContext context) { postgresqlContainer = (PostgreSQLContainer) new PostgreSQLContainer("postgres:14.2") .withDatabaseName("todo"); postgresqlContainer.start(); System.setProperty("spring.datasource.url", postgresqlContainer.getJdbcUrl()); System.setProperty("spring.datasource.username", postgresqlContainer.getUsername()); System.setProperty("spring.datasource.password", postgresqlContainer.getPassword()); }

Slide 34

Slide 34 text

4QSJOH#PPU5FTUิ଍ 5FTUDPOUBJOFSTͷόʔδϣϯ w 4QSJOH*OJUJBMJ[SͰ࡞੒ͨ͠ϓϩδΣΫτͷ5FTUDPOUBJOFSTͷόʔδϣϯ͸ Ͱ͢ w Ҏ߱Ͱ௥Ճ͞ΕͨϞδϡʔϧΛར༻͍ͨ͠৔߹͸ɺόʔδϣϯΛࢦఆ ͢Δඞཁ͕͋Γ·͢ʢࠓͷ࠷৽͸ʣ w ௥Ճ͞ΕͨϞδϡʔϧ͸4FMFOJVNɺLTɺ)JWF.2ͷͭͰ͢

Slide 35

Slide 35 text

·ͱΊ

Slide 36

Slide 36 text

5FTUDPOUBJOFSTͷಋೖޮՌ w ࠓ೔঺հͨ͠ൣғͰ΋5FTUDPOUBJOFST͸ͨ͘͞Μͷ࢓ࣄΛͯ͠·͢ w σʔλϕʔεͷΠϯετʔϧ͔Β࡟আ·ͰΛςετΫϥεͱີʹ࿈ܞ w ʮ+BWBͱ%PDLFS͕͋Ε͹Ͳ͜ͷϚγϯͰ΋੒ޭ͢Δςετʯ͕࡞ΕΔؾ͕͠ ͖ͯ·ͤΜ͔ʁ w গͳ͘ͱ΋ΞϓϦ΍ςετʹؔ܎ͳ͍໰୊Ͱɺ։ൃऀͷखΛ൥ΘͤΔ࣌ؒ΍࿑ ྗ͸࣮֬ʹݮΓ·͢

Slide 37

Slide 37 text

·ͱΊ w ೉қ౓ͱൺֱͯ͠5FTUDPOUBJOFSTͷՌͨ͢໾ׂ͸େ͖͍ͱࢥ͍·͢ w ݸਓతʹ஍ຯ͚ͩͲ࢓ࣄΛ࣮֬ʹ͜ͳͯ͘͠ΕΔ࢓ࣄਓελΠϧͳͱ͜Ζ͕޷ ͖Ͱ͢ w ϋϚΓϙΠϯτ͸େମ͸࣮ߦ͢Δίϯςφͷ࢓༷ɾɾɾ w ࠓճ͸4QSJOHͱͷ૊Έ߹ΘͤΛ঺հ͠·͕ͨ͠ɺผͷϑϨʔϜϫʔΫʢྫ͑͹ 2VBSLVTʣͱ΋࿈ܞ͢Δ͜ͱ͕Ͱ͖·͢ w ܁Γฦ͠ʹͳΓ·͕͢ɺςετ؀ڥͷ४උͱ͔໘౗ͳ͜ͱ͸શ෦ 5FTUDPOUBJOFSTʹ೚ͤ·͠ΐ͏ʂ w ։ൃऀ͸͍͍ίʔυΛॻ͘͜ͱʹઐ೦͠Α͏ʂ

Slide 38

Slide 38 text

ࢀߟࢿྉ w IUUQTXXXUFTUDPOUBJOFSTPSH w ެࣜ)1͸υΩϡϝϯτ͕ॆ࣮ w (JUIVCͷFYBNQMFʹ͸༷ʑͳϞδϡʔϧͷαϯϓϧ΋͋Γ·͢ w IUUQTHJUIVCDPNXFOBTTQSJOHUDFYBNQMF w ຊηογϣϯͷεϥΠυʹషͬͨίʔυ w શͯΛ঺հͰ͖·ͤΜͰͨ͠ͷͰɺ΋͠ΑΖ͚͠Ε͹ࢀর͍ͯͩ͘͠͞

Slide 39

Slide 39 text

ίϯςφςετֵ໋ 🐳