Mybatis--day02

非本人總結的筆記,抄點筆記復習復習。感謝傳智博客及黑馬程序猿
成長

關聯(lián)查詢

數(shù)據(jù)中的表結構

數(shù)據(jù)庫的分析方法

第一步:確定單表存儲的是什么內容。
第二步:確定每個表中的關鍵字段。不能為null的字段。
第三步:確定表和表之間數(shù)據(jù)庫層面的關系。外鍵關系。
第四步:從業(yè)務層面分析表和表之間的關系。

訂單--商品模型分析

第一步:

User:客戶表。存儲的是購買商品的用戶信息。

Orders:訂單表。存儲的就是用戶生成的訂單。

OrderDetail:訂單明細表。保存的是每個訂單的明細。

Items:商品表。保存的是商品信息。

第二步:

User:id:主鍵。Username:用戶名

Orders:id主鍵。user_id:用戶id(外鍵)

Orderdetail:id主鍵。orders_id:訂單的id(外鍵)。items_id:商品id(外鍵)

Items:id主鍵。Name商品名稱。Price商品價格。Createtime生成日期。

第三步:

關系

第四步:從業(yè)務層面分析表和表之間的關系

用戶→訂單:一個用戶可以下多個訂單。一對多

訂單→用戶:一個訂單只屬于一個用戶。一對一

訂單→訂單明細:一個訂單包含多個明細。一對多

訂單明細→訂單:一個訂單明細只屬于一個訂單。

訂單明細→商品:一個訂單明細對應一個商品。一對一

商品→訂單明細:一個商品可以被多個明細對應。一對多

用戶→商品:一對多

商品→用戶:一對多

一對一查詢

Sql語句

SELECT o.id, user_id, number, createtime, note, username, birthday, sex, address FROM orderso JOIN USER u ON o.user_id = u.id

使用resultType實現(xiàn)

定義一個POJO

和sql語句的結果集對應

public class OrderUser extends Orders {
    //用戶相關的字段
    private String username;
    private String sex;
    private Date birthday;
    private String address;
    //set和get方法省略
}

Mapper文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itcast.mapper.OrderMapper">
    <select id="getOrderWithUser" resultType="orderuser">
        SELECT
            o.id,
            user_id,
            number,
            createtime,
            note,
            username,
            birthday,
            sex,
            address
        FROM
            orders o
        JOIN USER u ON o.user_id = u.id
    </select>
</mapper>

接口定義

public interface OrderMapper{
    List<OrderUser> getOrderWithUser();
}

測試方法

@Test
public void testGetOrderWithUser() {
    SqlSession sqlSession = sessionFactory.openSession();
    OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
    List<OrderUser> orderUserList = orderMapper.getOrderWithUser();
    System.out.println(orderUserList);
    sqlSession.close();
}

使用ResultMap實現(xiàn)

定義一個POJO

在orders POJO中添加一個User屬性,保存用戶信息

public class Orders {
    private Integer id;
    private Integer userId;
    private String number;
    private Date createtime;
    private User user;
    //省略get和set方法
}

Mapper文件

<!-- 使用resultMap實現(xiàn)一對一映射 -->
<resultMap type="orders" id="orderUserResultMap">
    <!-- order表的主鍵 -->
    <id column="id" property="id"/>
    <!-- 普通列 -->
    <result column="user_id" property="userId"/>
    <result column="number" property="number"/>
    <result column="createtime" property="createtime"/>
    <result column="note" property="note"/>
    <!-- 用戶表的映射關系 -->
    <!-- 使用association做一對一關聯(lián)映射 -->
    <!-- property屬性就是pojo中要進行一對一關聯(lián)的屬性
     javaType:指定一對一關聯(lián)屬性的類型,可以使用別名。
     -->
    <association property="user" javaType="cn.itcast.pojo.User">
      <!-- user表的主鍵 -->
      <id column="user_id" property="id"/>
      <!-- 普通列 -->
      <result column="username" property="username"/>
      <result column="birthday" property="birthday"/>
      <result column="sex" property="sex"/>
      <result column="address" property="address"/>
    </association>
