diff --git a/java/23ai-springboot3-jdbc/README.md b/java/23ai-springboot3-jdbc/README.md new file mode 100644 index 00000000..71d3519f --- /dev/null +++ b/java/23ai-springboot3-jdbc/README.md @@ -0,0 +1 @@ +[Spring Data JDBC with the Oracle Database for Java Developers - Getting Started Guide](https://medium.com/oracledevs/spring-data-jdbc-with-the-oracle-database-23c-for-java-developers-getting-started-guide-1c4640fc8d27) diff --git a/java/23ai-springboot3-jdbc/pom.xml b/java/23ai-springboot3-jdbc/pom.xml new file mode 100644 index 00000000..1b6f5f55 --- /dev/null +++ b/java/23ai-springboot3-jdbc/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.2.0 + + + com.oracle.dev.springdata.jdbc + 23ai-springboot3-jdbc + 0.0.1-SNAPSHOT + 23ai-springboot3-jdbc + + 21 + + + + com.oracle.database.jdbc + ojdbc11 + 23.6.0.24.10 + + + com.oracle.database.jdbc + ucp17 + 23.6.0.24.10 + + + + org.springframework.boot + spring-boot-starter-data-jdbc + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + maven-compiler-plugin + + + + + + + + + diff --git a/java/23ai-springboot3-jdbc/script/EMPLOYEE.SQL b/java/23ai-springboot3-jdbc/script/EMPLOYEE.SQL new file mode 100644 index 00000000..edd9ff31 --- /dev/null +++ b/java/23ai-springboot3-jdbc/script/EMPLOYEE.SQL @@ -0,0 +1,28 @@ +CREATE USER ORACLE_23C_USER IDENTIFIED BY ; +GRANT DB_DEVELOPER_ROLE TO ORACLE_23C_USER; +GRANT CREATE SESSION TO ORACLE_23C_USER; +GRANT UNLIMITED TABLESPACE TO ORACLE_23C_USER; + +CREATE TABLE Employee + (id NUMBER(10) CONSTRAINT pk_employee PRIMARY KEY, + name VARCHAR2(20), + job VARCHAR2(20), + salary NUMBER(10), + commission NUMBER(10)); + +INSERT INTO Employee VALUES(7369,'JOHN','CLERK',7902,NULL); +INSERT INTO Employee VALUES(7499,'PETER','SALESMAN',7698,300); +INSERT INTO Employee VALUES(7521,'JEFF','SALESMAN',7698,500); +INSERT INTO Employee VALUES(7566,'MARK','MANAGER',7839,NULL); +INSERT INTO Employee VALUES(7654,'MARTIN','SALESMAN',7698,1400); +INSERT INTO Employee VALUES(7698,'ADAM','MANAGER',7839,NULL); +INSERT INTO Employee VALUES(7782,'CLARK','MANAGER',7839,NULL); +INSERT INTO Employee VALUES(7788,'SCOTT','ANALYST',7566,NULL); +INSERT INTO Employee VALUES(7839,'KING','PRESIDENT',NULL); +INSERT INTO Employee VALUES(7844,'TURNER','SALESMAN',0); +INSERT INTO Employee VALUES(7876,'ADAMS','CLERK',7788,NULL); +INSERT INTO Employee VALUES(7900,'JAMES','CLERK',7698,NULL); +INSERT INTO Employee VALUES(7902,'FORD','ANALYST',7566,NULL); +INSERT INTO Employee VALUES(7934,'MILLER','CLERK',7782,NULL); + +COMMIT; \ No newline at end of file diff --git a/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/Employee.java b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/Employee.java new file mode 100644 index 00000000..eca7c9fa --- /dev/null +++ b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/Employee.java @@ -0,0 +1,115 @@ +/* + Copyright (c) 2024, Oracle and/or its affiliates. + + This software is dual-licensed to you under the Universal Permissive License + (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License + 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose + either license. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.oracle.dev.springdata.jdbc; + +import java.util.Objects; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Table; + +@Table +public class Employee { + + private @Id Long id; + private String name; + private String job; + private Integer salary; + private Integer commission; + + public Employee() { + } + + public Employee(Long id, String name, String job, Integer salary, + Integer commission) { + this.id = id; + this.name = name; + this.job = job; + this.salary = salary; + this.commission = commission; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getJob() { + return job; + } + + public void setJob(String job) { + this.job = job; + } + + public Integer getSalary() { + return salary; + } + + public void setSalary(Integer salary) { + this.salary = salary; + } + + public Integer getCommission() { + return commission; + } + + public void setCommission(Integer commission) { + this.commission = commission; + } + + @Override + public int hashCode() { + return Objects.hash(commission, id, job, name, salary); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Employee other = (Employee) obj; + return Objects.equals(commission, other.commission) + && Objects.equals(id, other.id) && Objects.equals(job, other.job) + && Objects.equals(name, other.name) + && Objects.equals(salary, other.salary); + } + + public String toString() { + return String.format("%20s %20s %20s %20s %20s", id, name, job, salary, + commission); + + } +} diff --git a/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeApplication.java b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeApplication.java new file mode 100644 index 00000000..a3f05d61 --- /dev/null +++ b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeApplication.java @@ -0,0 +1,34 @@ +/* + Copyright (c) 2024, Oracle and/or its affiliates. + + This software is dual-licensed to you under the Universal Permissive License + (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License + 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose + either license. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.oracle.dev.springdata.jdbc; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class EmployeeApplication { + + public static void main(String[] args) { + SpringApplication.run(EmployeeApplication.class, args); + } + +} diff --git a/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeController.java b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeController.java new file mode 100644 index 00000000..a3f62a93 --- /dev/null +++ b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeController.java @@ -0,0 +1,76 @@ +/* + Copyright (c) 2024, Oracle and/or its affiliates. + + This software is dual-licensed to you under the Universal Permissive License + (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License + 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose + either license. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.oracle.dev.springdata.jdbc; + +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +class EmployeeController { + + private final EmployeeRepository repository; + + EmployeeController(EmployeeRepository repository) { + this.repository = repository; + } + + @GetMapping("/employees") + Iterable all() { + return repository.findAll(); + } + + @PostMapping("/employees") + Employee newEmployee(@RequestBody Employee newEmployee) { + return repository.save(newEmployee); + } + + @GetMapping("/employees/{id}") + Employee one(@PathVariable Long id) { + + return repository.findById(id) + .orElseThrow(() -> new EmployeeNotFoundException(id)); + } + + @PutMapping("/employees/{id}") + Employee replaceEmployee(@RequestBody Employee newEmployee, + @PathVariable Long id) { + + return repository.findById(id).map(employee -> { + employee.setName(newEmployee.getName()); + employee.setJob(newEmployee.getJob()); + return repository.save(employee); + }).orElseGet(() -> { + newEmployee.setId(id); + return repository.save(newEmployee); + }); + } + + @DeleteMapping("/employees/{id}") + void deleteEmployee(@PathVariable Long id) { + repository.deleteById(id); + } +} \ No newline at end of file diff --git a/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeNotFoundAdvice.java b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeNotFoundAdvice.java new file mode 100644 index 00000000..28b5090b --- /dev/null +++ b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeNotFoundAdvice.java @@ -0,0 +1,39 @@ +/* + Copyright (c) 2024, Oracle and/or its affiliates. + + This software is dual-licensed to you under the Universal Permissive License + (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License + 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose + either license. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.oracle.dev.springdata.jdbc; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ControllerAdvice +class EmployeeNotFoundAdvice { + + @ResponseBody + @ExceptionHandler(EmployeeNotFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + String employeeNotFoundHandler(EmployeeNotFoundException ex) { + return ex.getMessage(); + } +} \ No newline at end of file diff --git a/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeNotFoundException.java b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeNotFoundException.java new file mode 100644 index 00000000..25c64567 --- /dev/null +++ b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeNotFoundException.java @@ -0,0 +1,31 @@ +/* + Copyright (c) 2024, Oracle and/or its affiliates. + + This software is dual-licensed to you under the Universal Permissive License + (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License + 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose + either license. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.oracle.dev.springdata.jdbc; + +class EmployeeNotFoundException extends RuntimeException { + + private static final long serialVersionUID = 7768215094663842819L; + + EmployeeNotFoundException(Long id) { + super("Could not find employee " + id); + } +} \ No newline at end of file diff --git a/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeRepository.java b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeRepository.java new file mode 100644 index 00000000..fce67dc3 --- /dev/null +++ b/java/23ai-springboot3-jdbc/src/main/java/com/oracle/dev/springdata/jdbc/EmployeeRepository.java @@ -0,0 +1,39 @@ +/* + Copyright (c) 2024, Oracle and/or its affiliates. + + This software is dual-licensed to you under the Universal Permissive License + (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License + 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose + either license. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.oracle.dev.springdata.jdbc; + +import java.util.List; + +import org.springframework.data.jdbc.repository.query.Modifying; +import org.springframework.data.jdbc.repository.query.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; + +interface EmployeeRepository extends CrudRepository { + + List findByName(String name); + + @Modifying + @Query("UPDATE employee SET name = :name WHERE id = :id") + boolean updateByName(@Param("id") Long id, @Param("name") String name); + +} \ No newline at end of file diff --git a/java/23ai-springboot3-jdbc/src/main/resources/application.properties b/java/23ai-springboot3-jdbc/src/main/resources/application.properties new file mode 100644 index 00000000..41d447b2 --- /dev/null +++ b/java/23ai-springboot3-jdbc/src/main/resources/application.properties @@ -0,0 +1,15 @@ +# https://www.oracle.com/database/technologies/getting-started-using-jdbc.html + +# Oracle Database 23ai Free - DB instance details +# JDBC URL EXAMPLE = jdbc:oracle:thin:@:/ +spring.datasource.url= +spring.datasource.username= +spring.datasource.password= + +# Properties for UCP - Universal Connection Pool (UCP). Spring Boot 2.4.0 or above is required +spring.datasource.type=oracle.ucp.jdbc.PoolDataSource +spring.datasource.oracleucp.connection-pool-name=connectionPoolName1 +spring.datasource.oracleucp.initial-pool-size=1 +spring.datasource.oracleucp.min-pool-size=1 +spring.datasource.oracleucp.max-pool-size=2 +spring.datasource.oracleucp.connection-factory-class-name=oracle.jdbc.pool.OracleDataSource