1. 程式人生 > >hibernate QBC和QBE精講與案列分析(中)

hibernate QBC和QBE精講與案列分析(中)

16、Not equal

ne(String?propertyName, Object?value)

neProperty(String?propertyName, String?otherPropertyName)

From Object o where o.property not

17、查詢條件邏輯非

not(Criterion?expression)

From Object o where not(一個查詢條件)

18、查詢條件邏輯and

運算

or(Criterion?lhs, Criterion?rhs)

From Object o where o.property1 =? or o.property2=?

  

  具體各種方法的使用例子,請看8.3節。

Example類

  使用Example類進行查詢,首先需要建立一個物件樣板,然後檢索出所有與這個樣板物件相同的物件。如,

  BasicCar bc=new BasicCar();

  bc.setFactory("aaaa");

  

  Criteria crit = session.createCriteria(BasicCar.class);

  crit.add(Example.create(bc));

  

  List results = crit.list();

  Example使用靜態方法create(Object entity)來建立一個Criterion物件,它按照物件的屬性來比較查詢條件,以上的程式段檢索factory屬性為"aaaa"的BasicCar物件。

  另外,Example也提供了給這個樣板物件設定一些查詢過濾。例如,

  Example exampleUser =Example.create(bc)

  .ignoreCase() //忽略大小寫

  .enableLike(MatchMode.ANYWHERE); //任意位置的匹配

  

  Criteria crit = session.createCriteria(BasicCar.class);

  crit.add(exampleUser);

  List results = crit.list();

  這個查詢相當於查詢factory屬性為"�aa%",即只要對factory屬性值進行aaaa的模糊字串匹配。

  Example類提供的各種進行查詢過濾的方法如下。

● enableLike(MatchMode):用於過濾string匹配,有4個選擇。分別為MatchMode.ANYWHERE(預設匹配模式,表示任意位置的匹配,形如%value%)、MatchMode.END(表示匹配結尾,形如%value)、MatchMode.EXACT(表示完全匹配)、MatchMode.START (表示匹配開頭,形如value%)。

● excludeNone():排除為null或0的屬性值匹配。

● excludeProperty(String name):排除名字為name的屬性的匹配。

● excludeZeroes():排除為0的屬性值匹配。

● ignoreCase():匹配String時忽略大小寫。

● setEscapeCharacter(Character escapeCharacter):對like從句的字串匹配,排除某些字元。

● setPropertySelector(Example.PropertySelector selector):選擇屬性的匹配策略。

  這些過濾方法都是返回Example類,所以可以連線著設定各種過濾。

8.1.3  使用QBC各種檢索例子

  下面將通過具體的例子來介紹,如何使用Criteria查詢,結合各種Criterion查詢條件和Projection投影運算,滿足各種資料檢索要求。

  1.返回所有的物件

  下面是一個最簡單的Criteria查詢,只是在建立Criteria時制定檢索的物件,不設定任何查詢條件,即返回的List為所有的BasicCar物件。

  Criteria crit = session.createCriteria(BasicCar.class);

  List results = crit.list();

  返回的List中存放的是BasicCar物件。

  以上的程式碼相當於執行了select * from basiccar。

  2. 聚集函式

Criteria使用Projections類可以使用聚集函式max、min、avg、count、sum、countDistinct、rowCount等。

org.hibernate.criterion.Projections是 Projection 的例項工廠。我們通過呼叫 setProjection()應用投影到一個查詢。

List results = session.createCriteria(Cat.class)
    .setProjection( Projections.rowCount() )
    .add( Restrictions.eq("color", Color.BLACK) )
    .list();