</resultMap>
<select id="getOrderWithUserResultMap" resultMap="orderUserResultMap">
      SELECT
      o.id,
      user_id,
      number,
      createtime,
      note,
      username,
      birthday,
      sex,
      address
      FROM
      orders o
      JOIN USER u ON o.user_id = u.id
</select>

接口定義

public interface OrderMapper{
    List<Orders> getOrderWithUserResultMap();
}

測試方法

@Test
public void testGetOrderWithUserResultMap() throws Exception {
    SqlSession sqlSession = sessionFactory.openSession();
    OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
    List<Orders> list = orderMapper.getOrderWithUserResultMap();
    System.out.println(list);
    sqlSession.close();
}

小結

一對一映射可以有兩種方法,一種是使用resultType,根據(jù)sql語句返回的結果集創(chuàng)建一pojo類來接收結果集。

使用resultMap實現(xiàn),需要配置一個resultmap使用association 來配置映射關系。

實際開發(fā)中resultType用的多。

一對多查詢

訂單到訂單明細是一對多的關系。

Sql語句

SELECT o.id, user_id, number, createtime, note, username, birthday, sex, address, od.iddetail_id, od.items_id, od.items_num FROM orderso JOIN USER u ON o.user_id = u.id JOIN orderdetail od ON o.id = od.orders_id

定義一個POJO

在orders中添加List<OrderDetail>屬性,保存訂單明細列表

public class Orders{
    private Integer id;
    private Integer userId;
    private String number;
    private Date createtime;
    private String note;
    private List<OrderDetail> detailList;
    //省略set和get方法
}

Mapper文件

<!-- 一對多管理映射使用ResultMap實現(xiàn) -->
<!-- resultMap定義 -->
<!-- resultMap之間可以使用extends繼承 -->
<resultMap type="orders" id="orderDetailResultMap" extends="orderUserResultMap">
     <!-- 配置一對多映射關系 -->
     <!-- property一對多關系映射的屬性 -->
     <!-- ofType:指定列表中元素的數(shù)據(jù)類型 -->
     <collection property="detailList" ofType="cn.itcast.pojo.Orderdetail">
        <!-- 訂單明細表的id -->
        <id column="detail_id" property="id"/>
        <!-- 普通列 -->
        <result column="items_id" property="itemsId"/>
        <result column="items_num" property="itemsNum"/>
        <result column="id" property="ordersId"/>
     </collection>
</resultMap>
<select id="getOrderWithDetail" resultMap="orderDetailResultMap">
    SELECT
    o.id,
    user_id,
    number,
    createtime,
    note,
    username,
    birthday,
    sex,
    address,
    od.id detail_id,
    od.items_id,
    od.items_num
    FROM
    orders o
    JOIN USER u ON o.user_id = u.id
    JOIN orderdetail od ON o.id = od.orders_id
</select>

接口定義

public interface OrderMapper{
    List<Orders> getOrderWithDetail();
}

測試方法

@Test
public void testGetOrderWithDetail() throws Exception {
    SqlSession sqlSession = sessionFactory.openSession();
    OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
    List<Orders> list = orderMapper.getOrderWithDetail();       System.out.println(list);
    sqlSession.close();
}

一對多復雜

需求

查詢訂單關聯(lián)訂單明細,商品明細要關聯(lián)商品信息。

Sql語句

SELECT o.id, o.user_id, o.number, o.createtime, o.note, u.username, u.birthday, u.sex, u.address, od.iddetail_id, od.items_id, od.items_num, i.name, i.pic, i.price, i.createtimectime FROM orderso JOIN USER u ON o.user_id = u.id JOIN orderdetail od ON o.id = od.orders_id JOINitems i ON od.items_id = i.id

定義一個POJO

在Orderdetail中添加一個Items屬性,保存商品信息。

public class Orderdetail{
    private Integer id;
    private Integer ordersId;
    private Integer itemsId;
    private Integer itemNum;
    private Items items;
    //省略set和get方法
}

Mapper文件

<!-- 一對多復雜 -->
<!-- 定義一個ResultMap -->
<resultMap type="Orders" id="orderWithDetailWithItemsResultMap" extends="orderUserResultMap">
    <!-- 配置一對多映射關系 -->
    <!-- property一對多關系映射的屬性 -->
    <!-- ofType:指定列表中元素的數(shù)據(jù)類型 -->
    <collection property="detailList" ofType="cn.itcast.pojo.Orderdetail">
        <!-- 訂單明細表的id -->
        <id column="detail_id" property="id"/>
        <!-- 普通列 -->
        <result column="items_id" property="itemsId"/>
        <result column="items_num" property="itemsNum"/>
        <result column="id" property="ordersId"/>
        <!-- 訂單明細一對一關聯(lián)商品信息 -->
        <association property="items" javaType="cn.itcast.pojo.Items">
            <!-- 商品表的主鍵 -->
            <id column="items_id" property="id"/>
            <!-- 普通列 -->
            <result column="name" property="name"/>
            <result column="pic" property="pic"/>
            <result column="price" property="price"/>
            <result column="ctime" property="createtime"/>
        </association>
    </collection>
</resultMap>
<select id="getOrderWithDetailWithItems" resultMap="orderWithDetailWithItemsResultMap">
    SELECT
        o.id,
        o.user_id,
        o.number,
        o.createtime,
        o.note,
        u.username,
        u.birthday,
        u.sex,
        u.address,
        od.id detail_id,
        od.items_id,
        od.items_num,
        i.`name`,
        i.pic,
        i.price,
        i.createtime ctime
    FROM
        orders o
    JOIN USER u ON o.user_id = u.id
    JOIN orderdetail od ON o.id = od.orders_id
    JOIN items i ON od.items_id = i.id
</select>

接口方法定義

public interface OrderMapper{
    List<Orders> getOrderWithDetailWithItems();
}

測試方法

@Test
public void testGetOrderWithDetailWithItems() throws Exception {
    SqlSession sqlSession = sessionFactory.openSession();
    OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
    List<Orders> list = orderMapper.getOrderWithDetailWithItems();
    System.out.println(list);
    sqlSession.close();
}

多對多關聯(lián)映射

如下需求:

查詢用戶購買的商品信息,用戶和商品的關系是多對多關系。

需求1:

查詢顯示字段:用戶賬號、用戶名稱、用戶性別、商品名稱、商品價格(最常見)

企業(yè)開發(fā)中常見明細列表,用戶購買商品明細列表,

使用resultType將上邊查詢列映射到pojo輸出。

需求2:

查詢顯示字段:用戶賬號、用戶名稱、購買商品數(shù)量、商品明細(鼠標移上顯示明細)

使用resultMap將用戶購買的商品明細列表映射到user對象中。

其實是一個一對多的映射關系

延遲加載

需要查詢關聯(lián)信息時,使用mybatis延遲加載特性可有效的減少數(shù)據(jù)庫壓力,首次查詢只查詢主要信息,關聯(lián)信息等用戶獲取時再加載。
在mybatis中默認沒有開啟延遲加載

配置方法

需要配置SqlMapConfig.xml,中有一個setting節(jié)點,需要在setting節(jié)點中配置開啟延遲加載。

<!-- 全局參數(shù)配置 -->
<settings>
    <!-- 配置開啟延遲加載 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 設置按需加載 -->
    <setting name="aggressiveLazyLoading" value="false" />
</settings>

Mapper文件

<!-- 懶加載 -->
<!-- 配置一個resultMap,懶加載user -->
<resultMap type="orders" id="ordersLazyLoading">
    <!-- order表的主鍵 -->
    <id column="id" property="id"/>
    <!-- 普通列 -->
    <result column="user_id" property="userId"/>
    <result column="number" property="number"/>
    <result column="createtime" property="createtime"/>
    <result column="note" property="note"/>
    <!-- 延遲加載用戶信息 -->
    <!-- select指定一個statementID查詢用戶,延遲加載的查詢 -->
    <!-- column指定查詢條件的列 -->
    <association property="user" select="getUserById" column="user_id">
      <!-- user表的主鍵 -->
      <id column="user_id" property="id"/>
      <!-- 普通列 -->
      <result column="username" property="username"/>
      <result column="birthday" property="birthday"/>
      <result column="sex" property="sex"/>
      <result column="address" property="address"/>
    </association>
</resultMap>
<select id="getOrderLazyLoading" resultMap="ordersLazyLoading">
    select * from orders
</select>

<select id="getUserById" parameterType="int" resultType="cn.itcast.pojo.User">
    SELECT * from user where id = #{id}
</select>

接口定義

public interface OrderMapper{
    List<Orders> getOrderLazyLoading();
}

測試方法

@Test
public void testgetOrderLazyLoading() throws Exception {
    SqlSession sqlSession = sessionFactory.openSession();
    OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
    List<Orders> list = orderMapper.getOrderLazyLoading();
    Orders orders = list.get(0);
    System.out.println(orders.getId());
    //懶加載
    System.out.println(orders.getUser().getUsername());
    System.out.println(list);
    sqlSession.close();
}

Mybatis的緩存

一級緩存、二級緩存。

Mybatis緩存介紹

如下圖,是mybatis一級緩存和二級緩存的區(qū)別圖解:

緩存

Mybatis一級緩存的作用域是同一個SqlSession,在同一個sqlSession中兩次執(zhí)行相同的sql語句,第一次執(zhí)行完畢會將數(shù)據(jù)庫中查詢的數(shù)據(jù)寫到緩存(內存),第二次會從緩存中獲取數(shù)據(jù)將不再從數(shù)據(jù)庫查詢,從而提高查詢效率。當一個sqlSession結束后該sqlSession中的一級緩存也就不存在了。Mybatis默認開啟一級緩存。

Mybatis二級緩存是多個SqlSession共享的,其作用域是mapper的同一個namespace,不同的sqlSession兩次執(zhí)行相同namespace下的sql語句且向sql中傳遞參數(shù)也相同即最終執(zhí)行相同的sql語句,第一次執(zhí)行完畢會將數(shù)據(jù)庫中查詢的數(shù)據(jù)寫到緩存(內存),第二次會從緩存中獲取數(shù)據(jù)將不再從數(shù)據(jù)庫查詢,從而提高查詢效率。Mybatis默認沒有開啟二級緩存需要在setting全局參數(shù)中配置開啟二級緩存。

一級緩存

原理

下圖是根據(jù)id查詢用戶的一級緩存圖解:

一級緩存

一級緩存區(qū)域是根據(jù)SqlSession為單位劃分的。
每次查詢會先從緩存區(qū)域找,如果找不到從數(shù)據(jù)庫查詢,查詢到數(shù)據(jù)將數(shù)據(jù)寫入緩存。Mybatis內部存儲緩存使用一個HashMap,key為hashCode+sqlId+Sql語句。value為從查詢出來映射生成的java對象。
sqlSession執(zhí)行insert、update、delete等操作commit提交后會清空緩存區(qū)域。

測試一級緩存

@Test
public void testlevel1cache() throws Exception {
    SqlSession sqlSession = sessionFactory.openSession();
    OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
    //第一次查詢,從數(shù)據(jù)庫中查詢數(shù)據(jù)
    List<OrderUser> list = orderMapper.getOrderWithUser();
    System.out.println(list);
    //更新orders表,會清空一級緩存
    OrderUser orderUser = list.get(0);
    orderUser.setNote("修改數(shù)據(jù)庫清空一級緩存");
    orderMapper.updateOrders(orderUser);
    sqlSession.commit();
    //第二次查詢從一級緩存中命中
    List<OrderUser> list2 = orderMapper.getOrderWithUser();
    System.out.println(list2);
    //關閉sqlsession
    sqlSession.close();
}

二級緩存

原理

下圖是多個sqlSession請求UserMapper的二級緩存圖解。

二級緩存

二級緩存區(qū)域是根據(jù)mapper的namespace劃分的,相同namespace的mapper查詢數(shù)據(jù)放在同一個區(qū)域,如果使用mapper代理方法每個mapper的namespace都不同,此時可以理解為二級緩存區(qū)域是根據(jù)mapper劃分。

每次查詢會先從緩存區(qū)域找,如果找不到從數(shù)據(jù)庫查詢,查詢到數(shù)據(jù)將數(shù)據(jù)寫入緩存。

Mybatis內部存儲緩存使用一個HashMap,key為hashCode+sqlId+Sql語句。value為從查詢出來映射生成的java對象

sqlSession執(zhí)行insert、update、delete等操作commit提交后會清空緩存區(qū)域。

開啟二級緩存

第一步:在核心配置文件SqlMapConfig.xml中加入

<setting name="cacheEnabled"value="true"/>

描述 允許值 默認值
cacheEnabled 對在此配置文件下的所有cache 進行全局性開/關設置。 true | false true

第二步:在需要開啟二級緩存的mapper文件中加入<cache/>節(jié)點。

第三步:在開啟二級緩存的mapper中使用的pojo類需要實現(xiàn)序列化接口。

測試二級緩存

@Test
public void testLevel2Cache() throws Exception {
    //第一次查詢從數(shù)據(jù)庫中查詢
    SqlSession sqlSession = sessionFactory.openSession();
    OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
    List<OrderUser> list = orderMapper.getOrderWithUser();
    System.out.println(list);
    sqlSession.close();

    //更新數(shù)據(jù)庫清空二級緩存
    SqlSession sqlSession1 = sessionFactory.openSession();
    OrderMapper orderMapper1 = sqlSession1.getMapper(OrderMapper.class);
    OrderUser orderUser = list.get(0);
    orderUser.setNote("測試二級緩存");
    orderMapper1.updateOrders(orderUser);
    sqlSession1.commit();
    sqlSession1.close();
        
    //第二次查詢從二級緩存中取數(shù)據(jù)
    SqlSession sqlSession2 = sessionFactory.openSession();
    OrderMapper orderMapper2 = sqlSession2.getMapper(OrderMapper.class);
    List<OrderUser> list2 = orderMapper2.getOrderWithUser();
    System.out.println(list2);
    sqlSession2.close();        
}

設置某方法不使用二級緩存

不使用二級緩存

更新數(shù)據(jù)庫不刷新二級緩存

不刷新二級緩存

Mybatis集成第三方緩存工具ehcache

Ehcache是一個分布式的緩存框架

整合環(huán)境

需要用到ehcache的jar包mybatis+ehcache的整合包。

整合包

整合步驟

第一步:把ehcache的jar包和整合包放到工程中。

第二步:創(chuàng)建一個ehcache的配置文件。配置了ehcache的相關設置。

第三步:需要在mapper文件中指定使用ehcache做緩存。

整合的原理

Mybatis-ehcache整合包中實現(xiàn)了mybatis的Cache接口。只要實現(xiàn)這個接口就可以整合。

原理
Cache接口

創(chuàng)建ehcache的配置文件

