Mybatis--day02

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

關聯查詢

數據中的表結構

數據庫的分析方法

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

訂單--商品模型分析

第一步:

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生成日期。

第三步:

關系

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

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

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

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

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

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

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

用戶→商品:一對多

商品→用戶:一對多

一對一查詢

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實現

定義一個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實現

定義一個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實現一對一映射 -->
<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做一對一關聯映射 -->
    <!-- property屬性就是pojo中要進行一對一關聯的屬性
     javaType:指定一對一關聯屬性的類型,可以使用別名。
     -->
    <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,根據sql語句返回的結果集創建一pojo類來接收結果集。

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

實際開發中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實現 -->
<!-- resultMap定義 -->
<!-- resultMap之間可以使用extends繼承 -->
<resultMap type="orders" id="orderDetailResultMap" extends="orderUserResultMap">
     <!-- 配置一對多映射關系 -->
     <!-- property一對多關系映射的屬性 -->
     <!-- ofType:指定列表中元素的數據類型 -->
     <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();
}

一對多復雜

需求

查詢訂單關聯訂單明細,商品明細要關聯商品信息。

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:指定列表中元素的數據類型 -->
    <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"/>
        <!-- 訂單明細一對一關聯商品信息 -->
        <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();
}

多對多關聯映射

如下需求:

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

需求1:

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

企業開發中常見明細列表,用戶購買商品明細列表,

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

需求2:

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

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

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

延遲加載

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

配置方法

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

<!-- 全局參數配置 -->
<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一級緩存和二級緩存的區別圖解:

緩存

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

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

一級緩存

原理

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

一級緩存

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

測試一級緩存

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

二級緩存

原理

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

二級緩存

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

每次查詢會先從緩存區域找,如果找不到從數據庫查詢,查詢到數據將數據寫入緩存。

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

sqlSession執行insert、update、delete等操作commit提交后會清空緩存區域。

開啟二級緩存

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

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

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

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

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

測試二級緩存

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

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

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

不使用二級緩存

更新數據庫不刷新二級緩存

不刷新二級緩存

Mybatis集成第三方緩存工具ehcache

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

整合環境

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

整合包

整合步驟

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

第二步:創建一個ehcache的配置文件。配置了ehcache的相關設置。

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

整合的原理

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

原理
Cache接口

創建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">
    <!-- 數據緩存要存放的磁盤地址 -->
    <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屬性)來定時刷新二級緩存,這個刷新間隔根據具體需求來設置,比如設置30分鐘、60分鐘等,單位為毫秒。

局限性

Mybatis的二級緩存對細粒度的數據,緩存實現不好。

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

解決此類問題,需要在業務層根據需要對數據有針對性的緩存

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

Mybatis整合Spring

整合思路

Dao層:

1、數據庫連接池配置在spring中。

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

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

Service層:

1、所有的service實現類對象都放到spring容器中。

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

整合需要的環境

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

jar包

工程搭建步驟

第一步:創建一個java工程

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

第三步:創建mybatis的核心配置文件SqlmapConfig.xml

第四步:spring的配置文件

? 1、數據庫連接池

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

第五步:開發dao

? 1、傳統dao開發(接口+實現類)

? 2、Mapper代理的形式

第六步:

? 1、如果是傳統dao需要把實現類配置到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"/>  
    <!-- 數據庫連接池 -->
    <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"/>
        <!-- 數據庫連接池 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
</beans>

傳統dao的開發方式

接口+實現類

Mapper文件

創建mapper文件。在SqlmapConfig.xml中加載。

Mapper文件

接口

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

實現類

如果想從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;
    }

}

把實現類配置到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文件+接口的開發

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>

使用包掃描器創建代理對象

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

掃描器是應用廣泛的。

sqlmapConfig.xml:

sqlmapConfig.xml
結果

逆向工程

什么是逆向工程

根據數據庫中的表生成java代碼。

1、pojo類。根據數據庫中表的字段生成。

2、Mapper接口。

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

官方提供工具

官方工具
逆向工程

需要配置的信息

在generatorConfig.xml中配置

1、數據庫連接

數據庫連接

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

指定包名及位置

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

包及位置
接口位置

4、指定需要逆向的表

指定表

指定逆向工程

執行GeneratorSqlmap.java中的main方法。

工程

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容