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阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容