List results = session.createCriteria(Cat.class)
    .setProjection( Projections.projectionList()
        .add( Projections.rowCount() )
        .add( Projections.avg("weight") )
        .add( Projections.max("weight") )
        .add( Projections.groupProperty("color") )
    )
    .list();

 

  如果需要使用多個Projections設定多個條件,則需要使用Projections的projectionList()函式建立一個ProjectList。

  下面的例子Projections的max、min、countDistinct返回BasicCar的最大id、最小日期和計算不同的名字有多少個。

  Criteria crit = session.createCriteria(BasicCar.class)

  ProjectionList projList = Projections.projectionList();

  projList.add(Projections.max("id"));

  projList.add(Projections.min("date"));

  projList.add(Projections.countDistinct("name"));

  crit.setProjection(projList);

  List results = crit.list();

  返回的List中存放有最大id,最小日期,不同name的個數,這三者組成的物件陣列。

  其對應的SQL語句如下:

  select max(this_.id) as y0_, min(this_.date) as y1_, count(distinct this_.name) as y2_ from basiccar this_

  3. many-to-one雙向關聯檢索

  檢索sid=1的Salesman物件關聯的carorder物件cid大於1的資料

  Criteria crit = session.createCriteria(Salesman.class);

  .add(Restrictions.eq("sid",new Long(1)))

  .createCriteria("carorders")

  .add(Restrictions.gt("cid",new Long(1)))

  .list();

  返回的List中存放的是Salesman物件。

  如果使用了連線檢索策略,以上查詢相當於執行以下的SQL語句:

  select * from salesman this_ inner join carorder1 carorder1_ on this_.sid=carorder1_.salesId left outer join salesman salesman4_ on carorder1_.salesId=salesman4_.sid where this_.sid=? and carorder1_.cid>?

  4.使用數學運算子>=、>、!=、=

  下面的例子檢索日期大於等於"1994-03-04"的BasicCar物件,並且使用setMaxResults(1)函式設定返回的列表只取一個結果。

     Criteria crit = session.createCriteria(BasicCar.class);

   crit.add( Expression.ge("date", Date.valueOf("1994-03-04")) );

   crit.setMaxResults(1);

 

   List results = crit.list();

  其對應的SQL語句如下:

  select *  from basiccar b where b.date>='1994-03-04'

  下面的例子檢索id大於1的BasicCar物件。

     Criteria crit = session.createCriteria(BasicCar.class);

   crit.add( Expression.gt("id", new Long(1)) );

   List results = crit.list();

  其對應的SQL語句如下:

  select *  from basiccar b where b.id>1

  下面的例子檢索id不等於1的BasicCar物件。

  Criteria crit = session.createCriteria(BasicCar.class);

  crit.add( Expression.ne("id", new Long(1)) );

  List results = crit.list();

  其對應的SQL語句如下:

  select *  from basiccar b where b.id<>1

  5. 查詢id

  下面的例子檢索主鍵為1的物件。

  Criteria crit = session.createCriteria(BasicCar.class);

  crit.add( Expression idEq(new Long(1)) );

  crit.setMaxResults(1);

  List results = crit.list();

  其對應的SQL語句如下:

  select *  from basiccar b where b.id = 1

  6. group by

  下面的例子按name來進行分組。

  Criteria crit = session.createCriteria(BasicCar.class);

  crit.setProjection(Projections.groupProperty("name"));

  List results = crit.list();

  返回物件List用來存放不同名字的陣列,存放的是string行的name。

  其對應的SQL語句如下:

  select b.name from basiccar b group by b.name

  7. 字串匹配,like和islike

  下面的例子使用like()函式檢索name開頭字母為A的BasicCar物件。

  Criteria crit = session.createCriteria(BasicCar.class);

  crit.add(Restrictions.like("name","A%"));

  List results = crit.list();

  其對應的SQL語句如下:

  select * from basiccar b where b.name like ‘A%’

  使用islike()函式,代表不區分大小寫的字串匹配。

  MatchMode可以選擇匹配模式,MatchMode.END從末端開始匹配,MatchMode.ANYWHERE表示任意地方的字串匹配, MatchMode.START從開始的地方開始匹配, MatchMode.EXACT表示整個字串精確匹配。

  下面的例子檢索資料庫name的後面字元為不區分大小寫的a的BasicCar物件。

  Criteria crit = session.createCriteria(BasicCar.class);

  crit.add(Restrictions.islike("name","a", MatchMode.END));

  List results = crit.list();

  8. is null

  下面的例子檢索資料庫name為空的BasicCar物件。

  Criteria crit = session.createCriteria(BasicCar.class);

  crit.add(Restrictions.isNull("name"));

  List results = crit.list();

  9. 投影某些屬性

  使用Projections.property()函式,可以對結果進行某些屬性的投影,相當於使用select語句。

  下面的例子返回結果進行name和date列的投影。

  Criteria crit = session.createCriteria(BasicCar.class);

  ProjectionList projList = Projections.projectionList();

  projList.add(Projections.property("name"));

  projList.add(Projections.property("date"));

  crit.setProjection(projList);

  List results = crit.list();

  返回的List中存放的是由name和date組成的物件陣列。

  其對應的SQL語句如下:

  select b.name as n, b.date as d from basiccar b

  10. 計算列返回的數目

  下面的例子計算返回的BasicCar物件的數量。

  Criteria crit = session.createCriteria(BasicCar.class);

  crit.setProjection(Projections.rowCount());

  List results = crit.list();

  其對應的SQL語句如下:

  select count(*) as y0_ from basiccar this_

  11. 設定返回結果

  下面的例子使用setFirstResult(2)設定從第二個開始返回,使用setMaxResults(2)設定每次最多返回2個物件。

  Criteria crit = session.createCriteria(BasicCar.class);

  crit.setFirstResult(2);

  crit.setMaxResults(2);

  List results = crit.list();

  下面的例子使用uniqueResult得到單個物件。

  Criteria crit = session.createCriteria(BasicCar.class);

  Criterion price = Restrictions.gt("name",new Lone(1));

  crit.setMaxResults(1);

  Product product = (Product) crit.uniqueResult();

  12. 結果排序

  使用Order類呼叫desc()函式、asc()函式可以進行排序。

  下面的例子根據BasicCar物件的name進行升序排序。

  Criteria crit = session.createCriteria(BasicCar.class);

  crit.addOrder(Order.desc("name"));

  對應的SQL語句是:

  Select * from basiccar b by b.name desc

  13. 邏輯or、and條件

  下面的例子中設定了3個條件,分別是id大於等於1,name開頭字母為P,factory的開頭字母為f。然後把前兩個條件進行邏輯或操作,即只要滿足其中之一,再把最後一個條件進行邏輯與操作。

  Criteria crit = session.createCriteria(BasicCar.class);

  Criterion id = Restrictions.gt("id",new Long(1));

  Criterion name = Restrictions.like("name","P%");

  LogicalExpression orExp = Restrictions.or(id,name);

  crit.add(orExp);

  crit.add(Restrictions.ilike("factory","f%"));

  List results = crit.list();

  在上面的例子中Restrictions.or()把id和name兩個檢索條件進行or結合;在原來的查詢條件上不斷地add(),那麼就相當於把檢索條件進行and邏輯與操作。

  其對應的SQL語句如下:

