28 ноября 2008

Работа со строками в oracle

Наиболее частая операция, которую необходимо выполнять - это выбор подстроки из строки. Для этого в oracle присутствует специальная встроенная функция substr
например : substr('test string #1', 5, 11 ) , где 1й параметр - это задана строка, 2й - позиция с которой начинается подстрока, 3й(не обязательный) - длинна подстроки.
Если точна позиция начала подстроки не известна , можно воспользоваться функцией instr
Например instr('test string #1', ' ' ) - будет найдено первое вхождение пробела в строку. В функции instr есть ещё третий параметр, который задаёт начало поиска, причём если указать -1 начало будет производится с конца строки.

Другие полезные функции:

ascii('S') - ascii код символа
upper / lower / initcap - преобразования регистра букв в большие / маленькие / первая большая все остальные маленькие.
chr(168) - получения символа по заданному ascii коду
concat('s1','s2') - соединение строк
trim / rtrim / ltrim - отбрасывание пробелов
reverse('12345') - получение строки с символами в обратном порядке
length - длинна строки

23 ноября 2008

Паттерн поведения Observer (наблюдатель)

Наблюдатель (Observer) - паттерн поведения объектов, устанавливающий систему оповещения объектами своих соседей в процессе их деятельности.
Известен также под именами: Dependents (подчиненные), Publish-Subscribe (издатель-подписчик).

В процессе функционирования и взаимодействия объектов системы нужно оповещать других участников по завершении какой-нибудь значимой операции. Конечно же, можно в каждый такой класс, производящий значимые действия добавлять обращение к этим всем другим заинтересованным объектам, но таким образом мы дублируем связи между объектами (система становится все менее и менее гибкой) – это еще и в разы затруднит последующую модификацию каких либо участников, т.к. необходимо будет перекомпилировать этот код обращения ко всем заинтересованных субъектам.
В этом случае очень подошло бы иметь такую структуру, в которой каждый участник, если он заинтересован в каких-либо событиях системы, мог бы самостоятельно «подписаться» на эти изменния независимо от других заинтересованных участникам – и, таким образом, получая уведомления об этих событиях – выполнять требуемые ответные действия.
В результате – не создается лишних связей: есть источник значимых действий, есть заинтересованные в фактах выполнения этих действий субъекты, никак не связанный друг с другом, количество которых при этом – также неограниченно.

Паттерн-наблюдатель описывает именно такой подход: определяет зависимость типа «один ко многим» между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом и автоматически обновляются.

Реализация паттерна поведения Наблюдатель (Observer).

/** Observer design pattern sample
*/

import java.util.ArrayList;
import java.util.List;

public class Child {
// --
List list = new ArrayList();
void addObserver(Observer o){
list.add(o);
}
void removeObserver(Observer o){
list.remove(o);
}
void notifyObservers(){
for (Observer o:list){
o.update();
}
}
// --
void childGrow(int newAge){
System.out.println("Age of child changed to " + newAge);
notifyObservers();
}
public static void main(String []s){
Child ot = new Child();
ot.childGrow(1);
ot.addObserver(new Food());
ot.addObserver(new Toys());
ot.addObserver(new Clothes());
ot.childGrow(3);
ot.removeObserver(new Food());
ot.childGrow(10);
ot.removeObserver(new Toys());
ot.childGrow(15);
ot.addObserver(new Food());
ot.childGrow(20);
ot.removeObserver(new Food());
ot.removeObserver(new Clothes());
ot.childGrow(25);
}
}

interface Observer {
void update();
}

abstract class BaseObserver implements Observer {
public boolean equals(Object obj) {
return this.getClass().equals(obj.getClass());
}
}

class Clothes extends BaseObserver {
public void update() {
System.out.println("Change childs' clothes");
}
}

class Toys extends BaseObserver {
public void update() {
System.out.println("Change childs' toys");
}
}

class Food extends BaseObserver {
public void update() {
System.out.println("Change childs' food");
}
}


