SQLServer教程FG038-SQLServer Java集成实战
目录大纲
内容简介
本文档基于SQLServer官方文档的Java集成内容,结合生产环境实际情况,详细讲解SQLServer与Java的集成配置、数据访问、性能优化等内容。风哥教程参考SQLServer官方文档JDBC Driver for SQL Server、Java Development等相关章节。
Part01-基础概念与理论知识
1.1 SQLServer Java集成概念
SQLServer Java集成的概念:
- SQLServer与Java的集成是指通过Java程序与SQLServer进行数据交互
- 主要通过JDBC(Java Database Connectivity)实现
- 支持同步和异步数据访问
- 提供了丰富的API和工具,简化数据库操作
更多视频教程www.fgedu.net.cn
1.2 SQLServer Java驱动介绍
SQLServer Java驱动介绍:
- Microsoft JDBC Driver for SQL Server:官方提供的JDBC驱动,支持SQLServer 2012及以上版本
- JTDS:开源的JDBC驱动,支持SQLServer和Sybase
- 连接池实现:如HikariCP、Apache DBCP、C3P0等
- ORM框架:如Hibernate、MyBatis等
学习交流加群风哥微信: itpux-com
1.3 SQLServer Java集成架构
SQLServer Java集成架构:
- 应用层:Java应用程序,如Spring Boot应用、Java Web应用等
- 数据访问层:负责与数据库交互,如JDBC、ORM框架等
- 连接池:管理数据库连接,提高性能
- 驱动层:JDBC驱动,负责与SQLServer通信
- 数据库层:SQLServer数据库实例
学习交流加群风哥QQ113257174
Part02-生产环境规划与建议
2.1 SQLServer Java集成规划原则
集成规划原则:
- 根据应用类型和规模选择合适的数据访问技术
- 设计合理的数据访问层架构,确保可维护性和可扩展性
- 考虑并发访问和事务处理需求
- 制定连接池和性能优化策略
- 确保数据安全和错误处理机制
风哥提示:生产环境应根据实际需求选择合适的Java集成方案,平衡性能和开发效率
2.2 SQLServer Java连接池配置
连接池配置:
- 最大连接数:根据应用并发量设置,默认10-100
- 最小空闲连接数:保持一定数量的空闲连接,默认5-10
- 连接超时时间:获取连接的超时时间,默认30秒
- 空闲连接超时时间:空闲连接的最大存活时间,默认60秒
- 连接验证时间:验证连接是否有效的时间间隔,默认300秒
更多学习教程公众号风哥教程itpux_com
2.3 SQLServer Java性能优化建议
性能优化建议:
- 使用参数化查询,避免SQL注入和提高性能
- 合理使用连接池,减少连接开销
- 使用批处理,减少网络往返
- 缓存常用数据,减少数据库访问
- 优化SQL语句,提高查询性能
- 使用异步操作,提高应用响应速度
from SQLServer视频:www.itpux.com
Part03-生产环境项目实施方案
3.1 SQLServer Java集成配置
集成配置:
implementation ‘com.microsoft.sqlserver:mssql-jdbc:12.4.0.jre11’
spring.datasource.url=jdbc:sqlserver://fgedu-server:1433;databaseName=fgedudb;encrypt=true;trustServerCertificate=true;
spring.datasource.username=fgedu
spring.datasource.password=Password123!
spring.datasource.hikari.maximum-pool-size=100
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.idle-timeout=60000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.max-lifetime=1800000
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class TestConnection {
public static void main(String[] args) {
String connectionUrl = “jdbc:sqlserver://fgedu-server:1433;databaseName=fgedudb;encrypt=true;trustServerCertificate=true;”;
String username = “fgedu”;
String password = “Password123!”;
try (Connection connection = DriverManager.getConnection(connectionUrl, username, password)) {
System.out.println(“连接成功!”);
} catch (SQLException e) {
e.printStackTrace();
System.out.println(“连接失败:” + e.getMessage());
}
}
}
执行结果:
[INFO] — maven-dependency-plugin:3.6.1:tree (default-cli) @ fgedu-app —
[INFO] com.fgedu:fgedu-app:jar:1.0.0
[INFO] +- com.microsoft.sqlserver:mssql-jdbc:jar:12.4.0.jre11:compile
[INFO] +- org.springframework.boot:spring-boot-starter-jdbc:jar:3.2.0:compile
[INFO] | +- com.zaxxer:HikariCP:jar:5.0.1:compile
[INFO] | \- org.springframework:spring-jdbc:jar:6.1.0:compile
$ java TestConnection
连接成功!
3.2 SQLServer Java数据访问层实现
数据访问层实现:
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class LargeTableDAO {
private String connectionUrl;
private String username;
private String password;
public LargeTableDAO(String connectionUrl, String username, String password) {
this.connectionUrl = connectionUrl;
this.username = username;
this.password = password;
}
public LargeTable getById(int id) throws SQLException {
String sql = “SELECT Id, Col1, Col2 FROM fgedu.large_table WHERE Id = ?”;
try (Connection connection = DriverManager.getConnection(connectionUrl, username, password);
PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setInt(1, id);
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
return new LargeTable(
resultSet.getInt(“Id”),
resultSet.getString(“Col1”),
resultSet.getString(“Col2”)
);
}
return null;
}
}
}
public List
String sql = “SELECT Id, Col1, Col2 FROM fgedu.large_table”;
try (Connection connection = DriverManager.getConnection(connectionUrl, username, password);
PreparedStatement statement = connection.prepareStatement(sql);
ResultSet resultSet = statement.executeQuery()) {
List
while (resultSet.next()) {
result.add(new LargeTable(
resultSet.getInt(“Id”),
resultSet.getString(“Col1”),
resultSet.getString(“Col2”)
));
}
return result;
}
}
public void add(LargeTable entity) throws SQLException {
String sql = “INSERT INTO fgedu.large_table (Col1, Col2) VALUES (?, ?)”;
try (Connection connection = DriverManager.getConnection(connectionUrl, username, password);
PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setString(1, entity.getCol1());
statement.setString(2, entity.getCol2());
statement.executeUpdate();
}
}
public void update(LargeTable entity) throws SQLException {
String sql = “UPDATE fgedu.large_table SET Col1 = ?, Col2 = ? WHERE Id = ?”;
try (Connection connection = DriverManager.getConnection(connectionUrl, username, password);
PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setString(1, entity.getCol1());
statement.setString(2, entity.getCol2());
statement.setInt(3, entity.getId());
statement.executeUpdate();
}
}
public void delete(int id) throws SQLException {
String sql = “DELETE FROM fgedu.large_table WHERE Id = ?”;
try (Connection connection = DriverManager.getConnection(connectionUrl, username, password);
PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setInt(1, id);
statement.executeUpdate();
}
}
}
public class LargeTable {
private int id;
private String col1;
private String col2;
public LargeTable(int id, String col1, String col2) {
this.id = id;
this.col1 = col1;
this.col2 = col2;
}
// getters and setters
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getCol1() { return col1; }
public void setCol1(String col1) { this.col1 = col1; }
public String getCol2() { return col2; }
public void setCol2(String col2) { this.col2 = col2; }
}
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public class LargeTableRepository {
private JdbcTemplate jdbcTemplate;
public LargeTableRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public LargeTable getById(int id) {
String sql = “SELECT Id, Col1, Col2 FROM fgedu.large_table WHERE Id = ?”;
return jdbcTemplate.queryForObject(sql, new Object[]{id}, (rs, rowNum) ->
new LargeTable(rs.getInt(“Id”), rs.getString(“Col1”), rs.getString(“Col2”))
);
}
public List
String sql = “SELECT Id, Col1, Col2 FROM fgedu.large_table”;
return jdbcTemplate.query(sql, (rs, rowNum) ->
new LargeTable(rs.getInt(“Id”), rs.getString(“Col1”), rs.getString(“Col2”))
);
}
public void add(LargeTable entity) {
String sql = “INSERT INTO fgedu.large_table (Col1, Col2) VALUES (?, ?)”;
jdbcTemplate.update(sql, entity.getCol1(), entity.getCol2());
}
public void update(LargeTable entity) {
String sql = “UPDATE fgedu.large_table SET Col1 = ?, Col2 = ? WHERE Id = ?”;
jdbcTemplate.update(sql, entity.getCol1(), entity.getCol2(), entity.getId());
}
public void delete(int id) {
String sql = “DELETE FROM fgedu.large_table WHERE Id = ?”;
jdbcTemplate.update(sql, id);
}
}
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface LargeTableMapper {
@Select(“SELECT Id, Col1, Col2 FROM fgedu.large_table WHERE Id = #{id}”)
LargeTable getById(int id);
@Select(“SELECT Id, Col1, Col2 FROM fgedu.large_table”)
List
@Insert(“INSERT INTO fgedu.large_table (Col1, Col2) VALUES (#{col1}, #{col2})”)
void add(LargeTable entity);
@Update(“UPDATE fgedu.large_table SET Col1 = #{col1}, Col2 = #{col2} WHERE Id = #{id}”)
void update(LargeTable entity);
@Delete(“DELETE FROM fgedu.large_table WHERE Id = #{id}”)
void delete(int id);
}
执行结果:
LargeTable{id=1, col1=’test1′, col2=’value1′}
[LargeTable{id=1, col1=’test1′, col2=’value1′}, LargeTable{id=2, col1=’test2′, col2=’value2′}]
添加成功
更新成功
删除成功
LargeTable{id=1, col1=’test1′, col2=’value1′}
[LargeTable{id=1, col1=’test1′, col2=’value1′}, LargeTable{id=2, col1=’test2′, col2=’value2′}]
添加成功
更新成功
删除成功
LargeTable{id=1, col1=’test1′, col2=’value1′}
[LargeTable{id=1, col1=’test1′, col2=’value1′}, LargeTable{id=2, col1=’test2′, col2=’value2′}]
添加成功
更新成功
删除成功
3.3 SQLServer Java事务管理
事务管理:
public void transferFunds(int fromAccountId, int toAccountId, double amount) throws SQLException {
String connectionUrl = “jdbc:sqlserver://fgedu-server:1433;databaseName=fgedudb;encrypt=true;trustServerCertificate=true;”;
String username = “fgedu”;
String password = “Password123!”;
Connection connection = null;
try {
connection = DriverManager.getConnection(connectionUrl, username, password);
connection.setAutoCommit(false); // 开始事务
// 扣除转出账户余额
String deductSql = “UPDATE fgedu.accounts SET balance = balance – ? WHERE id = ?”;
try (PreparedStatement deductStatement = connection.prepareStatement(deductSql)) {
deductStatement.setDouble(1, amount);
deductStatement.setInt(2, fromAccountId);
int deductRows = deductStatement.executeUpdate();
if (deductRows == 0) {
throw new SQLException(“转出账户不存在”);
}
}
// 增加转入账户余额
String addSql = “UPDATE fgedu.accounts SET balance = balance + ? WHERE id = ?”;
try (PreparedStatement addStatement = connection.prepareStatement(addSql)) {
addStatement.setDouble(1, amount);
addStatement.setInt(2, toAccountId);
int addRows = addStatement.executeUpdate();
if (addRows == 0) {
throw new SQLException(“转入账户不存在”);
}
}
// 提交事务
connection.commit();
System.out.println(“转账成功”);
} catch (SQLException e) {
// 回滚事务
if (connection != null) {
try {
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
throw e;
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
import org.springframework.transaction.annotation.Transactional;
@Service
public class AccountService {
private final JdbcTemplate jdbcTemplate;
public AccountService(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Transactional
public void transferFunds(int fromAccountId, int toAccountId, double amount) {
// 扣除转出账户余额
String deductSql = “UPDATE fgedu.accounts SET balance = balance – ? WHERE id = ?”;
int deductRows = jdbcTemplate.update(deductSql, amount, fromAccountId);
if (deductRows == 0) {
throw new RuntimeException(“转出账户不存在”);
}
// 增加转入账户余额
String addSql = “UPDATE fgedu.accounts SET balance = balance + ? WHERE id = ?”;
int addRows = jdbcTemplate.update(addSql, amount, toAccountId);
if (addRows == 0) {
throw new RuntimeException(“转入账户不存在”);
}
System.out.println(“转账成功”);
}
}
@Service
public class AccountService {
private final AccountMapper accountMapper;
public AccountService(AccountMapper accountMapper) {
this.accountMapper = accountMapper;
}
@Transactional
public void transferFunds(int fromAccountId, int toAccountId, double amount) {
// 扣除转出账户余额
int deductRows = accountMapper.deductBalance(fromAccountId, amount);
if (deductRows == 0) {
throw new RuntimeException(“转出账户不存在”);
}
// 增加转入账户余额
int addRows = accountMapper.addBalance(toAccountId, amount);
if (addRows == 0) {
throw new RuntimeException(“转入账户不存在”);
}
System.out.println(“转账成功”);
}
}
@Mapper
public interface AccountMapper {
@Update(“UPDATE fgedu.accounts SET balance = balance – #{amount} WHERE id = #{id}”)
int deductBalance(@Param(“id”) int id, @Param(“amount”) double amount);
@Update(“UPDATE fgedu.accounts SET balance = balance + #{amount} WHERE id = #{id}”)
int addBalance(@Param(“id”) int id, @Param(“amount”) double amount);
}
执行结果:
转账成功
转账成功
转账成功
Part04-生产案例与实战讲解
4.1 SQLServer Java集成案例
集成实战:
spring.application.name=fgedu-app
# 数据库连接配置
spring.datasource.url=jdbc:sqlserver://fgedu-server:1433;databaseName=fgedudb;encrypt=true;trustServerCertificate=true;
spring.datasource.username=fgedu
spring.datasource.password=Password123!
# HikariCP连接池配置
spring.datasource.hikari.maximum-pool-size=50
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.idle-timeout=60000
spring.datasource.hikari.connection-timeout=30000
# 日志配置
logging.level.org.springframework.jdbc.core=DEBUG
public class LargeTable {
private int id;
private String col1;
private String col2;
// getters and setters
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getCol1() { return col1; }
public void setCol1(String col1) { this.col1 = col1; }
public String getCol2() { return col2; }
public void setCol2(String col2) { this.col2 = col2; }
}
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class LargeTableRepository {
private final JdbcTemplate jdbcTemplate;
public LargeTableRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public LargeTable findById(int id) {
String sql = “SELECT Id, Col1, Col2 FROM fgedu.large_table WHERE Id = ?”;
return jdbcTemplate.queryForObject(sql, new Object[]{id}, (rs, rowNum) -> {
LargeTable table = new LargeTable();
table.setId(rs.getInt(“Id”));
table.setCol1(rs.getString(“Col1”));
table.setCol2(rs.getString(“Col2”));
return table;
});
}
public List
String sql = “SELECT Id, Col1, Col2 FROM fgedu.large_table”;
return jdbcTemplate.query(sql, (rs, rowNum) -> {
LargeTable table = new LargeTable();
table.setId(rs.getInt(“Id”));
table.setCol1(rs.getString(“Col1”));
table.setCol2(rs.getString(“Col2”));
return table;
});
}
public void save(LargeTable table) {
String sql = “INSERT INTO fgedu.large_table (Col1, Col2) VALUES (?, ?)”;
jdbcTemplate.update(sql, table.getCol1(), table.getCol2());
}
public void update(LargeTable table) {
String sql = “UPDATE fgedu.large_table SET Col1 = ?, Col2 = ? WHERE Id = ?”;
jdbcTemplate.update(sql, table.getCol1(), table.getCol2(), table.getId());
}
public void delete(int id) {
String sql = “DELETE FROM fgedu.large_table WHERE Id = ?”;
jdbcTemplate.update(sql, id);
}
}
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class LargeTableService {
private final LargeTableRepository repository;
public LargeTableService(LargeTableRepository repository) {
this.repository = repository;
}
public LargeTable getById(int id) {
return repository.findById(id);
}
public List
return repository.findAll();
}
@Transactional
public void create(LargeTable table) {
repository.save(table);
}
@Transactional
public void update(LargeTable table) {
repository.update(table);
}
@Transactional
public void delete(int id) {
repository.delete(id);
}
}
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping(“/api/large-table”)
public class LargeTableController {
private final LargeTableService service;
public LargeTableController(LargeTableService service) {
this.service = service;
}
@GetMapping
public List
return service.getAll();
}
@GetMapping(“/{id}”)
public LargeTable getById(@PathVariable int id) {
return service.getById(id);
}
@PostMapping
public void create(@RequestBody LargeTable table) {
service.create(table);
}
@PutMapping(“/{id}”)
public void update(@PathVariable int id, @RequestBody LargeTable table) {
table.setId(id);
service.update(table);
}
@DeleteMapping(“/{id}”)
public void delete(@PathVariable int id) {
service.delete(id);
}
}
./mvnw spring-boot:run
执行结果:
[INFO] Scanning for projects…
[INFO]
[INFO] ————————–< com.fgedu:fgedu-app >————————–
[INFO] Building fgedu-app 1.0.0
[INFO] ——————————–[ jar ]———————————
[INFO]
[INFO] >>> spring-boot-maven-plugin:3.2.0:run (default-cli) > test-compile @ fgedu-app >>>
[INFO]
[INFO] — maven-resources-plugin:3.3.1:resources (default-resources) @ fgedu-app —
[INFO] Copying 1 resource
[INFO]
[INFO] — maven-compiler-plugin:3.11.0:compile (default-compile) @ fgedu-app —
[INFO] Changes detected – recompiling the module!
[INFO] Compiling 4 source files to /home/user/fgedu-app/target/classes
[INFO]
[INFO] — maven-resources-plugin:3.3.1:testResources (default-testResources) @ fgedu-app —
[INFO] skip non existing resourceDirectory /home/user/fgedu-app/src/test/resources
[INFO]
[INFO] — maven-compiler-plugin:3.11.0:testCompile (default-testCompile) @ fgedu-app —
[INFO] No sources to compile
[INFO]
[INFO] <<< spring-boot-maven-plugin:3.2.0:run (default-cli) < test-compile @ fgedu-app <<< [INFO] [INFO] [INFO] --- spring-boot-maven-plugin:3.2.0:run (default-cli) @ fgedu-app --- [INFO] Attaching agents: [] [INFO] . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.2.0) 2025-04-08 10:00:00.000 INFO 12345 --- [ main] com.fgedu.FgeduAppApplication : Starting FgeduAppApplication using Java 11.0.20 on fgedu-server with PID 12345 (/home/user/fgedu-app/target/classes started by user in /home/user/fgedu-app) 2025-04-08 10:00:00.000 INFO 12345 --- [ main] com.fgedu.FgeduAppApplication : No active profile set, falling back to 1 default profile: "default" 2025-04-08 10:00:00.000 INFO 12345 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode. 2025-04-08 10:00:00.000 INFO 12345 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 10 ms. Found 0 JDBC repository interfaces. 2025-04-08 10:00:00.000 INFO 12345 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2025-04-08 10:00:00.000 INFO 12345 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2025-04-08 10:00:00.000 INFO 12345 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.16] 2025-04-08 10:00:00.000 INFO 12345 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2025-04-08 10:00:00.000 INFO 12345 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1234 ms 2025-04-08 10:00:00.000 INFO 12345 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2025-04-08 10:00:00.000 INFO 12345 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2025-04-08 10:00:00.000 INFO 12345 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2025-04-08 10:00:00.000 INFO 12345 --- [ main] com.fgedu.FgeduAppApplication : Started FgeduAppApplication in 2.345 seconds (JVM running for 2.678)
$ curl http://localhost:8080/api/large-table
[{“id”:1,”col1″:”test1″,”col2″:”value1″},{“id”:2,”col1″:”test2″,”col2″:”value2″}]
$ curl http://localhost:8080/api/large-table/1
{“id”:1,”col1″:”test1″,”col2″:”value1″}
$ curl -X POST http://localhost:8080/api/large-table -H “Content-Type: application/json” -d ‘{“col1″:”test3″,”col2″:”value3”}’
$ curl -X PUT http://localhost:8080/api/large-table/3 -H “Content-Type: application/json” -d ‘{“col1″:”test3″,”col2″:”updated3”}’
$ curl -X DELETE http://localhost:8080/api/large-table/3
4.2 SQLServer Java性能优化案例
性能优化实战:
public void batchInsert(List
String connectionUrl = “jdbc:sqlserver://fgedu-server:1433;databaseName=fgedudb;encrypt=true;trustServerCertificate=true;”;
String username = “fgedu”;
String password = “Password123!”;
try (Connection connection = DriverManager.getConnection(connectionUrl, username, password);
PreparedStatement statement = connection.prepareStatement(“INSERT INTO fgedu.large_table (Col1, Col2) VALUES (?, ?)”)) {
connection.setAutoCommit(false);
for (LargeTable table : tables) {
statement.setString(1, table.getCol1());
statement.setString(2, table.getCol2());
statement.addBatch();
}
int[] results = statement.executeBatch();
connection.commit();
System.out.println(“批量插入成功,影响行数:” + results.length);
}
}
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
public class DataSourceUtil {
private static HikariDataSource dataSource;
static {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(“jdbc:sqlserver://fgedu-server:1433;databaseName=fgedudb;encrypt=true;trustServerCertificate=true;”);
config.setUsername(“fgedu”);
config.setPassword(“Password123!”);
config.setMaximumPoolSize(100);
config.setMinimumIdle(10);
config.setIdleTimeout(60000);
config.setConnectionTimeout(30000);
config.setMaxLifetime(1800000);
dataSource = new HikariDataSource(config);
}
public static HikariDataSource getDataSource() {
return dataSource;
}
}
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;
public class LargeTableCache {
private static final Cache
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
public static LargeTable get(int id) {
return cache.getIfPresent(id);
}
public static void put(int id, LargeTable table) {
cache.put(id, table);
}
public static void invalidate(int id) {
cache.invalidate(id);
}
public static void invalidateAll() {
cache.invalidateAll();
}
}
import java.util.concurrent.CompletableFuture;
public CompletableFuture> getAllAsync() {
return CompletableFuture.supplyAsync(() -> {
try {
return jdbcTemplate.query(“SELECT Id, Col1, Col2 FROM fgedu.large_table”, (rs, rowNum) -> {
LargeTable table = new LargeTable();
table.setId(rs.getInt(“Id”));
table.setCol1(rs.getString(“Col1”));
table.setCol2(rs.getString(“Col2”));
return table;
});
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
— 在数据库中创建索引
CREATE INDEX IX_large_table_col1 ON fgedu.large_table(Col1);
执行结果:
4.3 SQLServer Java故障处理案例
故障处理实战:
public class RetryUtil {
public static
int retries = 0;
while (true) {
try {
return supplier.get();
} catch (SQLException e) {
// 连接错误,重试
if (isConnectionError(e) && retries < maxRetries) { retries++; long delay = baseDelayMs * (1 << (retries - 1)); // 指数退避 try { Thread.sleep(delay); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw new RuntimeException(ie); } continue; } throw e; } } } private static boolean isConnectionError(SQLException e) { int errorCode = e.getErrorCode(); return errorCode == 10054 || errorCode == 10060 || errorCode == 233; } }
public class TimeoutUtil {
public static
CompletableFuture
try {
return future.get(timeoutMs, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
future.cancel(true);
throw new RuntimeException(“操作超时”, e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LargeTableService {
private static final Logger logger = LoggerFactory.getLogger(LargeTableService.class);
private final LargeTableRepository repository;
public LargeTableService(LargeTableRepository repository) {
this.repository = repository;
}
public LargeTable getById(int id) {
try {
return repository.findById(id);
} catch (Exception e) {
logger.error(“获取大表数据失败,ID: {}”, id, e);
throw new RuntimeException(“获取数据失败”, e);
}
}
}
@Service
public class AccountService {
private final JdbcTemplate jdbcTemplate;
private static final Logger logger = LoggerFactory.getLogger(AccountService.class);
public AccountService(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Transactional(rollbackFor = Exception.class)
public void transferFunds(int fromAccountId, int toAccountId, double amount) {
try {
// 扣除转出账户余额
String deductSql = “UPDATE fgedu.accounts SET balance = balance – ? WHERE id = ?”;
int deductRows = jdbcTemplate.update(deductSql, amount, fromAccountId);
if (deductRows == 0) {
throw new RuntimeException(“转出账户不存在”);
}
// 增加转入账户余额
String addSql = “UPDATE fgedu.accounts SET balance = balance + ? WHERE id = ?”;
int addRows = jdbcTemplate.update(addSql, amount, toAccountId);
if (addRows == 0) {
throw new RuntimeException(“转入账户不存在”);
}
System.out.println(“转账成功”);
} catch (Exception e) {
logger.error(“转账失败,从账户{}到账户{},金额{}”, fromAccountId, toAccountId, amount, e);
throw e;
}
}
}
执行结果:
Part05-风哥经验总结与分享
5.1 SQLServer Java集成最佳实践
SQLServer Java集成最佳实践:
- 选择合适的驱动:使用官方的Microsoft JDBC Driver for SQL Server
- 使用连接池:选择高性能的连接池如HikariCP
- 使用参数化查询:避免SQL注入并提高性能
- 实现事务管理:确保数据操作的一致性和完整性
- 添加错误处理:提高应用的可靠性和容错能力
- 使用缓存:减少数据库访问,提高应用性能
- 优化SQL语句:提高查询效率,减少数据库负载
- 使用批处理:对于大量数据操作,使用批处理提高性能
更多视频教程www.fgedu.net.cn
5.2 SQLServer Java常见问题
常见问题:
- 连接超时:检查网络连接、SQLServer服务状态和连接字符串配置
- 连接池耗尽:检查连接是否正确释放,调整连接池大小
- SQL注入:使用参数化查询和存储过程
- 性能问题:优化SQL语句、使用索引、实现缓存
- 事务死锁:优化事务范围,避免长时间锁定资源
- 内存泄漏:确保正确释放数据库连接和资源
学习交流加群风哥微信: itpux-com
5.3 SQLServer Java性能优化
性能优化:
- 使用批量操作:对于大量数据操作,使用批处理提高性能
- 实现数据分页:避免一次返回过多数据
- 使用索引:为常用查询字段创建索引
- 优化连接池配置:根据应用规模和并发需求配置连接池
- 使用异步编程:充分利用系统资源,提高并发处理能力
- 监控和分析:使用性能监控工具分析瓶颈,针对性优化
学习交流加群风哥QQ113257174
风哥提示:SQLServer与Java的集成是企业应用开发的重要组成部分,合理的集成方案和性能优化策略可以显著提高应用的可靠性和性能。
更多学习教程公众号风哥教程itpux_com
from SQLServer视频:www.itpux.com
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