select * from basiccar this_ where (this_.id>? or this_.name like ?) and lower(this_.factory) like ?

 

16.1. 建立一個Criteria 例項

org.hibernate.Criteria介面表示特定持久類的一個查詢。Session是 Criteria例項的工廠。

Criteria crit = sess.createCriteria(Cat.class);
crit.setMaxResults(50);
List cats = crit.list();

16.2. 限制結果集內容

一個單獨的查詢條件是org.hibernate.criterion.Criterion 介面的一個例項。org.hibernate.criterion.Restrictions類 定義了獲得某些內建Criterion型別的工廠方法。

List cats = sess.createCriteria(Cat.class)
    .add( Restrictions.like("name", "Fritz%") )
    .add( Restrictions.between("weight", minWeight, maxWeight) )
    .list();

約束可以按邏輯分組。

List cats = sess.createCriteria(Cat.class)
    .add( Restrictions.like("name", "Fritz%") )
    .add( Restrictions.or(
        Restrictions.eq( "age", new Integer(0) ),
        Restrictions.isNull("age")
    ) )
    .list();

List cats = sess.createCriteria(Cat.class)
    .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
    .add( Restrictions.disjunction()
        .add( Restrictions.isNull("age") )
     .add( Restrictions.eq("age", new Integer(0) ) )
     .add( Restrictions.eq("age", new Integer(1) ) )
     .add( Restrictions.eq("age", new Integer(2) ) )
    ) )
    .list();