Итак, у нас есть класс Child , который описывает модель ребёнка, основное действие - ребёнок растёт : childGrow, и в зависимости от возвраста ребёнка необходимо менять одежду, еду, игрушки - эти сущности описываются классами Clothes, Food, Toys соответственно. Эти три сущности реалиузют интерфейс Observer через класс BaseObserver.
После создания экземпляра класса ребёнка мы можем добавить или удалить специфических наблюдателей, и при достижении ребёнком какого то возраста (вызов childGrow) автоматически произойдёт обновление зарегистрированных в это время слушателей.


Источники:
Ппаттерн наблюдатель
Observer pattern
Speaking on the Observer pattern

22 ноября 2008

Перенаправление системного вывода в файл

Для того что бы выводить информацию из Java программы в файл не обязательно использовать навороченные системы логгирования.
Можно просто перенаправить стандартный поток вывода и стандартный поток для ошибок в файл.
Сделать это можно с помощью следующего фрагмента кода:


PrintStream st = new PrintStream(new FileOutputStream("output.txt"));
System.setErr(st);
System.setOut(st);

20 ноября 2008

Java EE справочник по русски

Java 2 Enterprise Eddition (J2EE)

Обзор J2EE:
Учебник по J2EE (PDF):
Разработчикам:

17 ноября 2008

JScience : Java научная библиотека

JSscience - всеобъемлющая Java библиотека предоставляющая API для научных вычислений. API включает функции для выполнения различных задач из таких областей науки, как : физика, биология, социология, астрономия, экономика, география и др.

Описание некоторых возможностей:
  • Модуль coordinates совместимый с OGC/ISO спецификацией для разработке географических
  • linear algebra - модуль включающий параметризированный класс матрица , позволяющий решать линейные уравнения различной сложности.
  • measurements - модуль для произведения измерений различной точности
  • models - модуль поддерживающий различные физические системы.
  • monetary- модуль для проведения валютных операций из заданой точностью.

Документация(версия 4.3.1)
Скачать библиотеку(версия 4.3.1)

SwisSQL - Oracle to Java Migration Tool

SwisSQL- утилита для преобразования Oracle PL/SQL кода в Java. SwisSQL на вход получает код пакетов, функций, процедур, тригеров и преобразует в Jdbc код.

Туториал построения Spring MVC приложения в Netbeans

http://www.developinjava.com/articles.php?article_id=3

Springmodules

Spring. Модули, дополнения и тулзы интеграции для Spring.

Документация

Последний релиз 0.8 содержит :

15 ноября 2008

Психологический барьер предодолён 100 уникальных посетителей в день.

14 ноября 2008 года Google Analytics показал, что сайт посетило ровно 100 уникальных посетителей. На данный момент это рекорд.
В среднем, за последних 2 месяца количество уникальных посетителей колеблется от 70 до 80 , постоянно увеличиваясь.
Так что продолжу добавлять востребованный контент, для достижения новых рекордов.

12 ноября 2008

Добавление элементов в Java масив

Написал 2 простые функции по добавлению одного или нескольких элементов в конец масива.

public static String[] addToArray(String[] array, String s) {
String[] ans = new String[array.length+1];
System.arraycopy(array, 0, ans, 0, array.length);
ans[ans.length - 1] = s;
return ans;
}

public static String[] addToArray(String[] array, String[] s) {
String[] ans = new String[array.length + s.length];
System.arraycopy(array, 0, ans, 0, array.length);
System.arraycopy(s, 0, ans, array.length, s.length);
return ans;
}

У кого есть более эффективный метод прошу поделиться.

SpringSource покупает G2One

11 ноября, 2008, SpringSource объявили, что он приобрели G2One - компанию которая поддерживает Groovy и Grails технологии.
источник 1(en)
источник 2(ru)

11 ноября 2008

Создание представления в PL/SQL c помощью execute immediate

