Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Samples and add new samples for new features #761

Merged
merged 5 commits into from
Jul 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 62 additions & 59 deletions src/samples/README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,62 @@
## Overview
The Microsoft JDBC Driver for SQL Server sample applications demonstrate various features of the JDBC driver. Additionally, they demonstrate good programming practices that you can follow when using the JDBC driver with SQL Server or Azure SQL Database.

All the sample applications are contained in *.java code files that can be compiled and run on your local computer. These code samples are based on the ones found in [MSDN](https://msdn.microsoft.com/en-us/library/aa342346(v=sql.110).aspx), where you can find additional content with more detailed descriptions.

The following samples are available:

1. adaptive
* **executeStoredProcedure** - how to retrieve a large OUT parameter from a stored procedure and use adaptive buffering mode.
* **readLargeData** - how to read large data and use adaptive buffering mode. It also demonstrates how to retrieve a large single-column value from by using the getCharacterStream method.
* **updateLargeData** - how to update large data and set the adaptive buffering mode explicitly for updatable result sets.

2. alwaysencrypted
* **AlwaysEncrypted** - how to create Column Master Key and Column Encryption Key for use with the Java Key Store for Always Encrypted feature.

3. azureactivedirectoryauthentication
* **AzureActiveDirectoryAuthentication** - how to connect to Azure SQL Databases using identities in Azure Active Directory.

4. connections
* **connectDS** - how to connect using a data source object and retrieve data using a stored procedure.
* **connectURL** - how to connect using a connection URL and retrieve data using an SQL statement.

5. datatypes
* **basicDT** - how to retrieve and update basic SQL Server data type values.
* **sqlxmlExample** - how to store and retrieve XML data as well as how to parse XML data with the SQLXML Java data type.

6. resultsets
* **cacheRS** - how to retrieve a large set of data and control the amount of data that is fetched and cached on the client
* **retrieveRS** - how to use a result set to retrieve a basic set of data.
* **updateRS** - how to use an updatable result set to insert, update, and delete a row of data.

7. sparse
* **SparseColumns** - how to detect column sets. It also shows a technique for parsing a column set's XML output, to get data from the sparse columns.

8. constrained
* **ConstrainedSample** - how to connect with Kerberos constrained delegation using an impersonated credential.


## Running Samples

###Prerequisites
* Java 8
* [Maven](http://maven.apache.org/download.cgi)
* An instance of SQL Server or SQL Azure Database that you can connect to.

###Using Maven

To run a sample, you need to provide Maven with the appropriate profile ID so that it knows which sample to run. To find them, open the associated POM file and look for the <id> elements within the <profile> section. For example, in \src\samples\adaptive\pom.xml, you will find: executeStoredProcedure, readLargeData and updateLargeData.

To run a specific sample, go to the directory that contains the sample's POM file and run the following commands:

* `mvn install -PprofileID` to compile the sample
* `mvn exec:java -PprofileID` to run the sample under the current directory.

For example, if you wish to compile and run the executeStoredProcedure sample you can run:

* `mvn install -PexecuteStoredProcedure`
* `mvn exec:java -PexecuteStoredProcedure`


# Running Sample Applications

The Microsoft JDBC Driver for SQL Server sample applications demonstrate various features of the JDBC driver. Additionally, they demonstrate good programming practices that you can follow when using the JDBC driver with SQL Server or Azure SQL Database.

All the sample applications are contained in *.java code files that can be compiled and run on your local computer. These code samples are based on the ones found in [Microsoft Docs](https://docs.microsoft.com/en-us/sql/connect/jdbc/sample-jdbc-driver-applications), where you can find additional content with more detailed descriptions.

The following samples are available:

1. adaptive
* **ExecuteStoredProcedures** - Demonstrates how to retrieve a large OUT parameter from a stored procedure and use adaptive buffering mode.
* **ReadLargeData** - Demonstrates how to read large data and use adaptive buffering mode. It also demonstrates how to retrieve a large single-column value from by using the getCharacterStream method.
* **UpdateLargeData** - Demonstrates how to update large data and set the adaptive buffering mode explicitly for updatable result sets.

2. alwaysencrypted
* **AlwaysEncrypted** - Demonstrates how to create Column Master Key and Column Encryption Key for use with the Java Key Store for Always Encrypted feature.

3. azureactivedirectoryauthentication
* **AzureActiveDirectoryAuthentication** - Demonstrates how to connect to Azure SQL Databases using identities in Azure Active Directory.

4. connections
* **ConnectDS** - Demonstrates how to connect using a data source object and retrieve data using a stored procedure.
* **ConnectURL** - Demonstrates how to connect using a connection URL and retrieve data using an SQL statement.

5. datatypes
* **BasicDataTypes** - Demonstrates how to retrieve and update basic SQL Server data type values.
* **SqlXmlDataType** - Demonstrates how to store and retrieve XML data as well as how to parse XML data with the SQLXML Java data type.
* **SpatialDatatypes** - Demonstrates how to store and retreive Spatial Data as well how to parse data using `Geometry` and `Geography` Java types defined by Microsoft JDBC Driver.

6. resultsets
* **CacheRS** - Demonstrates how to retrieve a large set of data and control the amount of data that is fetched and cached on the client
* **RetrieveRS** - Demonstrates how to use a result set to retrieve a basic set of data.
* **UpdateRS** - Demonstrates how to use an updatable result set to insert, update, and delete a row of data.

7. sparse
* **SparseColumns** - Demonstrates how to detect column sets. It also shows a technique for parsing a column set's XML output, to get data from the sparse columns.

8. constrained
* **ConstrainedDelegation** - Demonstrates how to connect with Kerberos constrained delegation using an impersonated credential.

## Running Samples

### Pre-Requisites

* Java 10
* [Maven](http://maven.apache.org/download.cgi)
* An instance of SQL Server or SQL Azure Database that you can connect to.

### Using Maven

To run a sample, you need to provide Maven with the appropriate profile ID so that it knows which sample to run. To find them, open the associated POM file and look for the `<id>` elements within the `<profile>` section. For example, in `\src\samples\adaptive\pom.xml`, you will find: _ExecuteStoredProcedures_, _ReadLargeData_ and _UpdateLargeData_.

To run a specific sample, go to the directory that contains the sample's POM file and run the following commands:

* `mvn install -PprofileID` to compile the sample
* `mvn exec:java -PprofileID` to run the sample under the current directory.

For example, if you wish to compile and run the _ExecuteStoredProcedures_ sample you can run:

* `mvn install -PExecuteStoredProcedures`
* `mvn exec:java -PExecuteStoredProcedures`

41 changes: 14 additions & 27 deletions src/samples/adaptive/pom.xml
Original file line number Diff line number Diff line change
@@ -1,101 +1,88 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.microsoft.sqlserver.jdbc</groupId>
<artifactId>adaptive</artifactId>
<version>0.0.1</version>

<packaging>jar</packaging>

<name>${project.artifactId}</name>
<url>https://github.com/Microsoft/mssql-jdbc/tree/master/src/samples</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.4.0.jre9</version>
<version>7.0.0.jre10</version>
</dependency>
</dependencies>

<profiles>
<profile>
<id>executeStoredProcedure</id>
<id>ExecuteStoredProcedures</id>
<build>
<finalName>executeStoredProcedure</finalName>

<finalName>ExecuteStoredProcedures</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>adaptive.src.main.java.executeStoredProcedure</mainClass>
<mainClass>adaptive.src.main.java.ExecuteStoredProcedures</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</profile>

<profile>
<id>readLargeData</id>
<id>ReadLargeData</id>
<build>
<finalName>readLargeData</finalName>

<finalName>ReadLargeData</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>adaptive.src.main.java.readLargeData</mainClass>
<mainClass>adaptive.src.main.java.ReadLargeData</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</profile>

<profile>
<id>updateLargeData</id>
<id>UpdateLargeData</id>
<build>
<finalName>updateLargeData</finalName>

<finalName>UpdateLargeData</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>adaptive.src.main.java.updateLargeData</mainClass>
<mainClass>adaptive.src.main.java.UpdateLargeData</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
<source>10</source>
<target>10</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
</plugin>
</plugins>
</build>

</project>
151 changes: 151 additions & 0 deletions src/samples/adaptive/src/main/java/ExecuteStoredProcedures.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Microsoft JDBC Driver for SQL Server Copyright(c) Microsoft Corporation All rights reserved. This program is made
* available under the terms of the MIT License. See the LICENSE file in the project root for more information.
*/
package adaptive.src.main.java;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerCallableStatement;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;

/**
* Sample application to demonstrate how to retrieve a large OUT parameter from
* a stored procedure and how to get the adaptive buffering mode.
*/
public class ExecuteStoredProcedures {

public static void main(String[] args) {

String serverName = null;
String portNumber = null;
String databaseName = null;
String username = null;
String password = null;

try (InputStreamReader in = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(in)) {

System.out.print("Enter server name: ");
serverName = br.readLine();
System.out.print("Enter port number: ");
portNumber = br.readLine();
System.out.print("Enter database name: ");
databaseName = br.readLine();
System.out.print("Enter username: ");
username = br.readLine();
System.out.print("Enter password: ");
password = br.readLine();

// Establish the connection.
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName(serverName);
ds.setPortNumber(Integer.parseInt(portNumber));
ds.setDatabaseName(databaseName);
ds.setUser(username);
ds.setPassword(password);

try (Connection con = ds.getConnection(); Statement stmt = con.createStatement()) {

createTable(stmt);
createStoredProcedure(stmt);

// Create test data as an example.
StringBuffer buffer = new StringBuffer(4000);
for (int i = 0; i < 4000; i++)
buffer.append((char) ('A'));

try (PreparedStatement pstmt = con.prepareStatement(
"UPDATE Document_JDBC_Sample " + "SET DocumentSummary = ? WHERE (DocumentID = 1)")) {

pstmt.setString(1, buffer.toString());
pstmt.executeUpdate();
}

// Query test data by using a stored procedure.
try (SQLServerCallableStatement cstmt = (SQLServerCallableStatement) con
.prepareCall("{call GetLargeDataValue(?, ?, ?, ?)}")) {

cstmt.setInt(1, 1);
cstmt.registerOutParameter(2, java.sql.Types.INTEGER);
cstmt.registerOutParameter(3, java.sql.Types.CHAR);
cstmt.registerOutParameter(4, java.sql.Types.LONGVARCHAR);

// Display the response buffering mode.
System.out.println("Response buffering mode is: " + cstmt.getResponseBuffering());

cstmt.execute();
System.out.println("DocumentID: " + cstmt.getInt(2));
System.out.println("Document_Title: " + cstmt.getString(3));

try (Reader reader = cstmt.getCharacterStream(4)) {

// If your application needs to re-read any portion of the value,
// it must call the mark method on the InputStream or Reader to
// start buffering data that is to be re-read after a subsequent
// call to the reset method.
reader.mark(4000);

// Read the first half of data.
char output1[] = new char[2000];
reader.read(output1);
String stringOutput1 = new String(output1);

// Reset the stream.
reader.reset();

// Read all the data.
char output2[] = new char[4000];
reader.read(output2);
String stringOutput2 = new String(output2);

System.out.println("Document_Summary in half: " + stringOutput1);
System.out.println("Document_Summary: " + stringOutput2);
}
}
}
}
// Handle any errors that may have occurred.
catch (Exception e) {
e.printStackTrace();
}
}

private static void createStoredProcedure(Statement stmt) throws SQLException {
String outputProcedure = "GetLargeDataValue";

String sql = " IF EXISTS (select * from sysobjects where id = object_id(N'" + outputProcedure
+ "') and OBJECTPROPERTY(id, N'IsProcedure') = 1)" + " DROP PROCEDURE " + outputProcedure;
stmt.execute(sql);

sql = "CREATE PROCEDURE " + outputProcedure + " @p0 int, @p1 int OUTPUT, @p2 char(50) OUTPUT, "
+ "@p3 varchar(max) OUTPUT " + " AS" + " SELECT top 1 @p1=DocumentID, @p2=Title,"
+ " @p3=DocumentSummary FROM Document_JDBC_Sample where DocumentID = @p0";

stmt.execute(sql);
}

private static void createTable(Statement stmt) throws SQLException {
stmt.execute("if exists (select * from sys.objects where name = 'Document_JDBC_Sample')"
+ "drop table Document_JDBC_Sample");

String sql = "CREATE TABLE Document_JDBC_Sample(" + "[DocumentID] [int] NOT NULL identity,"
+ "[Title] [char](50) NOT NULL," + "[DocumentSummary] [varchar](max) NULL)";

stmt.execute(sql);

sql = "INSERT Document_JDBC_Sample VALUES ('title1','summary1') ";
stmt.execute(sql);

sql = "INSERT Document_JDBC_Sample VALUES ('title2','summary2') ";
stmt.execute(sql);

sql = "INSERT Document_JDBC_Sample VALUES ('title3','summary3') ";
stmt.execute(sql);
}
}
Loading