Hibernate提供了相當多的內建criterion型別(Restrictions 子類), 但是尤其有用的是可以允許你直接使用SQL。

List cats = sess.createCriteria(Cat.class)
    .add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) )
    .list();

{alias}佔位符應當被替換為被查詢實體的列別名。

Property例項是獲得一個條件的另外一種途徑。你可以通過呼叫Property.forName() 建立一個Property

Property age = Property.forName("age");
List cats = sess.createCriteria(Cat.class)
    .add( Restrictions.disjunction()
        .add( age.isNull() )
     .add( age.eq( new Integer(0) ) )
     .add( age.eq( new Integer(1) ) )
     .add( age.eq( new Integer(2) ) )
    ) )
    .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )
    .list();

16.3. 結果集排序

你可以使用org.hibernate.criterion.Order來為查詢結果排序。

List cats = sess.createCriteria(Cat.class)
    .add( Restrictions.like("name", "F%")
    .addOrder( Order.asc("name") )
    .addOrder( Order.desc("age") )
    .setMaxResults(50)
    .list();

List cats = sess.createCriteria(Cat.class)
    .add( Property.forName("name").like("F%") )
    .addOrder( Property.forName("name").asc() )
    .addOrder( Property.forName("age").desc() )
    .setMaxResults(50)
    .list();

16.4. 關聯

你可以使用createCriteria()非常容易的在互相關聯的實體間建立 約束。

List cats = sess.createCriteria(Cat.class)
    .add( Restrictions.like("name", "F%")
    .createCriteria("kittens")
        .add( Restrictions.like("name", "F%")
    .list();

注意第二個 createCriteria()返回一個新的 Criteria例項,該例項引用kittens 集合中的元素。

接下來,替換形態在某些情況下也是很有用的。

List cats = sess.createCriteria(Cat.class)
    .createAlias("kittens", "kt")
    .createAlias("mate", "mt")
    .add( Restrictions.eqProperty("kt.name", "mt.name") )
    .list();

(createAlias()並不建立一個新的 Criteria例項。)

Cat例項所儲存的之前兩次查詢所返回的kittens集合是 沒有被條件預過濾的。

List cats = sess.createCriteria(Cat.class)
    .createCriteria("kittens", "kt")
        .add( Restrictions.eq("name", "F%") )
    .returnMaps()
    .list();
Iterator iter = cats.iterator();
while ( iter.hasNext() ) {
    Map map = (Map) iter.next();
    Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
    Cat kitten = (Cat) map.get("kt");
}

16.5. 動態關聯抓取

你可以使用setFetchMode()在執行時定義動態關聯抓取的語義。

List cats = sess.createCriteria(Cat.class)
    .add( Restrictions.like("name", "Fritz%") )
    .setFetchMode("mate", FetchMode.EAGER)
    .setFetchMode("kittens", FetchMode.EAGER)
    .list();

這個查詢可以通過外連線抓取matekittens。 檢視第 20.1 節 “ 抓取策略(Fetching strategies) ”可以獲得更多資訊。

16.6. 查詢示例

org.hibernate.criterion.Example類允許你通過一個給定例項 構建一個條件查詢。

Cat cat = new Cat();
cat.setSex('F');
cat.setColor(Color.BLACK);
List results = session.createCriteria(Cat.class)
    .add( Example.create(cat) )
    .list();

版本屬性、識別符號和關聯被忽略。預設情況下值為null的屬性將被排除。

你可以自行調整Example使之更實用。

Example example = Example.create(cat)
    .excludeZeroes()           //exclude zero valued properties
    .excludeProperty("color")  //exclude the property named "color"
    .ignoreCase()              //perform case insensitive string comparisons
    .enableLike();             //use like for string comparisons
List results = session.createCriteria(Cat.class)
    .add(example)
    .list();

你甚至可以使用examples在關聯物件上放置條件。

List results = session.createCriteria(Cat.class)
    .add( Example.create(cat) )
    .createCriteria("mate")
        .add( Example.create( cat.getMate() ) )
    .list();

16.7. 投影(Projections)、聚合(aggregation)和分組(grouping)

org.hibernate.criterion.Projections是 Projection 的例項工廠。我們通過呼叫 setProjection()應用投影到一個查詢。

List results = session.createCriteria(Cat.class)
    .setProjection( Projections.rowCount() )
    .add( Restrictions.eq("color", Color.BLACK) )
    .list();

List results = session.createCriteria(Cat.class)
    .setProjection( Projections.projectionList()
        .add( Projections.rowCount() )
        .add( Projections.avg("weight") )
        .add( Projections.max("weight") )
        .add( Projections.groupProperty("color") )
    )
    .list();

在一個條件查詢中沒有必要顯式的使用 "group by" 。某些投影型別就是被定義為 分組投影,他們也出現在SQL的group by子句中。

你可以選擇把一個別名指派給一個投影,這樣可以使投影值被約束或排序所引用。下面是兩種不同的實現方式:

List results = session.createCriteria(Cat.class)
    .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
    .addOrder( Order.asc("colr") )
    .list();

List results = session.createCriteria(Cat.class)
    .setProjection( Projections.groupProperty("color").as("colr") )
    .addOrder( Order.asc("colr") )
    .list();

alias()as()方法簡便的將一個投影例項包裝到另外一個 別名的Projection例項中。簡而言之,當你新增一個投影到一個投影列表中時 你可以為它指定一個別名:

List results = session.createCriteria(Cat.class)
    .setProjection( Projections.projectionList()
        .add( Projections.rowCount(), "catCountByColor" )
        .add( Projections.avg("weight"), "avgWeight" )
        .add( Projections.max("weight"), "maxWeight" )
        .add( Projections.groupProperty("color"), "color" )
    )
    .addOrder( Order.desc("catCountByColor") )
    .addOrder( Order.desc("avgWeight") )
    .list();

List results = session.createCriteria(Domestic.class, "cat")
    .createAlias("kittens", "kit")
    .setProjection( Projections.projectionList()
        .add( Projections.property("cat.name"), "catName" )
        .add( Projections.property("kit.name"), "kitName" )
    )
    .addOrder( Order.asc("catName") )
    .addOrder( Order.asc("kitName") )
    .list();

你也可以使用Property.forName()來表示投影:

List results = session.createCriteria(Cat.class)
    .setProjection( Property.forName("name") )
    .add( Property.forName("color").eq(Color.BLACK) )
    .list();

List results = session.createCriteria(Cat.class)
    .setProjection( Projections.projectionList()
        .add( Projections.rowCount().as("catCountByColor") )
        .add( Property.forName("weight").avg().as("avgWeight") )
        .add( Property.forName("weight").max().as("maxWeight") )
        .add( Property.forName("color").group().as("color" )
    )
    .addOrder( Order.desc("catCountByColor") )
    .addOrder( Order.desc("avgWeight") )
    .list();

16.8. 離線(detached)查詢和子查詢

DetachedCriteria類使你在一個session範圍之外建立一個查詢,並且可以使用任意的 Session來執行它。

DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
    .add( Property.forName("sex").eq('F') );
    
Session session = ....;
Transaction txn = session.beginTransaction();
List results = query.getExecutableCriteria(session).setMaxResults(100).list();
txn.commit();
session.close();

DetachedCriteria也可以用以表示子查詢。條件例項包含子查詢可以通過 Subqueries或者Property獲得。

DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)
 .setProjection( Property.forName("weight").avg() );
session.createCriteria(Cat.class)
 .add( Property.forName("weight).gt(avgWeight) )
 .list();

DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)
 .setProjection( Property.forName("weight") );
session.createCriteria(Cat.class)
 .add( Subqueries.geAll("weight", weights) )
 .list();

甚至相互關聯的子查詢也是有可能的:

DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")
 .setProjection( Property.forName("weight").avg() )
 .add( Property.forName("cat2.sex").eqProperty("cat.sex") );
session.createCriteria(Cat.class, "cat")
 .add( Property.forName("weight).gt(avgWeightForSex) )
 .list();

 

8.2  連 接 查 詢

  在資料庫檢索過程中,表之間的連線查詢是很常見,先來看一下各種連線的定義。

8.2.1  連線定義

  本節將介紹三種連線方式,分別是內連線、右外連線和左外連線。

● 左連線:左連線的結果集包括LEFT OUTER 子句中指定的左表的所有行,而不僅僅是連線列所匹配的行。如果左表的某行在右表中沒有匹配行,則在相關聯的結果集行中右表的所有選擇列表的列均為空值。

● 右連線:右連線是左連線的反向連線。將返回右表的所有行。如果右表的某行在左表中沒有匹配行,則將為左表返回空值。

● 內連線:內連線使用比較運算子根據每個表共有的列的值匹配兩個表中的行,即返回相關聯的列所匹配的行。

  下面用具體例項來說明這三種連線。

  資料庫中有兩個表,person和basiccar,其中person的列carId是關聯basiccar的外來鍵,現在表中的資料如下:

  basiccar表

  +----+------+----------+------------+

  | id | name | factory  | date         |

  +----+------+----------+------------+

  |  1 | car1 | shenzhen | 1992-02-02 |

  |  2 | car2 | nanjing  | 1992-04-02  |

  +----+------+----------+------------+

  person表

  +----+-----------+-------+

  | id | salesname  | carId |

  +----+-----------+-------+

  |  1 | man1        |     1  |

  |  2 | man2        |  NULL |

  |  3 | man3        |     1  |

  +----+-----------+-------+

  

  

  由上面的資料可以看出,basiccar表有2組資料;person表有3組資料。其中存在兩組關聯:id為1的person和id為1的basiccar關聯;id為3的person和id為1的basiccar關聯。下面,分別來看看各種連線下,資料的檢索結果。

  1.內連線

  在資料庫中輸入以下查詢語句:

  select person.id as pid, 

         basiccar.id as bid, 

         person.carid as carid, 

         person.salesname as sName,

         basiccar.name as carName, 

         basiccar.factory factory, 

         basiccar.date as date 

  from person person inner join basiccar basiccar

  on person.carId=basiccar.id;

  資料查詢結果如下:

  +-----+-----+------+-------+--------+----------+------------+

  | pid | bid | carid | sName | carName | factory  | date       |

  +-----+-----+------+-------+---------+----------+-----------+

  |   1 |   1  |     1 | man1  | car1    | shenzhen | 1992-02-02 |

  |   3 |   1  |     1 | man3  | car1    | shenzhen | 1992-02-02 |

  +-----+-----+------+-------+---------+----------+-----------+

  由上面的查詢結果可以看出,內連線檢索出有關聯關係的兩組物件組成的資料,內連線是把關聯關係返回。

  2.左連線

  先看使用person表左連線basiccar表的查詢結果。在資料庫中輸入以下查詢語句:

  select person.id as pid, 

         basiccar.id as bid, 

         person.carid as carid, 

         person.salesname as sName, 

         basiccar.name as carName, 

         basiccar.factory factory, 

         basiccar.date as date 

  from person person left join basiccar basiccar 

  on person.carId=basiccar.id;

  資料查詢結果如下:

  

  +-----+-----+-------+-------+---------+----------+----------+

  | pid | bid  | carid | sName | carName | factory  | date       |

  +-----+------+-------+-------+---------+----------+---------+

  |   1 |    1  |     1  | man1  | car1    | shenzhen  | 1992-02-02 |

  |   2 | NULL |  NULL | man2  | NULL    | NULL       | NULL        |

  |   3 |    1  |     1  | man3  | car1    | shenzhen  | 1992-02-02 |

  +-----+------+-------+-------+---------+----------+---------+

  由上面的查詢結果可以看出,person表的3組資料都被檢索出來了,與其相關聯的basiccar資料,如果有值,則把關聯的basiccar記錄檢索出來;如果為空,則賦值null。

  下面再看一下使用basiccar表左連線person表的查詢結果。在資料庫中輸入以下查詢語句:

  select person.id as pid, 

         basiccar.id as bid, 

         person.carid as carid, 

         person.salesname as sName, 

         basiccar.name as carName, 

         basiccar.factory factory, 

         basiccar.date as date 

  from basiccar basiccar left join person person 

  on person.carId=basiccar.id;

  資料查詢結果如下:

  +------+-----+-------+-------+---------+----------+---------+

  | pid  | bid | carid | sName | carName | factory  | date       |

  +------+-----+-------+-------+---------+----------+---------+

  |    1  |   1 |     1  | man1  | car1    | shenzhen | 1992-02-02 |

  |    3  |   1 |     1  | man3  | car1    | shenzhen | 1992-02-02 |

  | NULL |   2 |  NULL | NULL  | car2    | nanjing   | 1992-04-02 |

  +------+-----+-------+-------+---------+----------+---------+

  由上面的查詢結果可以看出,basiccar表的兩組資料都被檢索出來了,與其相關聯的person資料,如果為空,則賦值null。在上表結果中,由於basiccar.id=1的basiccar記錄關聯兩組person記錄(id=1,id=3),所以會把這兩組組合作為兩個記錄返回;basiccar.id=2的basiccar記錄,雖然沒有關聯的person記錄,則把person記錄記為null,也把其作為一個記錄返回。

  由此可見,左連線是內連線的檢索結果加上左連線左邊表中沒有關聯關係的資料。

  3.右連線

  先看一下使用person表右連線basiccar表的查詢結果。在資料庫中輸入以下查詢語句:

  select person.id as pid, 

         basiccar.id as bid, 

         person.carid as carid, 

         person.salesname as sName, 

         basiccar.name as carName, 

         basiccar.factory factory, 

         basiccar.date as date 

  from person person right join basiccar basiccar 

  on person.carId=basiccar.id;

  資料查詢結果如下:

  +------+-----+-------+-------+---------+---------+----------+

  | pid  | bid | carid | sName | carName | factory  | date       |

  +------+-----+-------+-------+---------+---------+----------+

  |    1 |   1 |     1 | man1  | car1    | shenzhen | 1992-02-02 |

  |    3  |   1 |     1  | man3  | car1    | shenzhen | 1992-02-02 |

  | NULL |   2 |  NULL | NULL  | car2    | nanjing   | 1992-04-02 |

  +------+-----+-------+-------+---------+---------+----------+

  由上面的查詢結果可以看出,person表右連線basiccar表的查詢結果與basiccar表左連線person表的查詢結果一樣。basiccar表的兩組資料都被檢索出來了,與其相關聯的person資料,如果為空,則賦值null。在上表結果中,由於basiccar.id=1的basiccar記錄關聯兩組person記錄(id=1,id=3),所以會把這兩組組合作為兩個記錄返回;basiccar.id=2的basiccar記錄,雖然沒有關聯的person記錄,則把person記錄記為null,也把其作為一個記錄返回。

  再看一下使用basiccar表右連線person表的查詢結果。在資料庫中輸入以下查詢語句:

  select person.id as pid, 

         basiccar.id as bid, 

         person.carid as carid, 

         person.salesname as sName, 

         basiccar.name as carName, 

         basiccar.factory factory, 

         basiccar.date as date 

  from basiccar basiccar right join person person 

  on person.carId=basiccar.id;

  資料查詢結果如下:

  +-----+------+-------+-------+---------+---------+----------+

  | pid | bid  |