Вот пытаюсь выполнить PL/SQL код, который должен создать представление в базе данных:
declare
begin
execute immediate 'create or replace force view test_view1 ("f1","F2") as select 0, sysdate from dual;';
end;
/
И получаю совершенно неожиданный результат, а именно исключение:
ORA-00911: invalid character
ORA-06512: at line 3
00911. 00000 - "invalid character"
*Cause: identifiers may not start with any ASCII character other than ...

И это при том, что SQL команда по созданию этого представления успешно протестированна и выполняется без ошибок.
В заблуждение вводит текст исключения, потому что хочется сразу проверить введённое имя представления, хоть оно и правильное. Методом проб и ошибок (точенее одной пробы) удалось установить что вызвало это исключение.
Причина - это точка с запятой указанная после ключевого слова dual ... всё логично, но при такой обработке исключение довольно сложно обнаружить такую ошибку.

И ещё одна заметка на эту тему : названия полей для представлений должны быть написаны большыми буквами!!! Такую ошибку также довольно сложно обнаружить, и притом не на этапе создания представления, а лишь на этапе тестирования, выполняя запросы к представлению.
Например в моём случае , запрос:
seleсt f2 from test_view1 успешно выполниться , в то время как
seleсt f1 from test_view1 сообщит мне что колонки f1 в таблице нету ...

Будьте бдительны).


JavaFX 1.0 релиз в декабре

По сообщению The Planetarium официальный релиз JavaFX намечен на 2 декабря 2008 года.
Напомню, что в начале этого года Sun создал JavaFX Preview SDK для программирования на JavaFX.

о JavaFx

08 ноября 2008

Новые функции в Java Math

Если в проекте много "математики" , то код получается не красивый и сложно понимаемый, приходиться писать множество комментариев , что бы было понятно что к чему.
Но SUN идёт на встречу разработчикам, и в каждой новой версии добавляет всё новые функции в основной математический класс - java.lang.Math

Новое в Java 1.5 :

log10(double a) - логарифм с основанием 10
cbrt(double a) - корень кубический
ulp(double d) - на сколько я понял это модуль разницы между параметром d преобразованным в float и ближайшим по возрастанию double значением. поправьте если я не прав!
signum(double d) - возвращает знак числа: 0, если d=0; -1.0 если d<0;>0;
sinh(double x) - \
cosh(double x) - - гиперболические синус, косинус и тангес
tanh(double x)- /
hypot(double x, double y) - гипотенуза
expm1(double x) - = exp(x) - 1
log1p(double x) - = ln(x+1)

Новое в 1.6
copySign(double magnitude, double sign)
getExponent(double d)
nextAfter(double start, double direction)
nextUp(double d)
scalb(double d, int scaleFactor)

Всё красиво, всё удобно - чего только стоит функция гипотенузы. Но всё имеет свои минусы, тут они также есть.
Если сравнить производительность, например той же функции hypot(x,y)
c более привычным способом получения значения гипотенузы Math.sqrt(x*x + y*y), то получим достаточно интересные результаты, а именно - разница в скорости выполнении различается почти в 100 раз!!! причём как это не удивительно , но не в пользу нововведённой функции.
Итак , мой тестовый класс:

public class RealType {
public static void main(String[] s) throws Exception{
long start1;
int counter = 0;
double temp = 0;
for (int k=0; k<5;>
start1 = System.currentTimeMillis();
for (int i=0; i<1000;>
for (int j=0; j<5000;>
temp = Math.sqrt(i*i + j*j);
counter++;
}
}
System.out.println("Spent time to run sqrt " + counter + " times : " + (System.currentTimeMillis() - start1));
counter = 0;
start1 = System.currentTimeMillis();
for (int i=0; i<1000;>
for (int j=0; j<5000;>
temp = Math.hypot(i, j);
counter++;
}
}
System.out.println("Spent time to run hypot " + counter + " times : " + (System.currentTimeMillis() - start1));
}
}
}

После выполнения я получил приблизительно следующие результаты:

