JPA Domain 을 디비에 자동으로 생성되게 해놓았는데


AWS RDS 에 DB 를 새로 세팅하고 MySQL 에서 Foreign key 걸때 아래와 같이 에러가 났다.


Error Code: 1215. Cannot add foreign key constraint


이것저것 보다보니 Dump 떠서 생성했던 기존 Table.Column 의 Collation 과 JPA 가 생성한 Collation 이 다르네


하나는 utf8_general_ci, 다른 하나는 utf8_bin 


두개가 서로 맞지않으면서 foreign key 생성이 안되던 문제


해결책은 아래



http://confluence.goldpitcher.co.kr/pages/viewpage.action?pageId=138838813

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



MongoDB 쿼리 옵션 모음



1. 프로젝션

프로젝션은 결과 값 도큐먼트에 대해 리턴할 필드를 지정하는 데 사용한다.


특별히 도큐먼트의 수가 많을 때 프로젝션을 사용하면 네트워크 지연(latency)과 디시리얼라이제이션에 들어가는

비용을 줄일 수 있다.


프로젝션은 다음과 같이 리턴할 필드로 보통 정의된다.


1) 리턴받고 싶은 필드를 정의하거나, 제외할 필드를 정의 할 수 있다.


db.users.find({}, {username:1})

==> 위 쿼리는 users 도큐먼트에서 username 필드와 _id 필드만을 리턴한다. _id는 디폴트로 항상 리턴한다.


포함시키지 않고싶은 필드는 0을 주면된다.

db.users.find({}, { address : 0, pay : 0})  // address와 pay 필드는 제외된 값이 리턴된다.



2) $slice - 리턴될 배열의 값을 어떤 범위 내에서 정할 수있다.

  예를 들어 리뷰를 여러 페이지로 나눠서 보여주길 원한다면 $slice 연산자로 제한할 수 있다.


도큐먼트 : { a:1, b:2, review:[{rating:3, ...},{},{},{},{},{},{},{},{},{}...] }


db.products.find({}, { review : { $slice: 12} }) // 결과값중 처음 12개만 가져온다.

db.products.find({}, { review : { $slice: -5} }) // 결과값중 마지막 5개만 가져온다.



$slice 는 2개의 숫자로 된 배열로도 가능하다. 각각. 스킵(skip), 리미트(limit) 를 나타낸다.


처음 24개의 리뷰를 제외하고 난 후 가져올 리뷰를 12개로 제한하는 쿼리

db.products.find({},{ review : { $slice : [24, 12]} })



3)   1) 과 2)를 조합하여 사용하는 예


바로위 쿼리에 review의 rating 필드만 가져오고 싶을때 


db.products.find({}, { review : { $slice : [24, 12], 'review.rating' : 1} } )








1. 정렬

정렬은 오름차순, 내림차순으로 정렬할 수 있다.


내림차순 

==> db.products.find({}).sort({ rating : -1 })


오름차순 

==> db.products.find({}).sort({ rating : 1 })


2개이상의 조건 

==> db.products.find({}).sort({ helpful: -1, rating: -1 })



추가중



YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



MongoDB 쿼리 연산자 모음




1. <, <=, >, >= 연산자

Mongo DB에서 <, <=, >, >= 를 사용할 때,


<  는  "$lt"

<=  는  "$lte"


>  는  "$gt"

>=  는  "$gte"


로 표현할 수 있다.


예제


SELECT * FROM users WHERE age >= 20;

==> db.users.find({ age : { "$gte" : 20 } });


SELECT * FROM users WHERE age < 20;

==> db.users.find({ age : { "$lt" : 20 } });


 AND 연산

SELECT * FROM users WHERE age BETWEEN 20 AND 25;

==> db.users.find({ age : { "$gte" : 20 , "$lte" : 25} });



age:{"gte":20}, age:{"$lte":25} 로 질의하면 같은 도큐먼트 내의 같은 수준에서는 반복으로 

질의 할 수 없습니다. 따라서 틀렸습니다.





2. $in, $nin, $all 연산자

SELECT * FROM users WHERE age IN(3,5,7,9);

