13. SQL Server 2014
现在,我们将把在 MySQL 上所做的操作移植到 SQL Server 2014 上。
![]() |
13.1. 工作环境的搭建
13.1.1. Eclipse 环境
我们将使用以下 Eclipse 环境进行工作:
![]() |
上述 SQL Server 项目位于 [<exemples>/spring-database-config\sqlserver\eclipse] 文件夹中。
注意:执行 [Alt-F5] 可重新生成所有 Maven 项目。
13.1.2. 数据库生成
与 Oracle 和 DB2 的操作类似,我们需要将 SQL Server 的驱动程序 JDBC 安装到本地 Maven 仓库中。
文件 [install.bat] 包含以下代码:
"%M2_HOME%\bin\mvn.bat" install:install-file -Dfile=sqljdbc4-3.0.jar -Dpackaging=jar -DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc4 -Dversion=4.0
其中 [%M2-HOME%] 是 Maven 的安装目录(参见第 23.2 节,第 466 页)。 安装完成后,可在 [pom.xml] 文件中通过以下依赖项引用 JDBC 驱动程序(来自 SQL Server):
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
</dependency>
此后,连接 SQL 和 SERVER 数据库均使用 [sa / msde] 凭据。 启动 SQL 服务器及其客户端 [MsManager](参见第 23.9 节)。
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() |
- 在 [1] 中,加载脚本 SQL [<exemples>\spring-database-config\sqlserver\databases\dbproduits.sql] ;
![]() | ![]() |
![]() |
- 在 [2] 中,无法将 [PRODUITS] 表用于 [spring-jdbc-01 à 03] 项目。原因是:
- [spring-jdbc-01 et 02]项目插入的行带有主键;
- 而项目 [spring-jdbc-03] 插入的行不包含主键,并期望由 SGBD 生成这些主键。 为此,[ID]的主键必须为[Identity]类型。 然而,SQL Server 中的该类型仅支持自动生成主键,不允许插入带有用户指定主键的行。因此会报错,而我未能找到解决方法。 [spring-jdbc-01 et 02] 项目使用 [PRODUITS] 表,该表不支持自动生成主键。[spring-jdbc-03] 项目使用 [PRODUITS2] 表,该表支持自动生成主键。
现在,请执行以下配置:
- [spring-jdbc-generic-01.IntroJdbc01];
- [spring-jdbc-generic-01.IntroJdbc02] ;
- [spring-jdbc-generic-03.JUnitTestDao1];
- [spring-jdbc-generic-03.JUnitTestDao2] ;
所有配置都应成功。
现在生成 [dbproduitscategories] 数据库。请针对 [dbproduitscategories] 重复执行创建 [dbproduits] 时所用的步骤。 待加载的脚本 SQL 位于 [<exemples>\spring-database-config\sqlserver\databases\ dbproduitscategories.sql] 位置;
![]() |
现在,执行以下配置:
- [spring-jdbc-generic-04.JUnitTestDao];
- [spring-jpa-generic-JUnitTestDao-openjpa];
这两项配置都应成功。
13.2. JDBC 层配置
![]() | ![]() |
项目 [sqlserver-config-jdbc] 配置了以下测试架构中的 [JDBC] 层:
![]() |
该项目与 SGBD MySQL 架构中 JDBC 层的配置项目 [mysql-config-jdbc] 类似(参见第 3.3 节)。此处仅列出修改内容:
文件 [pom.xml] 导入了来自 SQL 服务器的驱动程序 JDBC:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>dvp.spring.database</groupId>
<artifactId>generic-config-jdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>configuration generic jdbc</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.3.RELEASE</version>
</parent>
<dependencies>
<!-- 变量依赖项 ********************************************** -->
<!-- SGBD 的驱动程序 JDBC -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
</dependency>
<!-- 常量依赖项 ********************************************** -->
...
</dependencies>
...
</project>
- 第 18-22 行:来自 SQL 服务器的驱动程序 JDBC;
第二个修改位于 [ConfigJdbc] 类中,该类定义了数据库的访问凭据:
// 连接参数
public final static String DRIVER_CLASSNAME = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
public final static String URL_DBPRODUITS = "jdbc:sqlserver://localhost\\SQLEXPRESS:1433;databaseName=dbproduits";
public final static String USER_DBPRODUITS = "sa";
public final static String PASSWD_DBPRODUITS = "msde";
public final static String URL_DBPRODUITSCATEGORIES = "jdbc:sqlserver://localhost\\SQLEXPRESS:1433;databaseName=dbproduitscategories";
public final static String USER_DBPRODUITSCATEGORIES = "sa";
public final static String PASSWD_DBPRODUITSCATEGORIES = "msde";
第三项可进行的修改是调整 [PreparedStatement] 所能支持的参数最大数量:
// [PreparedStatement] 的最大参数数
public final static int MAX_PREPAREDSTATEMENT_PARAMETERS = 2000;
测试[JUnitTestPushTheLimits]针对5000种产品生成订单SQL,这些订单将生成包含5000个参数的[PreparedStatement]。MySQL此前已支持该数值。 SQL 服务器报错,指出该限制为 2100。
第四项修改涉及项目 [spring-jdbc-03] 所使用的表。该表已从 [PRODUITS] 更改为 [PRODUITS2]:
// 命令 SQL [jdbc-03]
public final static String V2_INSERT_PRODUITS = "INSERT INTO PRODUITS2(NOM, CATEGORIE, PRIX, DESCRIPTION) VALUES (?, ?, ?, ?)";
public final static String V2_DELETE_ALLPRODUITS = "DELETE FROM PRODUITS2";
public final static String V2_DELETE_PRODUITS = "DELETE FROM PRODUITS2 WHERE ID=?";
public final static String V2_SELECT_ALLPRODUITS = "SELECT ID, NOM, CATEGORIE, PRIX, DESCRIPTION FROM PRODUITS2";
public final static String V2_SELECT_PRODUIT_BYID = "SELECT NOM, CATEGORIE, PRIX, DESCRIPTION FROM PRODUITS2 WHERE ID=?";
public final static String V2_SELECT_PRODUIT_BYNAME = "SELECT ID, CATEGORIE, PRIX, DESCRIPTION FROM PRODUITS2 WHERE NOM=?";
public final static String V2_UPDATE_PRODUITS = "UPDATE PRODUITS2 SET NOM=?, PRIX=?, CATEGORIE=?, DESCRIPTION=? WHERE ID=?";
13.3. JPA 层的配置 OpenJpa
![]() | ![]() |
项目 [sqlserver-config-jpa-openjpa] 配置了测试架构中的 [JPA] 层:
![]() |
该项目与 SGBD MySQL 层中的 JPA OpenJpa 配置项目 [mysql-config-jpa-openjpa] 类似 (参见第8.3节)。实际上,这两个SGBD项目都使用[@GeneratedValue(strategy = GenerationType.IDENTITY)]注解来生成主键。 需要进行两处修改。修改位于 [ConfigJpa] 类的 [jpaVendorAdapter] Bean 定义中:
// 提供商 JPA
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
OpenJpaVendorAdapter openJpaVendorAdapter = new OpenJpaVendorAdapter();
openJpaVendorAdapter.setShowSql(false);
openJpaVendorAdapter.setDatabase(Database.SQL_SERVER);
openJpaVendorAdapter.setGenerateDdl(true);
return openJpaVendorAdapter;
}
- 第 6 行:告知实现类 JPA 它将与 SQL 服务器数据库配合工作。 JPA 实现将采用该 SGBD 的专有数据类型及其所属的 SQL。
第二项修改涉及与表 [PRODUITS] 和 [PRODUITS2] 关联的实体 JPA:
![]() |
实体 [Produit] 关联于表 [PRODUITS],且不自动生成主键(未标注 [@GeneratedValue]):
@Entity(name = "Produit1")
@Table(name = ConfigJdbc.TAB_PRODUITS)
public class Produit {
// 字段
@Id
@Column(name = ConfigJdbc.TAB_PRODUITS_ID)
private Long id;
实体 [Produit2] 关联到表 [PRODUITS2],并自动生成主键:
@Entity(name = "Produit2")
@Table(name = ConfigJdbc.TAB_PRODUITS2)
public class Produit2 {
// 字段
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = ConfigJdbc.TAB_PRODUITS_ID)
private Long id;
此外,生成数据库 [dbproduits] 的项目需进行修改,以表明该数据库中现包含两个 JPA 实体:
![]() |
文件 [persistence.xml] 的变更如下:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="generic-jpa-entities-dbproduits" transaction-type="RESOURCE_LOCAL">
<!-- 实体 JPA -->
<class>generic.jpa.entities.dbproduits.Produit</class>
<class>generic.jpa.entities.dbproduits.Produit2</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>
项目 [generic-create-dbproduits] 是所有 SGBD 的共同基础。此前研究对象中的 JPA 层不包含实体 [Produit2]。 因此,人们可能会质疑:引用一个不存在的 JPA 实体是否会导致这些 SGBD 项目崩溃。测试表明并非如此。
完成这些修改后,[spring-jpa-generic-JUnitTestDao-openjpa]配置的执行应能成功。
![]() | ![]() |
13.4. Hibernate 层配置 JPA
![]() | ![]() |
注:执行 [Alt-F5] 以重新生成所有 Maven 项目。
项目 [sqlserver-config-jpa-hibernate] 与项目 [mysql-config-jpa-hibernate](第 6.3 节)类似,采用了与将 [mysql-config-jpa-openjpa] 移植到项目 [sqlserver-config-jpa-openjpa] 时相同的修改 (第 8.3 节)。
完成这些修改后,[spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] 的配置执行应能成功。
13.5. JPA 层的配置 EclipseLink
![]() | ![]() |
注:执行 [Alt-F5] 以重新生成所有 Maven 项目。
项目 [sqlserver-config-jpa-eclipselink] 与项目 [mysql-config-jpa-eclipselink](第 7.3 节)类似 并采用了与将 [mysql-config-jpa-openjpa] 移植到 [sqlserver-config-jpa-openjpa] 项目(第 8.3 节)时相同的修改。
完成这些修改后,[spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] 的配置应能成功执行。






