Spent time to run sqrt 5000000 times : 63
Spent time to run hypot 5000000 times : 4109
Spent time to run sqrt 5000000 times : 47
Spent time to run hypot 5000000 times : 4172
Spent time to run sqrt 5000000 times : 47
Spent time to run hypot 5000000 times : 4140
Spent time to run sqrt 5000000 times : 47
Spent time to run hypot 5000000 times : 4157
Spent time to run sqrt 5000000 times : 46
Spent time to run hypot 5000000 times : 4172

Тоесть, скорость выполнения одного вызова функции на моём компьютере занимает 800 наносекунд для hypot и 9 наносекунд для sqrt.
Для того что бы понять откуда такая разница, пришлось порытся в исходниках и посмотреть что собой представляет нативная hypot . Поиски привели меня к hypot_e.c и выглядит он следующим образом:

/*----------------------*/


#include "fdlibm.h"

#ifdef __STDC__
double __ieee754_hypot(double x, double y)
#else
double __ieee754_hypot(x,y)
double x, y;
#endif
{
double a=x,b=y,t1,t2,y1,y2,w;
int j,k,ha,hb;

ha = __HI(x)&0x7fffffff; /* high word of x */
hb = __HI(y)&0x7fffffff; /* high word of y */
if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
__HI(a) = ha; /* a <- |a| */
__HI(b) = hb; /* b <- |b| */
if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
k=0;
if(ha > 0x5f300000) { /* a>2**500 */
if(ha >= 0x7ff00000) { /* Inf or NaN */
w = a+b; /* for sNaN */
if(((ha&0xfffff)|__LO(a))==0) w = a;
if(((hb^0x7ff00000)|__LO(b))==0) w = b;
return w;
}
/* scale a and b by 2**-600 */
ha -= 0x25800000; hb -= 0x25800000; k += 600;
__HI(a) = ha;
__HI(b) = hb;
}
if(hb <>
if(hb <= 0x000fffff) { /* subnormal b or 0 */
if((hb|(__LO(b)))==0) return a;
t1=0;
__HI(t1) = 0x7fd00000; /* t1=2^1022 */
b *= t1;
a *= t1;
k -= 1022;
} else { /* scale a and b by 2^600 */
ha += 0x25800000; /* a *= 2^600 */
hb += 0x25800000; /* b *= 2^600 */
k -= 600;
__HI(a) = ha;
__HI(b) = hb;
}
}
/* medium size a and b */
w = a-b;
if (w>b) {
t1 = 0;
__HI(t1) = ha;
t2 = a-t1;
w = sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
} else {
a = a+a;
y1 = 0;
__HI(y1) = hb;
y2 = b - y1;
t1 = 0;
__HI(t1) = ha+0x00100000;
t2 = a - t1;
w = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
}
if(k!=0) {
t1 = 1.0;
__HI(t1) += (k<<20);
return t1*w;
} else return w;
}


Теперь всё становится ясным, такое количество дополнительных проверок не могут обойтись дёшево. Совсем другой вопрос всегда ли нужны они! Решать вам...

Список наиболее часто используемых системных таблиц Oracle

Если быть точнее, то это не таблицы, а представления (view) .

Итак, поехали в алфавитном порядке:


ALL_ARGUMENTS - список всех аргументов по объектам
ALL_CATALOG - список всех table, view, synonym, sequence доступных пользователю*
ALL_COL_COMMENTS - список всех коментариев к колонкам для доступных таблиц и представлений
ALL_CONSTRAINTS - список всех внешних связей
ALL_DB_LINKS - дб линки достпные пользователю
ALL_ERRORS - недавние ошибки возникшие при создании хранимого объекта
ALL_INDEXES - индексы
ALL_IND_COLUMNS - колонки по индексам
ALL_LOBS - колоник по таблицам которые имеют тип LOB
ALL_OBJECTS - все доступные объекты
ALL_OBJECT_TABLES - все доступные таблицы
ALL_SEQUENCES - очереди
ALL_SNAPSHOTS - snapshot
ALL_SOURCE - код хранимых объектов
ALL_SYNONYMS - synonyms
ALL_TABLES - таблицы
ALL_TAB_COLUMNS - колонки для таблиц и представлений
ALL_TAB_COL_STATISTICS - статистика по обращениям к таблицам, представлениям
ALL_TAB_COMMENTS - коментарии к таблицам, представлениям
ALL_TRIGGERS - тригеры
ALL_TRIGGER_COLS - колонки таблиц используемые в тригерах
ALL_TYPES - типы
ALL_USERS - информация о пользователях
ALL_VIEWS - список представлений

