Драйвер tibcosoftwareinc.jdbc.sqlserver.SQLServerDriver поставляется с установкой Tibco BW. Похоже, что tibco tibcosoftwareinc.jdbc.sqlserver.SQLServerDriver драйвер не был установлен в вашей среде.
Если вы хотите использовать sqljdbc42.jar, вам нужно указать правильный класс драйвера jdbc в конфигурации соединения Tibco в поле «Драйвер JDBC» (см. Скриншот).
Для sqljdbc42.jar «Драйвер JDBC» равен
com.microsoft.sqlserver.jdbc.SQLServerDriver
, вы можете найти класс драйвера JDBC Пример имени и строки подключения в https://docs.microsoft.com/en-us/sql/connect/jdbc/using-the-jdbc-driver?view=sql-server-2017
строка подключения должна выглядеть следующим образом:
jdbc:sqlserver://localhost:1433;databaseName=AdventureWorks;user=MyUserName;password=*****;
, как вы сказали, вам нужно добавить sqljdbc42.jar в папку C: \ tibco \ tpcl \ 5.x \ jdbc. Папка C: \ tibco \ bw \ 5.x \ lib также работает.
Вам нужно перезапустить конструктор после добавления банок.
Ваша проблема подобна решенному "помощником получения", но я не уверен, что она может быть применена к Вашему второму примеру, где два отдельных метода используются. Ваше первое doStuff
метод мог определенно быть лучше записан как public void doStuff(Foo<?> foo)
, так как это работает независимо от Foo
введите параметр. Затем "шаблон" помощника получения был бы полезен.
Обновление: после лужения немного, расширяя идею помощника получения Goetz, я придумал это. Внутри, это выглядит немного грязным; с внешней стороны Вы не подозревали бы вещь.
public class Bar {
private final Helper<?> helper;
public Bar(Foo<?> foo) {
this.helper = Helper.create(foo);
}
public void startStuff() {
helper.startStuff();
}
public void finishStuff() {
helper.finishStuff();
}
private static class Helper<T> {
private final Foo<T> foo;
private T t;
private Helper(Foo<T> foo) {
this.foo = foo;
}
static <T> Helper<T> create(Foo<T> foo) {
return new Helper<T>(foo);
}
void startStuff() {
t = foo.getOne();
}
void finishStuff() {
foo.useOne(t);
}
}
}
Почему бы не трехуровневая иерархия:
abstract class Foo
abstract class FooImplBase<T> extends Foo
class Bar extends FooImplBase<String>
Клиенты только знают о Foo
, который не содержит общих методов. Представьте любые общие методы, в которых Вы нуждаетесь FooImplBase<T>
и затем реальный класс происходит из него.
Таким образом в Вашем примере startStuff()
и endStuff()
было бы абстрактно в Foo
и реализованный в FooImplBase<T>
. Это кажется, что могло бы работать в Вашей реальной ситуации? Я соглашаюсь, что это является немного громоздким.
Чтобы быть полезными, в какой-то момент Вы собираетесь установить foo
поле. В той точке необходимо знать (или смочь получить), T
. Я предложил бы делать это в конструкторе, и затем это будет иметь смысл для Bar
иметь универсальный параметр. Вы могли даже использовать интерфейс, таким образом, клиентский код не должен видеть тип. Однако я предполагаю, что Вы не собираетесь слушать мой совет и действительно хотеть a setFoo
. Поэтому просто добавьте точку к переключаемой реализации:
/* pp */ class final BarImpl<T> {
private final Foo<T> foo;
private T t;
BarImpl(Foo<T> foo) {
this.foo = foo;
}
public void startStuff() {
t = foo.getOne();
}
public void finishStuff() {
foo.useOne(t);
}
}
public final class Bar {
private BarImpl<?> impl;
/* ... */
// Need to capture this wildcard, because constructors suck (pre-JDK7?).
public void setFoo(Foo<?> foo) {
setFooImpl(foo);
}
private <T> void setFooImpl(Foo<T> foo) {
impl = new BarImpl<T>(foo);
}
public void startStuff() {
impl.startStuff();
}
public void finishStuff() {
impl.finishStuff();
}
}
Вы определяете класс Панели. Две вещи верны...
1) Нет никакого параметрического типа, вовлеченного в Панель. Таким образом, у нечто и t участников есть единственный тип скажем U, который фиксируется для определения. Если Вы передаетесь Нечто, которое Вы ожидаете присваивать нечто, это должно быть Нечто <U>. Если это все верно, то да, это не часть открытого интерфейса - все имеет определенный тип. Затем я не уверен, под чем Вы подразумеваете, "определяют количество", поскольку нет никаких свободных переменных типа. Если Вы имеете в виду, универсально определяют количество, как Вы согласовываете то, что Панель не имеет никакого параметрического ввода, так, должно быть, был дан конкретный тип для каждого из, его - участники?
2) Существует параметрический тип, вовлеченный в Панель. Это не может быть, очевидно, в открытом интерфейсе, но возможно Вы передаете в Нечто <T>, таким образом, Вы хотите иметь класс Панели быть инстанцированными с больше, чем единственный тип. Затем как указано, это находится в открытом интерфейсе, и необходимо сделать Панель параметрической в T с дженериками. Это дает Вам некоторую форму универсальной квантификации для определения, "Для всех типов T, это определение верно".
Где-нибудь это должно решенный, что вводит Вас, хотят использовать для 'T' в классе Панели. Таким образом, любой, Вы должны, выбрал его в определении Панели (заменяющий Нечто Нечто в определении класса), или Вы оставляете его до клиента класса Панели: В этом случае Панель должна быть сделана универсальной.
Если Вы хотите иметь интерфейс к Панели, не полагающейся T и смочь к, выбрал различные типы для T, необходимо использовать неуниверсальный интерфейс или абстрактный базовый класс, как в:
interface Bar {
void startStuff();
// ...
}
class BarImplement<T> {
private Foo<T> foo;
// ...
}
Если Вы действительно хотите потянуть некоторую ярость, можно поместить класс Панели в интерфейсе Foo и высосать T того пути. См. эту статью для получения дополнительной информации о классах в интерфейсах. Возможно, это - один случай, где это имеет смысл?
interface Foo<T> {
T getOne();
void useOne(T t);
public class Bar<T> {
private Foo<T> foo;
private T t;
public void startStuff() {
t = foo.getOne();
}
public void finishStuff() {
foo.useOne(t);
}
}
}
Параметр T в этом случае становится бесполезным, что касается Панели, так как это будет стерто для Возражения во время компиляции. Таким образом, Вы могли также "сохранить себя проблема" и сделать стирание рано:
public class Bar {
private Foo<Object> foo;
private Object t;
...
}