1. 首页 > SQLServer教程 > 正文

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集成配置

集成配置:




com.microsoft.sqlserver
mssql-jdbc
12.4.0.jre11


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());
}
}
}

执行结果:

$ mvn dependency:tree
[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 getAll() throws SQLException {
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 result = new ArrayList<>();
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 getAll() {
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);
}
}




org.mybatis.spring.boot
mybatis-spring-boot-starter
3.0.3


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 getAll();

@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 findAll() {
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 getAll() {
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 getAll() {
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







执行结果:

$ ./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 tables) throws SQLException {
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 cache = CacheBuilder.newBuilder()
.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 T executeWithRetry(Supplier supplier, int maxRetries, long baseDelayMs) {
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 T executeWithTimeout(Supplier supplier, long timeoutMs) {
CompletableFuture future = CompletableFuture.supplyAsync(supplier);
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

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息