mirror of
https://gitee.com/many2many/java-web.git
synced 2025-01-11 14:40:55 +08:00
add c5-tasks c6-tasks
This commit is contained in:
parent
0882e0eb57
commit
8ce96694d6
315
docs/tasks/chapter05-tasks.md
Normal file
315
docs/tasks/chapter05-tasks.md
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
## 5. 基于Spring框架的后端应用开发
|
||||||
|
|
||||||
|
### 5.1 Java基础增强
|
||||||
|
|
||||||
|
#### 5.1.1 Java异常处理
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
1. **异常处理练习**:
|
||||||
|
- 创建一个方法,该方法接受两个整数参数,并返回它们的除法结果。如果第二个参数为0,则抛出自定义异常。
|
||||||
|
- 在主程序中调用该方法,并使用try-catch块来捕获异常,输出友好的错误信息。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
public class Division {
|
||||||
|
public static double divide(int a, int b) throws IllegalArgumentException {
|
||||||
|
if (b == 0) {
|
||||||
|
throw new IllegalArgumentException("除数不能为0");
|
||||||
|
}
|
||||||
|
return (double) a / b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
double result = divide(10, 0);
|
||||||
|
System.out.println("结果: " + result);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **自定义异常练习**:
|
||||||
|
- 创建一个自定义异常类`InvalidAgeException`,继承自`IllegalArgumentException`。
|
||||||
|
- 创建一个方法`validateAge`,接收一个年龄参数,如果年龄小于0或大于150,则抛出`InvalidAgeException`。
|
||||||
|
- 在主程序中调用`validateAge`方法,并捕获异常,输出异常信息。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
public class AgeValidator {
|
||||||
|
public static void validateAge(int age) throws InvalidAgeException {
|
||||||
|
if (age < 0 || age > 150) {
|
||||||
|
throw new InvalidAgeException("年龄无效");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
validateAge(-5);
|
||||||
|
} catch (InvalidAgeException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InvalidAgeException extends IllegalArgumentException {
|
||||||
|
public InvalidAgeException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.1.2 注解
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
1. **自定义注解练习**:
|
||||||
|
- 创建一个自定义注解`@MyAnnotation`,并带有字符串属性`value`。
|
||||||
|
- 创建一个类`AnnotatedClass`,并在其方法上使用`@MyAnnotation`注解。
|
||||||
|
- 编写一个程序读取该注解,并打印出注解的值。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public @interface MyAnnotation {
|
||||||
|
String value();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AnnotatedClass {
|
||||||
|
@MyAnnotation(value = "Hello, Annotation!")
|
||||||
|
public void myMethod() {
|
||||||
|
// 方法实现
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Method[] methods = AnnotatedClass.class.getDeclaredMethods();
|
||||||
|
for (Method method : methods) {
|
||||||
|
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
|
||||||
|
if (annotation != null) {
|
||||||
|
System.out.println(annotation.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.1.3 Optional的介绍和使用
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
1. **Optional练习**:
|
||||||
|
- 创建一个方法`getUserById`,该方法接收一个ID参数,并返回一个`Optional<User>`对象。
|
||||||
|
- 如果ID对应的数据存在,则返回包含用户对象的`Optional`;否则返回空的`Optional`。
|
||||||
|
- 在主程序中调用该方法,并使用`ifPresent`或`orElse`方法处理结果。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
public class User {
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public User(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserService {
|
||||||
|
public static Optional<User> getUserById(long id) {
|
||||||
|
if (id == 1) {
|
||||||
|
return Optional.of(new User("John Doe"));
|
||||||
|
} else {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Optional<User> user = getUserById(1);
|
||||||
|
user.ifPresent(u -> System.out.println("用户姓名: " + u.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.1.4 Stream API的介绍和使用
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
1. **Stream API练习**:
|
||||||
|
- 创建一个方法`findMaxValue`,该方法接收一个`List<Integer>`参数,并返回列表中的最大值。
|
||||||
|
- 使用Stream API来实现这个功能。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MaxFinder {
|
||||||
|
public static int findMaxValue(List<Integer> numbers) {
|
||||||
|
return numbers.stream().max(Integer::compare).orElse(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
|
||||||
|
int maxValue = findMaxValue(numbers);
|
||||||
|
System.out.println("最大值: " + maxValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.1.5 泛型
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
1. **泛型练习**:
|
||||||
|
- 创建一个泛型类`Pair<T, U>`,用于存储两个不同类型的数据。
|
||||||
|
- 在主程序中创建一个`Pair<String, Integer>`对象,并设置和获取其中的值。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
public class Pair<T, U> {
|
||||||
|
private T first;
|
||||||
|
private U second;
|
||||||
|
|
||||||
|
public Pair(T first, U second) {
|
||||||
|
this.first = first;
|
||||||
|
this.second = second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getFirst() {
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public U getSecond() {
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirst(T first) {
|
||||||
|
this.first = first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecond(U second) {
|
||||||
|
this.second = second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Pair<String, Integer> pair = new Pair<>("Hello", 42);
|
||||||
|
System.out.println("First: " + pair.getFirst() + ", Second: " + pair.getSecond());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 Spring框架简介
|
||||||
|
|
||||||
|
#### 5.2.2 Spring框架的核心特性
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
1. **Spring框架特性练习**:
|
||||||
|
- 使用Spring框架创建一个简单的Web应用,该应用包含一个控制器,该控制器提供一个静态的欢迎页面。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class WelcomeController {
|
||||||
|
@GetMapping("/")
|
||||||
|
public String welcome() {
|
||||||
|
return "welcome";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 Spring IoC
|
||||||
|
|
||||||
|
#### 5.3.1 Spring Bean的定义和生命周期
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
1. **Bean生命周期练习**:
|
||||||
|
- 创建一个带有初始化和销毁方法的Spring Bean。
|
||||||
|
- 使用`@PostConstruct`和`@PreDestroy`注解来标记初始化和销毁方法。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class LifeCycleBean {
|
||||||
|
public LifeCycleBean() {
|
||||||
|
System.out.println("LifeCycleBean created.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
System.out.println("LifeCycleBean initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreDestroy
|
||||||
|
public void destroy() {
|
||||||
|
System.out.println("LifeCycleBean destroyed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.3.2 XML和注解方式的Bean配置
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
1. **XML和注解配置练习**:
|
||||||
|
- 使用XML和注解两种方式配置一个简单的Spring Bean。
|
||||||
|
- 在主程序中获取并使用该Bean。
|
||||||
|
- 示例代码 (XML配置):
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||||
|
|
||||||
|
<bean id="myBean" class="com.example.MyBean">
|
||||||
|
<property name="name" value="John Doe"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
||||||
|
```
|
||||||
|
|
||||||
|
- 示例代码 (注解配置):
|
||||||
|
```java
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class AppConfig {
|
||||||
|
@Bean
|
||||||
|
public MyBean myBean() {
|
||||||
|
return new MyBean("Jane Doe");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MyBean {
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public MyBean(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.4 Spring MVC
|
||||||
|
|
||||||
|
#### 5.4.2 使用@Controller定义控制器
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
1. **控制器练习**:
|
||||||
|
- 创建一个简单的控制器,该控制器接收一个GET请求并返回一个简单的HTML页面。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class SimpleController {
|
||||||
|
@GetMapping("/simple")
|
||||||
|
public String simplePage() {
|
||||||
|
return "simple";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
220
docs/tasks/chapter06-tasks.md
Normal file
220
docs/tasks/chapter06-tasks.md
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
## 6. 数据库访问
|
||||||
|
### 6.1 JDBC
|
||||||
|
|
||||||
|
#### 6.1.3 实现第一个JDBC程序
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
|
||||||
|
1. **创建数据库表**:
|
||||||
|
- 根据PetClinic中的`Owner`实体模型创建一个表,包含`id`(整数,主键,自增)、`firstName`(字符串,长度255,不可为空)、`lastName`(字符串,长度255,不可为空)、`address`(字符串,长度255)、`city`(字符串,长度255)、`telephone`(字符串,长度255)字段。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
private static void createOwnerTable(Connection conn) throws SQLException {
|
||||||
|
String sql = "CREATE TABLE IF NOT EXISTS owners (" +
|
||||||
|
"id INT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
|
"firstName VARCHAR(255) NOT NULL," +
|
||||||
|
"lastName VARCHAR(255) NOT NULL," +
|
||||||
|
"address VARCHAR(255)," +
|
||||||
|
"city VARCHAR(255)," +
|
||||||
|
"telephone VARCHAR(255))";
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **插入业主记录**:
|
||||||
|
- 向`owners`表中插入两条记录。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
private static void insertOwners(Connection conn) throws SQLException {
|
||||||
|
String sql = "INSERT INTO owners (firstName, lastName, address, city, telephone) VALUES (?, ?, ?, ?, ?)";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setString(1, "Alice");
|
||||||
|
pstmt.setString(2, "Johnson");
|
||||||
|
pstmt.setString(3, "123 Main St");
|
||||||
|
pstmt.setString(4, "Springfield");
|
||||||
|
pstmt.setString(5, "555-1234");
|
||||||
|
pstmt.executeUpdate();
|
||||||
|
|
||||||
|
pstmt.setString(1, "Bob");
|
||||||
|
pstmt.setString(2, "Smith");
|
||||||
|
pstmt.setString(3, "456 Elm St");
|
||||||
|
pstmt.setString(4, "Springfield");
|
||||||
|
pstmt.setString(5, "555-5678");
|
||||||
|
pstmt.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **查询业主记录**:
|
||||||
|
- 查询`owners`表中的所有记录,并打印出每条记录的信息。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
private static void queryOwners(Connection conn) throws SQLException {
|
||||||
|
String sql = "SELECT * FROM owners";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql);
|
||||||
|
ResultSet rs = pstmt.executeQuery()) {
|
||||||
|
while (rs.next()) {
|
||||||
|
int id = rs.getInt("id");
|
||||||
|
String firstName = rs.getString("firstName");
|
||||||
|
String lastName = rs.getString("lastName");
|
||||||
|
String address = rs.getString("address");
|
||||||
|
String city = rs.getString("city");
|
||||||
|
String telephone = rs.getString("telephone");
|
||||||
|
System.out.println("ID: " + id + ", First Name: " + firstName + ", Last Name: " + lastName + ", Address: " + address + ", City: " + city + ", Telephone: " + telephone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **更新业主记录**:
|
||||||
|
- 更新`owners`表中名字为"Alice Johnson"的业主的电话号码为"555-1111"。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
private static void updateOwner(Connection conn) throws SQLException {
|
||||||
|
String sql = "UPDATE owners SET telephone = ? WHERE firstName = ? AND lastName = ?";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setString(1, "555-1111");
|
||||||
|
pstmt.setString(2, "Alice");
|
||||||
|
pstmt.setString(3, "Johnson");
|
||||||
|
int rowsUpdated = pstmt.executeUpdate();
|
||||||
|
System.out.println(rowsUpdated + " row(s) updated.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **删除业主记录**:
|
||||||
|
- 删除`owners`表中名字为"Bob Smith"的业主记录。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
private static void deleteOwner(Connection conn) throws SQLException {
|
||||||
|
String sql = "DELETE FROM owners WHERE firstName = ? AND lastName = ?";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setString(1, "Bob");
|
||||||
|
pstmt.setString(2, "Smith");
|
||||||
|
int rowsDeleted = pstmt.executeUpdate();
|
||||||
|
System.out.println(rowsDeleted + " row(s) deleted.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **完整程序**:
|
||||||
|
- 将以上步骤整合到一个完整的程序中,确保正确加载MySQL驱动、建立数据库连接,并处理异常。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class JdbcCrudExample {
|
||||||
|
private static final String DB_URL = "jdbc:mysql://localhost:3306/petclinic";
|
||||||
|
private static final String USER = "root";
|
||||||
|
private static final String PASS = "password";
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Connection conn = null;
|
||||||
|
try {
|
||||||
|
// 加载MySQL驱动
|
||||||
|
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||||
|
|
||||||
|
// 获取数据库连接
|
||||||
|
conn = DriverManager.getConnection(DB_URL, USER, PASS);
|
||||||
|
|
||||||
|
// 创建表
|
||||||
|
createOwnerTable(conn);
|
||||||
|
|
||||||
|
// 插入记录
|
||||||
|
insertOwners(conn);
|
||||||
|
|
||||||
|
// 查询记录
|
||||||
|
queryOwners(conn);
|
||||||
|
|
||||||
|
// 更新记录
|
||||||
|
updateOwner(conn);
|
||||||
|
|
||||||
|
// 删除记录
|
||||||
|
deleteOwner(conn);
|
||||||
|
|
||||||
|
// 再次查询记录
|
||||||
|
queryOwners(conn);
|
||||||
|
|
||||||
|
} catch (ClassNotFoundException | SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (conn != null) {
|
||||||
|
try {
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他方法...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.3 SQL注入的预防措施
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
|
||||||
|
1. **使用PreparedStatement防止SQL注入**:
|
||||||
|
- 修改上述的`queryOwners`方法,使用`PreparedStatement`来执行查询。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
private static void queryOwners(Connection conn) throws SQLException {
|
||||||
|
String sql = "SELECT * FROM owners WHERE firstName = ? AND lastName = ?";
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
pstmt.setString(1, "Alice");
|
||||||
|
pstmt.setString(2, "Johnson");
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
int id = rs.getInt("id");
|
||||||
|
String firstName = rs.getString("firstName");
|
||||||
|
String lastName = rs.getString("lastName");
|
||||||
|
String address = rs.getString("address");
|
||||||
|
String city = rs.getString("city");
|
||||||
|
String telephone = rs.getString("telephone");
|
||||||
|
System.out.println("ID: " + id + ", First Name: " + firstName + ", Last Name: " + lastName + ", Address: " + address + ", City: " + city + ", Telephone: " + telephone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 数据库连接池
|
||||||
|
|
||||||
|
#### 6.2.4 使用HikariCP实现数据库连接池
|
||||||
|
|
||||||
|
**练习任务**:
|
||||||
|
|
||||||
|
1. **配置HikariCP连接池**:
|
||||||
|
- 使用HikariCP配置一个连接池,并使用它来获取数据库连接。
|
||||||
|
- 示例代码:
|
||||||
|
```java
|
||||||
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class HikariCpExample {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
HikariConfig config = new HikariConfig();
|
||||||
|
config.setJdbcUrl("jdbc:mysql://localhost:3306/petclinic");
|
||||||
|
config.setUsername("root");
|
||||||
|
config.setPassword("password");
|
||||||
|
config.setMaximumPoolSize(10);
|
||||||
|
config.setConnectionTimeout(30000);
|
||||||
|
|
||||||
|
HikariDataSource ds = new HikariDataSource(config);
|
||||||
|
|
||||||
|
try (Connection conn = ds.getConnection()) {
|
||||||
|
// 使用连接执行数据库操作
|
||||||
|
System.out.println("Database connection established.");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
13
docs/todo.md
Normal file
13
docs/todo.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
mvc开源项目参考 https://gitee.com/YHC/book-JavaEE-SSM
|
||||||
|
|
||||||
|
spring petclinic https://gitee.com/phxism/spring-framework-petclinic
|
||||||
|
|
||||||
|
|
||||||
|
https://gitee.com/univerciti/java-ee-spring-pet-clinic
|
||||||
|
|
||||||
|
|
||||||
|
https://github.com/FlaviodosSantos/TutorialSpringMVC
|
||||||
|
|
||||||
|
|
||||||
|
**https://github.com/spring-petclinic/spring-framework-petclinic**
|
Loading…
Reference in New Issue
Block a user