DATABASE_COMPATIBLE_LEVEL - параметр совместимости бд, устанавливается в init.ora

DBA_DB_LINKS - все дб линки *
DBA_ERRORS - текущие ошибки при создании хранимых объектов
DBA_OBJECTS - все объекты в бд
DBA_ROLES- все существующие роли в бд
DBA_ROLE_PRIVS - все привилегии
DBA_SOURCE - исходные коды всех хранимых объектов
DBA_TABLESPACES - все пространства таблиц
DBA_TAB_PRIVS - все права доступа к таблицам
DBA_TRIGGERS - все тригеры
DBA_TS_QUOTAS - quotas
DBA_USERS - все пользователи
DBA_VIEWS- все представления

DICTIONARY - коментарии к таблицам и представлениям
DICT_COLUMNS - коментарии к колонкам таблиц и представлений

GLOBAL_NAME - глобальное имя бд

NLS_DATABASE_PARAMETERS - NLS параметры бд
NLS_INSTANCE_PARAMETERS - NLS параметры инстанса
NLS_SESSION_PARAMETERS - NLS параметры сессии

PRODUCT_COMPONENT_VERSION - версии компонентов продукта

ROLE_TAB_PRIVS - таблица привилегий по ролям
SESSION_PRIVS - доступные привилегии текущему пользователю
SESSION_ROLES - роли текущего пользователя
TABLE_PRIVILEGES - привилегии по таблицам

* Вероятно вы заметили что некоторые таблицы (точнее представления) имеют одинаковые названия, но разный префикс - DBA_ и ALL_

В чём же их отличия.

В представлении с префиксом ALL_ содержатся записи, которые доступны только текущему пользователю.

В представлении с префиксом DBA_ такого ограничения нет - тут содержатся абсолютно все записи, но зато к этому представлению имеют доступ только немногие привелигированные пользователи - с ролью SELECT_CATALOG_ROLE.

Полезные запросы к системным таблицам

В системных таблицах оракл так много интересного и полезного. Поделюсь тем чем сам регулярно пользуюсь.
- Список всех оракловых объектов :
select * from all_objects /* where upper(object_name) like '%[NAME]%' and object_type in ('TABLE','VIEW') */;
- Список активных сессий и параметры подключённых пользователей к базе данных:
select sid, username, schemaname, osuser, machine, program,type from sys.V_$SESSION where status = 'ACTIVE';
- Список сессий находящихся в режиме ожидания :
select s.sid, s.username, s.schemaname, s.osuser, s.machine, s.program, s.type,
sw.event, sw.p1text, sw.seconds_in_wait, sw.wait_class,sw.state
from sys.V_$SESSION s, sys.V_$SESSION_WAIT sw
where s.sid = sw.sid
and s.status = 'ACTIVE';
- Последние выполненные запросы в базе:
select sql_text, sql_full_text from SYS.V_$SQL order by first_load_time desc; (первая колонка содержит только первую строку запроса, а вот во второй запрос представлен полностью.)
- SQL&PL/SQL код текущего пользователя в базе : скрипты создание всех таблиц, тригеров, процедур, пакетов и т.д. :
select * from sys.USER_SOURCE order by name , line
(форма представления конечно не слишком читабельная, но немного изменив вышеуказанный запрос можно легко найти где по всему коду встречается то или иное ключевое слово).

01 ноября 2008

Форма обратной связи

В блоге открыта обратной связи. Ваш вопрос немедленно будет доставлен непосредственно мне на почту.


Ваш вопрос/предложение/замечание:
Имя
Содержание*


Внимание, после отправки сообщения, вы будете переправлены на домашнюю страницу блога!!