==> db.users.find({ age : { $in : [3, 5, 7, 9] });


SELECT * FROM users WHERE age NOT IN(3,5,7,9);

==> db.users.find({ age : { $nin : [3, 5, 7, 9] }); // 문자열["ab", "안녕", "margo"]




모든 조건이 검색키와 일치되는 도큐먼트 찾기


도큐먼트 

{ name: "Bird Feeder",

   tags: [ "gift", "birds", "garden" ]

}

==> db.products.find({ tags : { $all : ["gift", "garden"] }  });






3. $ne, $not, $or, $and, $exists
 연산자

$ne - 같지않음(not equal to)  ** 단일한 값이거나, 배열인 경우 모두 수행된다

name 이 "ace" 인 도큐먼트중 tags가 "test" 가 아닌 모든 도큐먼트

==> db.products.find({ 'name':'ace', tags: {$ne : "test"} })



$not - 다른 연산자나 정규 표현식으로 부터 얻은 결과의 여집합을 리턴

성이 B로 시작하지 않는 모든 유저의 도큐먼트

==> db.users.find({ last_name: { $not: /^B/ } })



$or - 서로 다른 키에 대한 검색을 할 때 사용한다. 만약 같은 키에 대해 찾는다면  $in을 써야한다.

color 가 blue 이거나, name 이 ace인 도큐먼트를 검색할 때

==> db.products.find({ $or : [

{ 'details.color': 'blue'}

, { 'details.name': 'ace'}

})



$and 

- {age:3, name:'margo'} 는 age :3 AND name:'margo' 로 해석된다.

  이런 방법으로 AND 를 표현할 수 없을때 $and를 사용한다.

예제 도큐먼트

{ tags: ['gift', 'holiday', 'gardening', 'landscaping'] }


gift 나 holiday중 하나가 포함되고, gardening 나 landscaping 중 하나가 포함된 도큐먼트를

찾고싶을때, 이 쿼리를 표현하는 유일한 방법은 2개의 $in 쿼리를 $and 로 연결하는 것이다.


db.products.find({ $and : [

{tags : { $in : ['gift', 'holiday']}}

, {tags : { $in : ['gardening', 'landscaping']}}

]

}) 




$exists - 특정 키, 즉 도큐먼트가 해당 속성을 가지고 있는지 질의하는 쿼리다.

도큐먼트내에 특성 속성이 존재할수도 있고, 존재하지 않을수도 있다.

상품에 대한 컬렉션의 경우, 어떤 상품만의 특별한 키를 가질수 있을텐데, 

그때 해당도큐먼트가 그 키를 가지고 있는지 확인하고싶을때 사용한다.


속성을 가지고 있지 않은 도큐먼트를 찾을때 - false

==> db.products.find({ 'datails.color' : { $exists : false}})


속성을 가진 도큐먼트 - true

==> db.products.find({ 'datails.color' : { $exists : true}})


$exists : false 는 아래와 같이 표현가능하다.

==> db.products.find({ 'details.color' : null })


$exists : true 는 아래와 같이 표현가능하다.

==> db.products.find({ 'details.color' : {$ne: null }  })



YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



DB에 저장되어있는 컬럼 중에 DATE 타입에 대한 연산이 필요할 때가 있다.

예를 들어 지금시간으로부터 12시간안의 모든 레코드를 필요로 한다던지,

지금시간으로부터 12시간 이전의 자료를 모두 삭제한다던지 할때 DATE 형이 시간이 기록되어 있다면

시간까지 연산가능하고, 만약 시간이 기록되지 않은 DATE 타입이면 날짜연산만 가능하다. 




UPDATE sample SET state = 'done' WHERE date < DATE_ADD(now(), INTERVAL -6 hour)

 ↑ 해석 : sample 테이블의 date 컬럼의 시간이

             현재(now()) 시간으로부터 6시간전의 시간을 기준으로 그 이전시간 레코드의
             state 컬럼을 'done'으로 다 입력한다. 




DATE_ADD(now(), INTERVAL -6 hour)

↑ 이 문장에서 hour 대신에 year, day, minute, second 로 바꿀 수 있다.

맨위 코드에서 '<' 를 '>' 로 바꾸게되면

6시간전을 기준으로 이전레코드가 아니라, 현재시간으로부터 6시간내의 자료만 가져올 것이다.


헷갈린다면 한번 해보면 확실할 것.

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



제목 그대로다

 PreparedStatement 에서 LIKE 를 쓰고 싶을때, '?' 와 '%' 합치는 법

출처 :  http://mainia.tistory.com/557 녹두장군님



웹 어플리케이션 작업시 sql 쿼리를 보통 properties xml 로 문자열을 만들어 빼놓는다.

예전처럼 무식하게 쿼리를 문자열 합치기로 소스상에서 사용하지는 않는다여러가지 문제가

많기 때문이다.

 

쿼리에서 동적으로 변하는 데이타는 ? 를 써서 문자열을 만들고 PreparedStatement 사용해

파라미터 값을 맵핑시킨다아래는 스프링의 예이다스프링은 framework 내부에 PreparedStatement

사용해서 맵핑을 구현해 놓았고 우리가 사용하는 부분은 아래와 같이 함수에 파라미터로

갯수에 맞게 Objec 배열로 넘기면 된다.

 

쿼리문자열

test.srch.select = \n\

           select * from board where id = ? \n\

 

String sql = message.getMessage("test.srch.select");

getJdbcTemplate().queryForList(sql, new String[]{srchText});

 

일반적인 쿼리문자열은 이렇게 적용을 하면 되는데 문제는 like 를 사용할때 이다.

보통 사용하는 것처럼 like %?% 로 하면 안된다. % 문자와 ? 맵핑할 문자를 합쳐야 된다.

RDBMS 프로그램에 따라 차이가 있다. Oracle 일때에는  like '%' || ? || '%' 사용하면 된다.

중간에 ORM framework 인 iBatis 를 사용할 경우에는 like '%' || #?# || '%' 이다.

 

 

하지만 MySql 일 경우에는 이것이 통하지 않는다그래서 문자열을 합치는 함수를 사용해

해결하였다일반적인 경우는 like concat ('%', ?, '%') 이며 

iBatis 
라고 한다면

like concat ('%', #?#, '%') 사용해서 처리 하면된다.



 
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



윈도우7 64bit 에서

오라클 sql developer 가 java.exe 를 찾지 못하면서  실행되지 않는 이유는

JDK 가 64bit 용이기 때문이다.

오라클 Sql Developer 는  64bit java.exe 를 사용하지 못한다.

그래서 JDK 를 32bit 버전을 깔고,

그 패스를 지정해주면 정상적으로 실행된다. 






Oracle SQL Developer unable to find Java Virtual Machine

Published: April 21, 2011 , Updated: April 21, 2011 , Author: mkyong

Problem

Here’s my PC environment :

  1. Database : Oracle 11g
  2. OS Platform : Windows 7 Ultimate 64 bits
  3. JDK : 1.6 .0_24, 64 bits

While click on the Oracle SQL developer, it prompts me to key in the JDK folder. However, after i specified the JDK folder, it prompts me following error dialog box :


Oracle SQL developer is NOT support on 64 bits JDK. To solve it, install a 32 bits / x86 JDK and update your SQL developer config file, so that it points to the 32 bits JDK.

Fix it!
Edit the “sqldeveloper.conf“, which can be found under “{ORACLE_HOME}\sqldeveloper\sqldeveloper\bin\sqldeveloper.conf“, make sure “SetJavaHome” is point to your 32 bits JDK.

For example, “SetJavaHome C:\Program Files (x86) \Java\jdk1.6.0_13“.


YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


PL/SQL 이란 ?

- PL/SQL 은 Oracle's Procedural Language extension to SQL. 의 약자 입니다.
- SQL 문장에서 변수정의, 조건처리(IF), 반복처리(LOOP, WHILE, FOR)등을 지원하며,

오라클 자체에 내장되어 있는 Procedure Language 입니다
- DECLARE 문을 이용하여 정의되며, 선언문의 사용은 선택 사항입니다.
- PL/SQL 문은 블록 구조로 되어 있고 PL/SQL 자신이 컴파일 엔진을 가지고 있습니다.


PL/SQL 의 장점

- PL/SQL 문은 BLOCK 구조로 다수의 SQL 문을 한번에 ORACLE DB 로 보내서 처리하므로 수행속도를 향상 시킬수 있습니다.
- PL/SQL 의 모든 요소는 하나 또는 두개이상의 블록으로 구성하여 모듈화가 가능하다.
- 보다 강력한 프로그램을 작성하기 위해서 큰 블록안에 소블럭을 위치시킬 수 있습니다.
- Variable, Constant, Cursor, Exception 을 정의하고, SQL 문장과 Procedural 문장에서 사용합니다.
- 단순, 복잡한 데이터형태의 변수를 선언합니다.
- 테이블의 데이터 구조와 DataBase 의 컬럼럼에 준하여 동적으로 변수를 선언 할 수 있습니다.
- Exception 처리 루틴을 이용하여 Oracle Server Error 를 처리합니다.
- 사용자 정의 에러를 선언하고 Exception 처리 루틴으로 처리 가능 합니다.

PL/SQL Block Structure

- PL/SQL 은 프로그램을 논리적인 블록으로 나누는 구조화된 블록 언어 입니다.
- PL/SQL 블록은 선언부(선택적), 실행부(필수적),예외 처리부(선택적)로 구성되어 있고, BEGIN 과 END 키워드는 반드시 기술해 주어야 합니다.
- PL/SQL 블록에서 사용하는 변수는 블록에 대해 논리적으로 선언할 수 있고 사용할 수 있습니다.

◈ Declarative Section(선언부)
- 변수, 상수, CURSOR, USER_DEFINE Exception 선언

◈ Executable Section(실행부)
- SQL, 반복분, 조건문실행
- 실행부는 BEGIN 으로 시작하고 END 로 끝납니다.
- 실행문은 프로그램 내용이 들어가는 부분으로서 필수적으로 사용되어야 합니다.

◈ Exception Handling Section(예외처리)
- 예외에 대한 처리.
- 일반적으로 오류를 정의하고 처리하는 부분으로 선택 사항입니다.




● DECLARE
- Optional
- Variables, cursors, user-defined exceptions
● BEGIN
- Mandatory
- SQL Statements
- PL/SQL Statements
● EXCEPTION
- Actions to perform when errors occur
● END;
- Mandatory



PL/SQL 프로그램의 작성 요령

- PL/SQL 블록내에서는 한 문장이 종료할 때마다 세미콜론(;)을 사용합니다. .
- END 뒤에 ;을 사용하여 하나의 블록이 끝났다는 것을 명시 합니다.
- PL/SQL 블록의 작성은 편집기를 통해 파일로 작성할 수도 있고, SQL 프롬프트에서 바로 작성할 수도 있습니다.
- SLQ*PLUS 환경에서는 DELCLARE 나 BEGIN 이라는 키워드로 PL/SQL 블럭이 시작하는 것을 알 수 있습니다.
- 단일행 주석 : --
- 여러행 주석 : /* */
- PL/SQL 블록은 행에 / 가 있으면 종결됩니다.

출처 : http://www.oracleclub.com/oraclelecture.action?lectureType=PLSQL
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


프로시져란?

 - 특정 작업을 수행할수 있고, 이름이 있는 PL/SQL 블록으로서. 매개 변수를 받을 수 있고..

반복적으로 사용할 수 있는거죠.. 보통 연속 실행 또는 구현이 복잡한 트랜잭션을 수행하는 PL/SQL 블록을 데이터 베이스에 저장하기 위해 생성합니다.
⊙ CREATE OR REPLACE 구문을 사용하여 생성합니다.
⊙ IS 로 PL/SQL 의 블록을 시작합니다.
⊙ LOCAL 변수는 IS 와 BEGIN 사이에 선언합니다.




프로시저 작성방법입니다.

// 리턴값이 없는 프로시져입니다. 
// 모든 파라미터 타입이 'IN' 입니다.

create or replace PROCEDURE setContent
(in_id VARCHAR2, in_title VARCHAR2, in_body VARCHAR2, in_password VARCHAR2, in_fileName VARCHAR2)
// Parameter Type 이 in, 인자 out 인지 생략되어 있는데
// 생략할 경우 in_in in VARCHAR2 처럼 in 으로 인식됩니다. 

is

BEGIN
INSERT INTO
margo VALUES(
margo_sequence.NEXTVAL,
in_id,
in_title,
in_body,
in_password,
0,
0,
sysdate,
in_fileName
);
commit; // 커밋을 해야합니다. 만약 트랜잭션의 경우 예외처리를 두어서 RollBack 도 생각해볼수 있습니다.
end;
 


위 구문에서 'create or replace' 뜻은 없으면 프로시져를 생성하고, 있으면 수정하라는 뜻 입니다.

'is' 로 PL-SQL 블록을 시작합니다.

LOCAL 변수는 IS 와 BEGIN 사이에 선언합니다.

위 예제는 리턴값이 없는 디비에 in 만하는 예제였습니다.




다음 예제는 디비에 입력후에 리턴값을 받아보는 예제입니다.

create or replace PROCEDURE getContentTest
(in_article_num NUMBER, out_title
OUT varCHAR2, out_hit OUT NUMBER)
//리턴받는 파라미터로 2개를 주겠습니다.


is
BEGIN
SELECT
title,
hit
INTO
out_title,
out_hit
FROM margo
WHERE article_num = in_article_num;
commit;
end;
/ <<<<<<<<<-----  끝낼때는 무조건 '/' 기호를 붙이면 프로시져 작성이 끝납니다. 


article_num 이 입력받은 파라미터인  
in_article_num 과 같은 글의 title과 hit 을 가져와서 INTO out_title, out_hit에

입력하고 있습니다.

이렇게 입력된 파라미터는 리턴되어 외부에서 callableStatement 에서 심어진 인덱스번호로 뽑아낼수있습니다.




이제 위 프로시져를 사용하는 자바코드를 보겠습니다.

  
private CallableStatement cstmt = null;

..................


try{
conn = this.getConnection();
cstmt = conn.prepareCall("{call getContentTest( ?, ?, ? )}"); // 3개를 심습니다.
cstmt.setInt(1, article_num); // 첫번째는 가져올 컨텐츠의 글번호 입니다.
cstmt.registerOutParameter(2,Types.CHAR); //  저위의 예제에서 OUT 파라미터 와 매핑되는 리턴입니다.

cstmt.registerOutParameter(3,Types.INTEGER);  
//  저위의 예제에서 OUT 파라미터 와 매핑되는 리턴입니다.

cstmt.executeUpdate();
System.out.println("타이틀은 : " + cstmt.getString(2));
System.out.println("힛은 : " + cstmt.getInt(3));
} catch(Exception e){
e.printStackTrace();
}finally{
closeDoor();
}

 
{call getContentTest( ?, ?, ? )} 프로시져를 부를때는 

{} 괄호 사이에 프로시저명 앞에 call 을 붙이고,
인자를 순서와 개수에 맞게 입력해주면 됩니다. 


 

cstmt.registerOutParameter(2,Types.CHAR); 

cstmt.registerOutParameter(3,Types.INTEGER); 

보통의 리턴값은 ResultSet 을 이용해서 받지만 

프로시져를 이용하면 리턴값은 CallableStatement 자체가 됩니다.

심어놓은 인덱스번호를 그대로 뽑아내면 됩니다.


registerOutParameter() 메소드를 이용해서 (? 를심어놓은 순번, 리턴받을 타입) 을 해서, 리턴값을 받은다음

cstmt.getString(2) <<-- 이런식으로 순번을 적어서 값을 이용할수 있습니다. 











 
 
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


PL-SQL 이란 ?

Oracle's Procedural Language Extension to SQL. 의 약자입니다.

SQL 문장에서 변수정의, 조건처리(IF), 반복처리( Loop, While, For) 등을 지원하며,
오라클 자체에 내장되어 있는 Procedure Language입니다.

Declare 문을 이용하여 정의되며, 선언문의 사용은 선택 사항 입니다.
-PL/SQL 문은 블록 구조로 되어 있고, PL/SQL 자신이 컴파일 엔진을 가지고 있습니다.  



PL-SQL 의 장점

Block 구조로 다수의 SQL 문을 한번에 Oracle DB 로 보내서 처리하므로, 수행 속도를 향상 시킬수 있습니다.

모든요소는 하나 또는 두개 이상의 블록으로 구상하여 모듈화가 가능합니다. 



PL-SQL Block Structure

프로그램을 논리적인 블록으로 나누는 구조화된 블록 언어 입니다.

블록은 선언부(선택적), 실행부(필수적), 예외 처리부(선택적) 으로 구성되어 있고,
 BEGIN 과 END 키워드는 반드시 기술해 주어야 합니다.

블록내에서 사용하는 변수는 블록에 대해 논리적으로 선언할 수 있고 사용할 수 있습니다. 


Declarative Section(선언부)
 
- 변수, 상수 CURSOR, USER_DEFINE Exception 선언


Executable Section(실행부)

- SQL, 반복문, 조건문 실행
- 실행부는 BEGIN 으로 시작하고, END로 끝납니다.
- 실행문은 프로그램 내용이 들어가는 부분으로서 필수적으로 사용되어야 합니다.


Exception Handling Section(예외 처리부)

-예외에 대한 처리
- 일반적으로 오류를 정의하고 처리하는 부분으로 선택사항.

Figure 15.1 




PL/SQL 프로그램의 작성 요령
  - PL/SQL 블록내에서는 한 문장이 종료할 때마다 세미콜론(;)을 사용합니다. .
  - 
END뒤에 ;을 사용하여 하나의 블록이 끝났다는 것을 명시 합니다
  - PL/SQL 
블록의 작성은 편집기를 통해 파일로 작성할 수도 있고
    SQL
프롬프트에서 바로 작성할 수도 있습니다.
  - SLQ*PLUS
환경에서는 
DELCLARE BEGIN이라는 키워드로 PL/SQL블럭이 시작하는 것을 알 수 있습니다.
 - 
단일행 주석 : --
 - 
여러행 주석 : /* */
 - PL/SQL 
블록은 행에 / 가있으면 종결 됩니다.





YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



ORA-12514, ORA-28056, ORA-01034, ORA-27101 오라클 갑자기 접속 안될 때  Oracle 데이터베이스

2011/01/07 15:49

복사http://blog.naver.com/mbk82/110100506345

음...오라클을 비정상 종료하게 되면 가끔 볼 수 있게 되는 에러들이다.

 

ORA-12514 리스너가 현재 접속 기술자에 요청된 서비스를 알지 못함

ORA-01034, ORA-27101  이런 메시지가 나올 수도 있고...

 

기본적으로 리스너가 SID를 찾지 못하는 에러이다.

 

그런데 리스너를 건드리지도 않았고 TNS를 건들지도 않았는데 이런다...

이건 비정상 종료를 의심할 수 있다...

 

내가 해결한 방법은

 

시작 -> 실행 -> cmd

 

 

이렇게 3번까지 해서 DB가 마운트 되면

exit를 눌러서 나오면 된다.

 

오라클 서비스를 다시 시작하고 원래하던 것처럼 접속하면 잘 될 것이다.

 

하.지.만.

 

2번에서 암호를 입력했음에도 불구하고 접속이 안될 수가 있다.

 

ORA-28056

Writing audit records to Windows Event Log failed

 

바로 요놈;;;

 

이럴 때는 이벤트로그를 삭제해줘야 한다.

 

제어판 -> 관리도구 -> 이벤트뷰어

 

 

자 이렇게 지워주고서 다시 위에 1번, 2번, 3번 진행해보시기 바란다.

 

괜히 리스너 정보 계속 바꾸고

TNS 정보 바꾸고 삽질하고-.-;;

 

도움이 되시길...^-^

 

P.S : 혹시 Tns를 열심히 만지셨다면...되도록 초기화 시켜보시고 SERVICE_NAME 을 SID로 바꾸어 보기!!

        쉽게 풀리는 경우도 있음ㅋ

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST