刚刚用sequence ,又忘了,呵呵,从网上找了一篇文章,写的不错,copy 在这里
1、Create Sequence
你首先要有CREATE SEQUENCE或者CREATE ANY SEQUENCE权限,
CREATE SEQUENCE emp_sequence
INCREMENT BY 1 -- 每次加几个
START WITH 1 -- 从1开始计数
NOMAXVALUE -- 不设置最大值
NOCYCLE -- 一直累加,不循环
CACHE 10;
一旦定义了emp_sequence,你就可以用CURRVAL,NEXTVAL
CURRVAL=返回 sequence的当前值
NEXTVAL=增加sequence的值,然后返回 sequence 值
比如:
emp_sequence.CURRVAL
emp_sequence.NEXTVAL
可以使用sequence的地方:
- 不包含子查询、snapshot、VIEW的 SELECT 语句
- INSERT语句的子查询中
- NSERT语句的VALUES中
- UPDATE 的 SET中
可以看如下例子:
INSERT INTO emp VALUES
(empseq.nextval, 'LEWIS', 'CLERK',7902, SYSDATE, 1200, NULL, 20);
SELECT empseq.currval FROM DUAL;
但是要注意的是:
- 第一次NEXTVAL返回的是初始值;随后的NEXTVAL会自动增加你定义的INCREMENT BY值,然后返回增加后的值。CURRVAL 总是返回当前SEQUENCE的值,但是在第一次NEXTVAL初始化之后才能使用CURRVAL,否则会出错。一次NEXTVAL会增加一次SEQUENCE的值,所以如果你在同一个语句里面使用多个NEXTVAL,其值就是不一样的。明白?
- 如果指定CACHE值,ORACLE就可以预先在内存里面放置一些sequence,这样存取的快些。cache里面的取完后,
oracle自动再取一组到cache。 使用cache或许会跳号, 比如数据库突然不正常down掉(shutdown abort),cache中的sequence就会丢失. 所以可以在create sequence的时候用nocache防止这种情况。
2、Alter Sequence
你或者是该sequence的owner,或者有ALTER ANY SEQUENCE 权限才能改动sequence. 可以alter除start至以外的所有sequence参数.如果想要改变start值,必须 drop sequence 再 re-create .
Alter sequence 的例子
ALTER SEQUENCE emp_sequence
INCREMENT BY 10
MAXVALUE 10000
CYCLE -- 到10000后从头开始
NOCACHE ;
影响Sequence的初始化参数:
SEQUENCE_CACHE_ENTRIES =设置能同时被cache的sequence数目。
可以很简单的Drop Sequence
DROP SEQUENCE order_seq;
1 Guidelines for Using Subqueries
a Enclose subqueries in parenttheses
b placce subqueries on the right side of the comparision condition
c the order by clause in the subquery is not needed
d using single-row operators with single-row subqueries and use multiple -row operator with multiple-row subqueries .
single-row subqueries can work as a expression,and muitiple-row subqueries can only be used with in all any ,i will talk it later
select last_name where job_idd=(select job_id
from employees
where imployee_id=141)
2 The HAVING CLause with Subqueries
a The Oracle server execute subqueries first
b The Oracle return result into the HAVING clause of the main query
select department_id,min(salary)
from employee
group by department_id
having min(salary)>
(select min(salary)
from employees
where department_id=50);
3 Multiple-Row Subqueries
a Return more than one row
Using mutiple-row comparsion operator
select employee_id
from employees
where salary<any
(select salary
from employees
where job_id='ddd')
select employee_id
from employees
where salary<all
(select salary
from employees
where job_id='ddd')
select emp.last_name
from employees emp
where emp.employee_id not in
(select mgr.manager_id
from employees mgr)
1 Jioning Tables Using Oracle Syntax
Using a join to query data form more than one table
select table1.column,table2,column
from table1,table2
where table1.column1=table2.column2 .
2 outjoin
1)You use an outer join to also see rows that do not meet the join condition
2)The Outer join operator is the plus sign(+)
a left join
select tabl1.column,table2,column
from table1,table2
where table1.column(+)=table2.column
b right join
select table1.column,table2.column
from table1,table2
wheretable1.coulmn=table2.column(+)
3) self join
select worker.last_name||'works for'||manager.last_name
from employees owrker,employees manager
where worker.manager_id=manager.employee_id;
3 Joining Tables Using SQL:1999 Syntax
Use a join to query data from more than one table
1) Creationg Cross Joins
a The cross join clause produces thee cross product of two tables
b This is the same as Cartesian product between the two tables
select last_name,department_name
from employees
ccross join departments
2) Creating Natual Joins
a The Natual join clause is bassed on all columns in the two tables that have the same name
b it select rows from the two tables that have the equal values in all matched columns
c if the columns having the same name and have the different data types in an error is returned.
select department_id,department_name,location_id,city
from departments
natual join locations
3) using clause
select e.employee_id,e.last_name
from employees e join departments d
using (department_id);
4) Creating joins with thee on clause
a The join condition for thee natual join is basically an equaljoin of all column with the same name.
b To specify arbitrary condition or specify columns to join, the on clause is userd
c The join condition is separated from other search conditions
d The on claus make code easy to understand.
select e.employee_id,e.last_name,e.department_id,
from employees e join departments d
on (e.department_id=d.department_id);
from employe
join departments d
on d.department_id=e.department_id
join locations l
on d.location_id=l.location_id
5) INNER Versus OuTER Joins
a In SQL:1999,the join of two tables returning only matched rows is an inner join
6) FULL OUTER JOIN
select e.last_name,e,department_id,d.department_name
from employees e
full outer join departments d
on (e.department_id=d.department_id);
1 "'
2 ||
3 isql*plus http://127.0.00.1/isqlplus
4 desc author
5 initcap('SQL Course')
INSERT('JellwWord','W') 6
LPAD (salary,10,'*') *****24000
RPAD (salary,10,'*') 24000*****
TRIM ('H' from 'HolloWorld') olloWord
substr('helloword',1,5) hello
substr('helloword',-1,5) oword
6 Number Functions
round(45.926,2) 45.93
round(45.926,-2) 0
round(55.926,-2) 100
trunc(45.926,2) 45.92
mod(1600,300) 100
7 data function
systdate
(sysdate-hire_date)/7 as weeks
months_between number of months between two dates
months_between ('01-sep-95','11,jan-94') 19.6774194
add_months add calendar months to date
add_months('11-JAN-94',6) '11-JUL-94'
next_day next day of the date specified
next_day('01-SEP-95','FRIDAY') '08-SEP-95'
last_day last day of the month
last_day('01-feb-95') '28-feb-95'
round round date
assume sysdate='25-jul-95'
round(sysdate,'month') 01-aug-95
round(sysdate,'year') 01-JAN-96
trunc truncate date
trunc(sysdate,'month') 01-Jul-95
trunc(sysdate,'month') 01-JAN-95
8 Conversion Functions
1) implicit data typ conversion
varchar2 or char ---number
varchar2 or char ---date
numbeer ---varchar2
date ---varchar2
2) to_char(date,'format')
format:
YYYY Full year in numbers
YEAR Year spelled out
MM Two-digit value for month
MONTH Full name of the month
MON THree-letter abbreviation of the month
DY Three-letter abbreviation of the day of the week
DAY Full name of the day of hte week
DD Numberic day of the month
HH24:MI:SS AM 15:45:32:PM
DD "of" MONTH 12 of october
3) to_char function with number
TO_CAHR(number,'format_model')
These are some of the format elements you can use with the to_char function to display number as a character.
9 Reqresents a number
0 Forces a zero to be displayed
$ Places a flationg dollar sign
L Uses the floating local currency symbol
. Prints a decimal point
, Print a thousand director
select to_char(qtym,"$999.99")
4) Using t_number and to _date functions
a converting a character string to a number format using to_number function
to_number(char,"format")l
b converting a character string to a date format
to_date(char,"format")
5 Nesting Functions
.Single-row function can be nested to many level
.Nested function can be evaluated from deepest level
6General Function
These function work with any data type and pertain to using nulls
nvl(expr1,expr2);
nvl2(expr1,expr2,expr3)
nullif(expr1,expr2)
coalesce(expr1,expr2,,,,exprn)
1) nvl function
convert a null to an actual function
a Data type can be used are data character and number
b Data types must match
(set wrap off
set line 1000
)
2)Using the COALESCE Function
a The advantage of the coalesce function over nal function is that coalesce function can take multiple alternative value
b If the first value is not null, it return that expression,otherwise,it does a coalesce of remaining expressions
6 Conditional Expressions
a Provide the use of if-then-else logic
b use two methods: case expression decode function
select last_name,job_id,salary,
case job_id when 'it' then 1*salary
when 'manager' then 1.2*salary
else salary end;
from employee.
select last_namek,job_id,salary,
decode(job_id,'it' ,1*salary,
'manager',1.2*salary,
salary)
from employees
1 What Are Group Functions
Group functions operatee on sets of rows to give one result per group
1)agg,count,max,min,stddev,sum,variance
select avg(salary),max(salary),min(salary),sum(salary)
from employees
where job_id like '%REP%'
select count(*) from
select count(address) from authors
count the valid count of the address (exclude the null value)
2) Using theDISTINCT Keyword
count(distinct expr) return thee number of the distinct non-null value of the expr
select count(distincee department_id) from employees
3)Group functions and null values
group functions ignore null values in the clumn
4) Using thee NVL Function with Group Functions
The nul function force group funtion to include null values
select avg(nvl(commission_pct,0)) from employees
2 Creating Groups of Data
1)
a Divide rows in a table into smaller groups by using the group by clause
b All coulmns in the select list that are not in group function must be in the group by clause
select department_id,avg(salary)
from employees
group by department_id;
2) Grouping by More Than One Column
3) Ilegal Queries Using Group Functions
a You cannot use thee where clause to restrict groups
b You use thee having clause to restrict groups
c you cannot use group functions in the where clause
4)Excluding Group Resdults:The Having Clause
Use the HAVING clause to restrict groups
a Rows are grouped
b The group functions is applied
c Groups matcching the Having clause are display
select department_id,max(salary)
from employees
group by department_id
having max(salary)>10000
5) Nesting Group function
select max(avg(salary))
from employees
group by department_id;
1 Keyboardd Basics
1) Ignoring the Keyboard
Your programm does not need to act on every keyboard message it received,Window handle many keyboard message function itself.
2)Who's Got thefocus
Though the keyboard is shared by all the window in the application ,The DispatchMessage send the message to the window procedure associated the window which message is intended.
The window that receives a particular keyboard event is the window has the input foucs.
Sometime no window has input foucs,this is the case if all your programs have been minmized,window continue send keyboard to the active window ,but it is send in the deffert form from sending to the input foucs.
A window procedure can be determine when its window has the input focus by trapping WM_SETFOCUS and WM_KILLFOCUS.
3) Queues and Synchronization
As the user presses and releases key on keyborad,Windows and keyboard device driver translate the hardware scan code into formatted message.Howerver the messages are not palced on the application queue right away,Instean Windows store these message in a system message queue .The System message queue is a single message maintained by windows specifically for the prelimary storage of user input from keyboard and the mouse. Window will take the next message from the system message queue and place it on the application message queue only when a window application has finished proecssing the previous user input message.
4) Keystorkes and Character
The message that an application receives from windows about keyboard events distingush between keystrokes and characters.
for instance The keysokes has only one key labbed 'A' ,and the character may be 'a' or 'ctr-a' etc.
2 Keystroke Message
1)Wirtual key Codes
The virtual key code is stored in the wParam parameter of WM_KEYDOWN,WM_KEYUP,the code identifies the key being pressed or release.
2)lParam Information
the wParam message parameter contain virtual key code and the lparam message parameter contains other information in understanding the keystoke.
3) Shift States
iState = GetKeyState (VK_SHIFT) ;
iState variable will be negative if the Shift key is donw
iState = GetKeyState (VK_CAPITAL) ;
4)Using Keystroke Messages
5)
case WM_KEYDOWN:
switch (wParam)
{
case VK_HOME:
SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0) ;
break ;
case VK_END:
SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0) ;
break ;
case VK_PRIOR:
SendMessage (hwnd, WM_VSCROLL, SB_PAGEUP, 0) ;
break ;
3 Character Messages
Message Key or Code
WM_KEYDOWN Virtual key code for `A' (0x41)
WM_CHAR Character code for `a' (0x61)
WM_KEYUP Virtual key code for `A' (0x41)
Message Key or Code
WM_KEYDOWN Virtual key code VK_SHIFT (0x10)
WM_KEYDOWN Virtual key code for `A' (0x41)
WM_CHAR Character code for `A' (0x41)
WM_KEYUP Virtual key code for `A' (0x41)
WM_KEYUP Virtual key code VK_SHIFT (0x10)
Key Character Code Duplicated by ANSI C Escape
Backspace 0x08 Ctrl-H \b
Tab 0x09 Ctrl-I \t
Ctrl-Enter 0x0A Ctrl-J \n
Enter 0x0D Ctrl-M \r
Esc 0x1B Ctrl-[
case WM_CHAR:
[other program lines]
switch (wParam)
{
case `\b': // backspace
[other program line
break ;
case `\t': // tab
[other program lines]
break ;
case `\n': // linefeed
[other program lines]
break ;
case `\r': // carriage return
[other program lines]
break ;
default: // character codes
[other program lines]
break ;
}
return 0 ;
1 An Architectural Overview
1)Getting a good feel for messages is an import part of learning how to write programs for windows.
Windows send a message to your porgram means that Windows calls a function in your program .The parameter of this function describe the message that is being send.The function in your program is know as Window Procedure.
Windows send a message to window by calling window procedure ,The window procedure do some processing based on the message and return control to Windows.
More precisely , a Window is always createdd based on a "window class".The window class identifies the window procedure that precesses messages to the windows.The use of window class allow mutiple window to be based the same window class and hence use the same window procedure.
2) Requsteriing the Window Class
typedef struct
{
UINT style ;
WNDPROC lpfnWndProc ;
int cbClsExtra ;
int cbWndExtra ;
HINSTANCE hInstance ;
HICON hIcon ;
HCURSOR hCursor ;
HBRUSH hbrBackground ;
LPCTSTR lpszMenuName ;
LPCTSTR lpszClassName ;
}
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
2)Creating the Window
Window class define the general Characteristics of the a window.If you want to create window based on the same window class,you can use CreateWindwo which allow you to specify more detail imformation about the window.
hwnd = CreateWindow (szAppName, // window class name
TEXT ("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
3)Displaying the window
When thee CreateWindow function return ,windows create a window internal.What it means is that windows allocate a block memory to store the imformation about the window.If you want to show that ,you should call
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
4) The Message Loop
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
typedef struct tagMSG
{
HWND hwnd ;
UINT message ;// message identifier
WPARAM wParam ;
LPARAM lParam ;
DWORD time ; // the time the message is placed on the message queen
POINT pt ; // the mouse coordiante
}
typedef struct tagPOINT
{
LONG x ;
LONG y ;
}
POINT, * PPOINT;
the message filed of message retrived from the message queen is anyting except WM_QUITm ,GetMessage return a nonzero value
wM_QUIT cause GetMessage reuturn 0.
TranslateMessage (&msg) ;
passing the msg struct back to window for some keysboard translation
DispatchMessage (&msg) ;
pass the msessageback to window .Windwo then send the message to the appropriate window procedure for processing.After window
procedure processing the message ,it return control to the windows,which is still in serving the Dispatchmessage
5) The Window Procedure
a The window procedure determined the how the window display on the client area and how the window respose to user input
b LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam),the four parameter is idential to the first four filed of the message struct.
6) Processing the Message
switch (iMsg)
{
case WM_CREATE :
[process WM_CREATE message]
return 0 ;
case WM_PAINT :
[process WM_PAINT message]
return 0 ;
case WM_DESTROY :
[process WM_DESTROY message]
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
when a window procedure process the message ,it should return 0;
7) The WM_PAINT Message
WU_PAINT message is extremely import in window.it inform a program when part or all of the window 's client area are invalid and must be redraw or repaint.
WM_PAINT processing almost always begins with a call to BeginPaint:
hdc = BeginPaint (hwnd, &ps) ; //return a handle to device context
and ends with a call to EndPaint:
EndPaint (hwnd, &ps) ;
8)The WM_DESTROY Message
PostQuitMessage (0) ;
WNDCLASS, * PWNDCLASS ;
#include <windows.h>
/* the same as long _stdcall WndPro(long,unsign int,unsign int ,long)*/
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
/*int _stdcall WinMain(long hInstance,long hPrevInstance,char * szComdLine,int iCmdShow)*/
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
/*
all window createe based on this window class will completely repaint whenever horizational window sizd and vertial
window size change.
*/
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ; // set the window procedure for the window class
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ; // the handle of this program
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name
TEXT ("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;// iCmdShow determine how the window is to be initially displayed on the screen.
UpdateWindow (hwnd) ; // cause the client area to paint
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
switch (message)
{
case WM_CREATE:
PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;//return a handle to device context
GetClientRect (hwnd, &rect) ;// set the struct rect with the dimensions of the client area
DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;// insert a WM_QIUT in the message queue.
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
2 The Window Programming Hurdles
1)Queue and noqueue message
queue message are post the message queue and the noqueue message send to the window procdure directly.
1 Understand Transaction
1) Introduce Spring's transaction manager
a JDBC transactions
<bean id="transactionManager" class="org.springframework.jdbc.
datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
b Hibernate transactions
<bean id="transactionManager" class="org.springframework.
orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
2 Programing transaction in Spring
One approach to adding transaction to your code is to programmly add transactional boundary using transiationTemplate class.
Programming is good when you want complete control over transactional boundary.but you have to use spring specific class.In most case ,your tansactional needs will not require such precise control over transactional boundaries.That is why you will typically choolse to declare transaction support
public void enrollStudentInCourse() {
transactionTemplate.execute(
new TransactionCallback() {
public Object doInTransaction(TransactionStatus ts) {
try {
// do stuff Runs within doInTransaction()
} catch (Exception e) {
ts.setRollbackOnly(); //Calls setRollbackOnly() to roll Calls setRollbackOnly() //to roll back
}
return null; //If successful, transaction is committed
}
}
);
}
<bean id="transactionTemplate" class="org.springframework.
transaction.support.TransactionTemplate">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
<bean id="courseService"
class="com.springinaction.training.service.CourseServiceImpl">
<property name=" transactionTemplate">
<ref bean=" transactionTemplate"/>
</property>
</bean>
3 Declaring transactions
Spring's support for declarative transaction management is implementedd through Spirng's AOP framework.
<bean id="courseService" class="org.springframework.transaction.
interceptor.TransactionProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>
com.springinaction.training.service.CourseService
</value>
</list>
</property>
<property name="target">
<ref bean="courseServiceTarget"/> //Bean being proxied
</property>
<property name="transactionManager">
<ref bean="transactionManager"/> //Transaction manager
</property>
<property name="transactionAttributeSource">
<ref bean="attributeSource"/> //Transaction attribute source
</property>
</bean>
1) Understanding transaction attributes
In Spring transaction attribute is a description of how transaction policies should be
applied to a methods
a Propagation behavior
Propagation behavior What it means
PROPAGATION_MANDATORY indicate that the method must run within a transaction.If no transaction is in progress
an exception will be thrown
PROPAGATION_NESTED
PROPAGATION_NEVER indicate that the method can not run withi a transaction. if a transaction exist an exception will be thrown.
PROPAGATIOM_NOT_SUPPORT Indicates that the method should not run within a transaction. If an existing transaction is in progress, it will be suspended for the
duration of the method.
PROPAGATION_REQUIRED indicate that the current method must run within a transaction.if an existing transaction is in progress,the ,method will run with the transaction
otherwise a new transaction will be started
PROPAGATION_REQUIRENEW indicates that the current must run within its own
transaction.A new transaction is started and an existing transaction will be suspend
PROPAGATION_SUPPORT indicate the current mehtod does not require a transaction.but may run if on is already in progress
b Isolation levels
Isolation level What it means
ISOLATION_DEFAULT Using the defaul isolation level of the underlying database
ISOLATION_READ_UNCOMMITTED Allows you read change that have not yet been commit
May result in dirty read,phantom read,nonrepeatable read
ISOLATION_READ_COMMITTED Allows reads from concurrent transactions that have
bean committed.Dirty read are prevent.but platform and norepeatable reads may still occur.
ISOLATIOM_REPEATABLE_READ Multiple read the same field will yield the same result ,unless changed by the transaction itself.Dirty reads ,nonrepeatable are all prevented
phantom may still occur
ISOLATION_SERIALIZABLE This fully ACID-compliant isolation level ensusme that dirty read,unrepeatable read ,phantom read are all prevented.And this is the most slowest isolation
since it is typically accomplished by doing full table lock on the tables in the transaction.
c Read-Only
If a transaction performs only read operation against the underlying datastore.when a transaction begin ,it only make sense to declare a transaction as read only on mehtods with
propagation behavior which start a new transaction.
Furthermore ,if you are Hibernate as persistence mechanism,declaring a transaction as read only will reult in Hibernate flush mode being set to FLUST_NEVER.this tell hibernate to avoid synchroniztion of objects with database.
d Transaction timeout
Suppose that your transaction becomes unexpectedly long-running transaction.Because transaction may invole locks on the underlying database.Instead of waiting it out ,you can delcare a transaction to automaitically roll back.
because timeout clock begin ticking when a transaction start. it only make sense to declare a transaction timeout on methods with propagation behavior that start a new transaction.
2) Declaring a simple transaction policy
<bean id="myTransactionAttribute"
class="org.springframework.transaction.interceptor.
DefaultTransactionAttribute">
<property name="propagationBehaviorName">
<value>PROPAGATION_REQUIRES_NEW</value>
</property>
<property name="isolationLevelName">
<value>ISOLATION_REPEATABLE_READ</value>
</property>
</bean>
<bean id="transactionAttributeSource"
class="org.springframework.transaction.interceptor.
MatchAlwaysTransactionAttributeSource">
<property name="transactionAttribute">
<ref bean="myTransactionAttribute"/>
</property>
</bean>
4 Declaring transactions by method name
1) Using NameMatchTransactionAttributeSource
The properties property of NameMatchTransactionAttributeSource maps mehtod to a transaction property descriptor. the property descriptor takes the following form:
Propagation,isolation,readOnly,-Exception,+Exception
<bean id="transactionAttributeSource"
class="org.springframework.transaction.interceptor.
NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="enrollStudentInCourse">
PROPAGATION_REQUIRES_NEW
</prop>
</props>
</property>
</bean>
2) Specifying the transaction Isolation level
<bean id="transactionAttributeSource"
class="org.springframework.transaction.interceptor.
NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="enrollStudentInCourse">
PROPAGATION_REQUIRES_NEW,ISOLATION_REPEATABLE_READ
</prop>
</props>
</property>
</bean>
3) Using real-only transaction
<bean id="transactionAttributeSource"
class="org.springframework.transaction.interceptor.
NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="getCompletedCourses">
PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ,readOnly
</prop>
</props>
</property>
</bean>
4)Specifying rollback rules
You can sepcify that a transaction be rollback on specify checked exception
<bean id="transactionAttributeSource"
class="org.springframework.transaction.interceptor.
NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="enrollStudentInCourse">
PROPAGATION_REQUIRES_NEW,ISOLATION_REPEATABLE_READ,
-CourseException
</prop>
</props>
</property>
</bean>
Exception can be marked as negative(-) or postive(+)
Negative exception will trigger the roll back if the exception (or sublclass of it) is thrown.Postive exception on the other hand indicate that the transacton should be commit
even if the exception is thrown
5)Using wildcard matches
<bean id="transactionAttributeSource"
class="org.springframework.transaction.interceptor.
NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="get*">
PROPAGATION_SUPPORTS
</prop>
</props>
</property>
</bean>
6 Short-cut name match transaction
<bean id="courseService" class="org.springframework.transaction.
interceptor.TransactionProxyFactoryBean">
<property name="transactionProperties">
<props>
<prop key="enrollStudentInCourse">
PROPAGATION_REQUIRES_NEW
</prop>
</props>
</property>
</bean>
一 Unicode 简介
1 Unicode 是ASCII 扩展,从传统的7位,扩展位16 位,可以显示世界上所有语言
ASCII 码
0- 1- 2- 3- 4- 5- 6- 7-
-0 NUL DLE SP 0 @ P ` p
-1 SOH DC1 ! 1 A Q a q
-2 STX DC2 " 2 B R b r
-3 ETX DC3 # 3 C S c s
-4 EOT DC4 $ 4 D T d t
-5 ENQ NAK % 5 E U e u
-6 ACK SYN & 6 F V f v
-7 BEL ETB ' 7 G W g w
-8 BS CAN ( 8 H X h x
-9 HT EM ) 9 I Y I y
-A LF SUB * : J Z j z
-B VT ESC + ; K [ k {
-C FF FS , < L \ l |
-D CR GS - = M ] m }
-E SO RS . > N ^ n ~
-F SI US / ? O _ o DEL
2 双位字符集
DBCS:double-byte character set,最初的128个代码是ASCII,较高的128个代码中的某些总是跟随著第
二个位元组。这两个位元组一起(称作首位元组和跟随位元组)定义一个字元。
3 Unicode 解决方案
Unicode是统一的16位元系统,也DBCS 这样的同时含有一位和两位的字符集不同,Unicode 可以表示
65536 个字符。
Unicode 的缺点是,Unicode 使用的空间是ASCII 的两倍
二 宽字符和c
1 char
char c='A';
变量c 用一个字节来存储,用16 进制表示位0x41
char * p;
32 位系统,一次指针变量需要用4个字节表示
char * p="Hello!";
字符串占用7个字节 其中 6个用于保存字符串,1个用于保存中止符号0
char [10]
占用10个字节
char a[]="Hello!";
占用 7个字节
2 宽字节
typedef unsigned short whcar_t which is define in the window.h
与unsign short 一样 为16 字节,两个字节
wchar_t c='A' 0x0041
wchar_t *p=L"Hello!" 指针占用 4个字节 而 字符串占用 14 个字节
3 宽字元程序库函数
char * pc = "Hello!" ;
iLength = strlen (pc) ;
wchar_t * pw = L"Hello!" ;
iLength = wcslen (pw) ;
4 维护单一原始码
Microsoft Visual C++包含的TCHAR.H
如果定义了名为_UNICODE的识别字,并且程式中包含了TCHAR.H表头档案,那么_tcslen就定义为wcslen
#define _tcslen wcslen
如果没有定义UNICODE,则_tcslen定义为strlen:
#define _tcslen strlen
如果定义了 _UNICODE识别字,那么TCHAR就是wchar_t:
typedef wchar_t TCHAR ;
否则,TCHAR就是char:
typedef char TCHAR ;
如果没有定义_UNICODE识别字
#define __T(x) x
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
三 宽字节和windows
1 window 头文件中的类型
typedef char CHAR ;
typedef wchar_t WCHAR ;
typedef CHAR * PCHAR, * LPCH, * PCH, * NPSTR, * LPSTR, * PSTR ;
typedef CONST CHAR * LPCCH, * PCCH, * LPCSTR, * PCSTR ;
typedef WCHAR * PWCHAR, * LPWCH, * PWCH, * NWPSTR, * LPWSTR, * PWSTR ;
typedef CONST WCHAR * LPCWCH, * PCWCH, * LPCWSTR, * PCWSTR ;
#ifdef UNICODE
typedef WCHAR TCHAR, * PTCHAR ;
typedef LPWSTR LPTCH, PTCH, PTSTR, LPTSTR ;
typedef LPCWSTR LPCTSTR ;
#else
typedef char TCHAR, * PTCHAR ;
typedef LPSTR LPTCH, PTCH, PTSTR, LPTSTR ;
typedef LPCSTR LPCTSTR ;
#endif
2 Windows 函数调用
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif
3 Windows 的字符函数
ILength = lstrlen (pString) ;
pString = lstrcpy (pString1, pString2) ;
pString = lstrcpyn (pString1, pString2, iCount) ;
pString = lstrcat (pString1, pString2) ;
iComp = lstrcmp (pString1, pString2) ;
iComp = lstrcmpi (pString1, pString2) ;
4 在windows 使用printf
windows 并不支持printf 但是可以使用sprintf
int printf (const char * szFormat, ...) ;
printf ("The sum of %i and %i is %i", 5, 3, 5+3) ;
int sprintf (char * szBuffer, const char * szFormat, ...) ;
char szBuffer [100] ;
sprintf (szBuffer, "The sum of %i and %i is %i", 5, 3, 5+3) ;
puts (szBuffer) ;
一 Spring DAO philosophy
1 Understanding Spring's DataAccesssException
Spring's DAO frameworks donot throw teechnology-specific exceptions such as SQLException
or HibernateeExcepiton.Instead ,all exceptions thrown are subclasses of DataAccessException
2 You are not forced to handle DataAccessExceptions
DataAccessException is a RuntimeException,so it si an unchecked exception.Since these are quite often unrecoverable,you are not forced to handle these exception.
Instead ,you can catch the exception if recovery is possible.since DataAccessException is not only a RuntimeException,but it subclasses Spring's NestedRuntimeException. This menas that the root Exception is alwarys via NestedRuntimeException's getCause() method.
3 Work with DataSources
a getting a Datasource from JNDI
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/myDatasource</value>
</property>
</bean>
b Creating a Datasource connection pool
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driver">
<value>${db.driver}</value>
</property>
<property name="url">
<value>${db.url}</value>
</property>
<property name="username">
<value>${db.username}</value>
</property>
<property name="password">
<value>${db.password}</value>
</property>
</bean>
c Using a DataSource while testing
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
4 Consistent DAO support
Spring template class handle the invariant part of data access-controling the trancsaction
manage resource,handling exception .Implementation of callback interface define what is specific to your application--creating statement,binding parameter and marshalling result set.
Spring separates the fixed an vaiant parts of data access process into tow distince classes:
template and callbacks.Template manage the fixed parts of the process while callback are where you fill in the implement details;
one the top of template-callback desing ,spring framework provide a support class which your own data access subclass it. And the support class already have a property for holding a template.
二 Integerating Hibernate with Spring
1 Managing Hibernate resources
you will keep a single instance of SessionFactory throughtout your application
<bean id="sessionFactory"class="org.springframework.
orm.hibernate.LocalSessionFactoryBean">
<bean id="sessionFactory" class="org.springframework.
orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
you also want to manager how hibernate is configured
<bean id="sessionFactory" class="org.springframework.
orm.hibernate.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.
dialect.MySQLDialect</prop>
</props>
</property>
…
</bean>
and the last thing is whick map files is read
<bean id="sessionFactory" class="org.springframework.
orm.hibernate.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>Student.hbm.xml</value>
<value>Course.hbm.xml</value>
…
</list>
</property>
…
</bean>
Now you have fully configured your sessionfactory ,so we need do create an object which we
will access hibernate. As we know, we will use a template class
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="courseDao" class="com.springinaction.
training.dao.hibernate.CourseDaoHibernate">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate"/>
</property>
</bean>
2 Accessing Hibernate through HibernatTemplate
The template-callback mechanism in Hibernatee is pretty simple.There is the HibernatTmpplate and one callback interface
public Student getStudent(final Integer id) {
return (Student) hibernateTemplate.execute(
new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException {
return session.load(Student.class, id);
}
});
The HibernateTemplate class provides some convience methods that implicit create a HibernateCallback instance:
(Student) hibernateTemplate.load(Student.class, id);
hibernateTemplate.update(student);
hibernateTemplate.find("from Student student " +
"where student.lastName = ?",
lastName, Hibernate.STRING);
3 Subclassing HibernateDaoSupport
public class StudentDaoHibernate extends HibernateDaoSupport
implements StudentDao {
…
}
getHibernateTemplate()
getSession()