classpath下名稱為:ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <!-- 數(shù)據(jù)緩存要存放的磁盤地址 -->
    <diskStore path="d:\temp\ehcache" />
    <defaultCache 
        maxElementsInMemory="1000" 
        maxElementsOnDisk="10000000"
        eternal="false" 
        overflowToDisk="false" 
        timeToIdleSeconds="120"
        timeToLiveSeconds="120" 
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

制定使用ehcache做緩存

配置

應用場景

使用場景:對于訪問響應速度要求高,但是時效性不高的查詢,可以采用二級緩存技術。

注意:在使用二級緩存的時候,要設置一下刷新間隔(cache標簽中有一個flashInterval屬性)來定時刷新二級緩存,這個刷新間隔根據(jù)具體需求來設置,比如設置30分鐘、60分鐘等,單位為毫秒。

局限性

Mybatis的二級緩存對細粒度的數(shù)據(jù),緩存實現(xiàn)不好。

場景:對商品信息進行緩存,由于商品信息查詢訪問量大,但是要求用戶每次查詢都是最新的商品信息,此時如果使用二級緩存,就無法實現(xiàn)當一個商品發(fā)送變化只刷新該商品的緩存信息而不刷新其他商品緩存信息,因為二級緩存是Mapper級別的,當一個商品的信息發(fā)送更新,所有的商品信息緩存數(shù)據(jù)都會被清空。

解決此類問題,需要在業(yè)務層根據(jù)需要對數(shù)據(jù)有針對性的緩存

比如可以對經常變化的數(shù)據(jù)操作單獨放到另一個namespace的Mapper中

Mybatis整合Spring

整合思路

Dao層:

1、數(shù)據(jù)庫連接池配置在spring中。

2、sqlsessionFactory對象放到spring容器中,以單例形式存在。

3、把mapper的代理對象都放到spring容器。如果使用傳統(tǒng)的dao開發(fā)方式,sqlsession應用從spring容器中獲得。

Service層:

1、所有的service實現(xiàn)類對象都放到spring容器中。

2、事務配置也應該放到service層,交給spring管理。

整合需要的環(huán)境

1、Mybatis的jar包
2、Mybatis依賴的jar包
3、Spring的jar包
4、Mybatis和spring的整合包。
5、Mysql的數(shù)據(jù)庫驅動
6、數(shù)據(jù)庫連接池的jar包。

jar包

工程搭建步驟

第一步:創(chuàng)建一個java工程

第二步:導入jar包(上面提到的jar包)

第三步:創(chuàng)建mybatis的核心配置文件SqlmapConfig.xml

第四步:spring的配置文件

? 1、數(shù)據(jù)庫連接池

? 2、SqlsessionFactory配置,應該是整合包中的。

第五步:開發(fā)dao

? 1、傳統(tǒng)dao開發(fā)(接口+實現(xiàn)類)

? 2、Mapper代理的形式

第六步:

? 1、如果是傳統(tǒng)dao需要把實現(xiàn)類配置到spring容器中

? 2、Mapper代理形式,也需要把代理對象配置spring容器中。

第七步:測試。

Sql mapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!-- 別名配置 -->
    <typeAliases>
        <package name="cn.itcast.pojo"/>
    </typeAliases>

    <!-- 加載Mapper映射文件 -->
    <mappers>
        <package name="cn.itcast.mapper"/>
    </mappers>
    
</configuration>

applicationContext. xml(Spring的配置文件)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"                   xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
    <!-- 加載配置文件 -->
    <context:property-placeholder location="classpath:db.properties"/>  
    <!-- 數(shù)據(jù)庫連接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
       <property name="driverClassName" value="${JDBC_DRIVER}"/>
        <property name="url" value="${JDBC_URL}"/>
        <property name="username" value="${JDBC_USER}"/>
        <property name="password" value="${JDBC_PASSWORD}"/>
        <property name="maxActive" value="10"/>
        <property name="maxIdle" value="5"/>
    </bean>
    <!-- sqlsessionFactory配置 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 加載mybatis的配置文件 -->
        <property name="configLocation" value="classpath:SqlMapConfig.xml"/>
        <!-- 數(shù)據(jù)庫連接池 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
