Введение в разработку для Android:
http://www.ibm.com/developerworks/ru/library/os-android-devel/index.html
пятница, 26 февраля 2010 г.
среда, 10 февраля 2010 г.
Производительность java-программ
Производительность java-программ можно увеличить, если применить серверные настройки (которые не так сильно экономят память, как настройки по умолчанию):
java -server MyAppЕсли верить публикациям в интернете, то производительность может иногда увеличиться в два раза.
вторник, 9 февраля 2010 г.
Swing и многопоточность
Для прорисовки интерфейса в Java с помощью библиотеки swing лучше пользоваться, например, SwingUtilities.invokeLater(Runnable r), а не обычно создавать поток и запускать в нем Runnable. В противном случае будут лезть непонятные ошибки типа JTable Exception in thread "AWT-EventQueue-0" (ArrayIndexOutOfBoundsEx...) или подобные. Это происходит потому, что обращаться к swing-компонентам можно только из потока Event Dispatch Thread (EDT). Функцияция invokeLater ставит задачу в очередь на потоке EDT (т.к. все взаимодействие с swing-овскими графическими элементами управления необходимо осуществавлять только в потоке EDT). Но это не работает в случае, если необходимо выполнить длительный процесс, который заставит ждать поток EDT. Для таких случаев необходимо вместо обычного Thread задействовать SwingWorker.
Очень хорошая русскоязычная статья по этой теме:
http://developers.sun.ru/content/view/159/89/
и еще одна статья (видимо, слегка устаревшая):
http://www.ibm.com/developerworks/ru/edu/j-medswing/section4.html
Очень важно понять, что никаких обращений к swing-компонентам внутри метода SwingWorker.doInBackground() быть не должно т.к. он выполняется в отдельном потоке (не EDT) и если обращаться к swing-компонентам не из EDT потока, то это может стать причиной возникновения исключений. Вывод результатов можно производить, например, в методе SwingWorker.done(), который выполняется в потоке EDT и автоматически вызывается после того, как doInBackground() завершит свою работу, что оберегает нас от возможных проблем.
Очень хорошая русскоязычная статья по этой теме:
http://developers.sun.ru/content/view/159/89/
и еще одна статья (видимо, слегка устаревшая):
http://www.ibm.com/developerworks/ru/edu/j-medswing/section4.html
Очень важно понять, что никаких обращений к swing-компонентам внутри метода SwingWorker.doInBackground() быть не должно т.к. он выполняется в отдельном потоке (не EDT) и если обращаться к swing-компонентам не из EDT потока, то это может стать причиной возникновения исключений. Вывод результатов можно производить, например, в методе SwingWorker.done(), который выполняется в потоке EDT и автоматически вызывается после того, как doInBackground() завершит свою работу, что оберегает нас от возможных проблем.
среда, 3 февраля 2010 г.
Процедуры и триггеры в Oracle
Процедуры
Ниже приведен пример кода процедуры. Сампример немного громоздок, т.к. взят непосредственно из рабочей базы без каких-либо модификаций и упрощений:
Триггеры
Иногда достаточно удобно использовать триггеры. Допустим, у нас есть таблица файлов платежей, у записей которой есть потомки - платежи, хранящиеся в таблице платежей. Необходимо, чтобы при удалении файла автоматически удалялись и все платежи, связанные с ним. Ниже представлен простой пример:
http://www.techonthenet.com/oracle/triggers/before_delete.php
Ниже приведен пример кода процедуры. Сампример немного громоздок, т.к. взят непосредственно из рабочей базы без каких-либо модификаций и упрощений:
create or replace procedure jlb_set_kr_by_phone
is
is_region_found NUMERIC(1,0);
pers sch2.jlb_pays_temp2.account%TYPE;
vcode_count NUMERIC(5,0);
valid_vcode NUMERIC(5,0);
begin
--перебираем лицевые
FOR c1 IN (SELECT phone
FROM sch2.jlb_pays_temp2
WHERE phone IS NOT NULL AND account IS NULL) LOOP
is_region_found := 0;
vcode_count := 0;
--ищем код района лицевого счета
FOR c2 IN (SELECT
z.vcode,
c.npers
FROM
BS.BSSUBSACCT SA,
bs.bstechnic t,
bs.bstechsubs ts,
bs.bsclient c,
bs.vbszone z
WHERE
sa.nsubs = c.nclient_id
and ts.nsubs=sa.nsubs
and t.ntech_id=ts.ntech
and t.vcode = c1.phone
and c.nzone = z.nzone_id) LOOP
--признак физ. или юр. лица
pers := c2.npers;
--запомним найденный код р-на
valid_vcode := c2.vcode;
--укажем, что код р-на такого лицевого был найден
is_region_found := 1;
--считаем кол-во найденных р-нов
vcode_count := vcode_count + 1;
END LOOP; --end c2
--если все в порядке
IF is_region_found = 1 AND vcode_count = 1 AND pers IS NOT NULL THEN
UPDATE sch2.jlb_pays_temp2 p
SET p.is_invalid = 0, p.reg_code = valid_vcode
WHERE p.phone = c1.phone;
END IF;
--если не найдено кодов района (т.е. телефон не найден ни в одном из р-нов)
IF is_region_found = 0 THEN
UPDATE sch2.jlb_pays_temp2 p
SET p.is_invalid = 6
WHERE p.phone = c1.phone;
END IF;
--если неск. кодов района - тоже ошибка
IF is_region_found = 1 AND vcode_count > 1 THEN
UPDATE sch2.jlb_pays_temp2 p
SET p.is_invalid = 7
WHERE p.phone = c1.phone;
END IF;
--если это юрлицо
IF pers IS NULL THEN
UPDATE sch2.jlb_pays_temp2 p
SET p.is_invalid = 1
WHERE p.phone = c1.phone;
END IF;
END LOOP; --end c1
commit;
end jlb_set_kr_by_phone;
* This source code was highlighted with Source Code Highlighter.В вышеприведенном примере, если говорить коротко, в таблице выставляются соостветствующие телефонам коды районов.Триггеры
Иногда достаточно удобно использовать триггеры. Допустим, у нас есть таблица файлов платежей, у записей которой есть потомки - платежи, хранящиеся в таблице платежей. Необходимо, чтобы при удалении файла автоматически удалялись и все платежи, связанные с ним. Ниже представлен простой пример:
--таблица файлов
create table jlb_files(
file_id number(10) PRIMARY KEY USING INDEX,
bank_id number(10),
file_name varchar2(50),
file_date DATE,
upload_date DATE,
total_pays_cnt NUMERIC(9, 0),
total_pays_sum NUMERIC(10, 2)
);
--таблица оплат
create table jlb_pays(
pay_id number(10) PRIMARY KEY USING INDEX,
file_id number(10),
account varchar2(20),
pay_sum NUMERIC(9,2),
pay_date DATE,
);
--триггер
CREATE OR REPLACE TRIGGER jlb_files_before_delete
BEFORE DELETE
ON jlb_files
FOR EACH ROW
DECLARE
BEGIN
DELETE FROM jlb_pays p
WHERE :old.file_id = p.file_id;
END;
* This source code was highlighted with Source Code Highlighter.Очевидно, что jlb_files - это таблица файлов, а jlb_pays - это таблица дочерних платежей. При удалении файла из jlb_files автоматически удаляются все платежи с соответствующим file_id. В теле триггера видно, что old представляет собой удаляемую строку. http://www.techonthenet.com/oracle/triggers/before_delete.php
понедельник, 4 января 2010 г.
Windows PowerShell
Очень удобное средство в Windows для написания различных скриптов, автоматизирующих работу. Более мощное средство, чем стандартные cmd-скрипты. Файлы powershell-скриптов имеют расширение ".ps1". Вот пример простенького скрипта, в котором мы архивируем файлы с помощью 7-zip и копируем их в архивную папку:
Инода возникает необходимость узнать дату, которая, предшествующую текущему времени и использовать ее, допустим, в названии архивной папки. Это можно сделать, например, таким образом:
Удобно работать с файлами. Следующий скрипт, например, выводит список файлов и их размер:
Кстати говоря, сначала файлы скриптов не исполнялись, т.к. их запуск был запрещен политикой по умолчанию. Чтобы разрешить запуск скриптов, установим в powershell соответствующую политику безопасности:
- список команд с описанием
- включение политик
- простенький примерчик
- особое спасибо автору этого поста про запуск консольных программ в пауэршелле
- и этим людям за раскрытие темы контроля состояния запущенного процесса
- форматирование строк
# archive files using 7-zipСтоит особо пояснить строку do { } while (!$process.HasExited). Здесь мы проверяем в цикле состояние запущенного процесса и скрипт не продолжит выполнятся, пока процесс создания файла архива полностью не завершится. Вместо этой конструкции можно использовать
$application = "C:\Program Files\7-zip\7z.exe"
$arguments = "a -tzip C:\xls.zip -r F:\results\xls\*.*"
$process = [Diagnostics.Process]::Start($application, $arguments)
do { } while (!$process.HasExited)
# create new folder and copy file
$curdate = get-date -format "yyyyMMdd"
$src = "C:\xls.zip"
$dest = "D:\archives\$curdate"
New-Item $dest -type directory -force
Copy-Item $src "$dest\xls.zip"
или вообще все в одну строчку лаконично уместить:$process.WaitForExit()
[Diagnostics.Process]::Start($application, $arguments).WaitForExit()
Инода возникает необходимость узнать дату, которая, предшествующую текущему времени и использовать ее, допустим, в названии архивной папки. Это можно сделать, например, таким образом:
# get date before 30 days agoВ результате переменная $path будет чем-то вроде "D:\archives\200912".
$date = (Get-Date).AddDays(-30)
$datestr= "{0:yyyyMM}" -f $date
$path = "D:\archives\$datestr"
Удобно работать с файлами. Следующий скрипт, например, выводит список файлов и их размер:
foreach ($file in Get-ChildItem "F:\old_bases\DBF")В нижеприведенном примере происходит копирование файлов из одних папок в другие при помощи цикла foreach:
{
$file.name + " " +$file.length
}
foreach ($depNo in 40..75)Что интересно, запуск скриптов можно осуществлять как набрав в консоли паэршелла полный путь скрипта типа "D:\scripts\ps1scripts\test.ps1", так и "D:\scripts/ps1scripts/test.ps1". Причем при указании пути во втором случае при указании диска используется обратный слеш, а при указании пути прямой. Также можно в консоли пауэршелла применить команду cd и сделать нужную папку со скрипатми текущей, и вызвать из ее корня необходимый скрипт, набрав "./script.ps1". То есть точка и прямой слеш подразумевают текущую директорию.
{
if(($depNo -gt 66) -and ($depNo -lt 72)) { continue }
$src = "F:\resultxls\dep" + $depNo + "\tables"
$dst = "T:\backup\dep" + $depNo+ "\tables"
Copy-Item "$src\*.xls" -destination "$dst"
"files to dep$depNo are copied"
}
Кстати говоря, сначала файлы скриптов не исполнялись, т.к. их запуск был запрещен политикой по умолчанию. Чтобы разрешить запуск скриптов, установим в powershell соответствующую политику безопасности:
Set-ExecutionPolicy UnrestrictedВзято отсюда:
- список команд с описанием
- включение политик
- простенький примерчик
- особое спасибо автору этого поста про запуск консольных программ в пауэршелле
- и этим людям за раскрытие темы контроля состояния запущенного процесса
- форматирование строк
пятница, 4 декабря 2009 г.
LayoutManager-ы
Кроме станадртного BorderLayout, весьма удобно использовать GridBagLayout.
http://java.sun.com/j2se/1.4.2/docs/api/java/awt/GridBagLayout.html
http://java.sun.com/j2se/1.4.2/docs/api/java/awt/GridBagLayout.html
четверг, 3 декабря 2009 г.
Скрытие cmd-окна при запуске java-программ
Достаточно странные результаты в первых строчках выдает гугл, если спросить у него "how to hide cmd window in windows" или "hide cmd line". Ведь просто-напросто необходимо запустить некую программу с параметрами ипосле запуска командная строка уже не нужна и сильно раздражает. Для этого можно использовать команду start с ключом /b. Конкретно у меня проблема возникла при запуске джавашных программ, хотя то же, естественно, применимо для любых не-консольных программ, запускающихся с параметрами. Для джавы решение такое:
1) использовать не java, а jawaw;
2)указать командному интерпретатору Windows скрыть окно.
Если раньше cmd-файлик запуска java-класса был таким:
java -Xms128m -Xmx512m -classpath F:\Projects\JavaProjects\GetOborotToBank\bin;F:\Projects\JavaProjects\GetOborotToBank\lib\classes12.jar GetOborotToBank -outfile c:\outfile.txt
Теперь он выглядит так:
start /B javaw -Xms128m -Xmx512m -classpath F:\Projects\JavaProjects\GetOborotToBank\bin;F:\Projects\JavaProjects\GetOborotToBank\lib\classes12.jar;F:\Projects\JavaProjects\GetOborotToBank\lib\javadbf.jar GetOborotToBank -outfile c:\outfile.txt
То есть мы "java" заменили на "javaw" и перед командой добавили "start /B". Последнее действие скрывает cmd-окно.
Взято отсюда:
http://www.rsdn.ru/forum/java/2647235.flat.aspx
Официальная майкрософтовская справка по команде start:
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/start.mspx?mfr=true
1) использовать не java, а jawaw;
2)указать командному интерпретатору Windows скрыть окно.
Если раньше cmd-файлик запуска java-класса был таким:
java -Xms128m -Xmx512m -classpath F:\Projects\JavaProjects\GetOborotToBank\bin;F:\Projects\JavaProjects\GetOborotToBank\lib\classes12.jar GetOborotToBank -outfile c:\outfile.txt
Теперь он выглядит так:
start /B javaw -Xms128m -Xmx512m -classpath F:\Projects\JavaProjects\GetOborotToBank\bin;F:\Projects\JavaProjects\GetOborotToBank\lib\classes12.jar;F:\Projects\JavaProjects\GetOborotToBank\lib\javadbf.jar GetOborotToBank -outfile c:\outfile.txt
То есть мы "java" заменили на "javaw" и перед командой добавили "start /B". Последнее действие скрывает cmd-окно.
Взято отсюда:
http://www.rsdn.ru/forum/java/2647235.flat.aspx
Официальная майкрософтовская справка по команде start:
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/start.mspx?mfr=true
Подписаться на:
Сообщения (Atom)