</beans>

傳統(tǒng)dao的開發(fā)方式

接口+實現(xiàn)類

Mapper文件

創(chuàng)建mapper文件。在SqlmapConfig.xml中加載。

Mapper文件

接口

public interface OrderDao {
    List<OrderUser> getOrderWithUser();
    List<Orders> getOrderWithUserResultMap();
}

實現(xiàn)類

如果想從spring容器中獲得sqlsession需要繼承SqlSessionDaoSupport類。

SqlSessionDaoSupport類
public class OrderDaoImpl extends SqlSessionDaoSupport implements OrderDao {

    @Override
    public List<OrderUser> getOrderWithUser() {
        //從spring容器中獲得sqlsession對象
        SqlSession sqlSession = this.getSqlSession();
        List<OrderUser> list = sqlSession.selectList("test.getOrderWithUser");
        //不能調用close方法,交給spring完成
        //sqlSession.close();
        return list;
    }

    @Override
    public List<Orders> getOrderWithUserResultMap() {
        SqlSession sqlSession = this.getSqlSession();
        List<Orders> list = sqlSession.selectList("test.getOrderWithUserResultMap");
        return list;
    }

}

把實現(xiàn)類配置到spring容器中

spring容器

測試方法

public class OrderDaoTest {

    private ApplicationContext applicationContext;
    
    @Before
    public void setUp() throws Exception {
        //初始化spring容器
        applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    @Test
    public void testGetOrderWithUser() {
        OrderDao orderDao = (OrderDao) applicationContext.getBean("orderDao");
        List<OrderUser> orderWithUser = orderDao.getOrderWithUser();
        System.out.println(orderWithUser);
    }

    @Test
    public void testGetOrderWithUserResultMap() {
        OrderDao orderDao = (OrderDao) applicationContext.getBean("orderDao");
        List<Orders> list = orderDao.getOrderWithUserResultMap();
        System.out.println(list);
    }

}

Mapper代理形式的dao

Mapper文件+接口的開發(fā)

Mappwer文件+接口

Mapper代理對象配置到spring容器中

使用Mapper的代理類

Mapper代理類
<!-- mapper的代理對象 -->
<bean id="orderMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <!-- mapperInterface這個屬性就是指定要為哪個接口做代理 -->
    <property name="mapperInterface" value="cn.itcast.mapper.OrderMapper"/>
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>

使用包掃描器創(chuàng)建代理對象

包掃描器
<!-- 配置包掃描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!-- 指定要掃描的包,如果有多個包,使用半角逗號分隔 -->
    <!-- 掃描后bean的id就是類名,首字母小寫 -->
    <property name="basePackage" value="cn.itcast.mapper"/>
    <!-- 不需要指定sqlsessionFactory,掃描器會自動找 -->
</bean>

掃描器是應用廣泛的。

sqlmapConfig.xml:

sqlmapConfig.xml
結果

逆向工程

什么是逆向工程

根據(jù)數(shù)據(jù)庫中的表生成java代碼。

1、pojo類。根據(jù)數(shù)據(jù)庫中表的字段生成。

2、Mapper接口。

3、Mapper映射文件。都是基于單表的操作。

官方提供工具

官方工具
逆向工程

需要配置的信息

在generatorConfig.xml中配置

1、數(shù)據(jù)庫連接

數(shù)據(jù)庫連接

2、指定POJO生成的包名及生成的位置

指定包名及位置

3、指定Mapper文件、映射文件生成的包及位置

包及位置
接口位置

4、指定需要逆向的表

指定表

指定逆向工程

執(zhí)行GeneratorSqlmap.java中的main方法。

工程

注意:如果發(fā)現(xiàn)生成的代碼有問題需要刪除后重新生成,否則會在原文件中追加內容。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容