mybatis

作者: 蕊er | 来源:发表于2017-11-24 10:31 被阅读0次

    每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它是线程不安全的

    配置文件

    (已下载IDEA Mybatis插件 ---- MyBatis plugin)

    • SqlMapConfig.xml

      mybatis的全局配置文件,配置了mybatis的运行环境等信息

      • 配置的内容顺序如下:

        • properties(属性) ---- 用resource属性加载外部配置文件

        • typeAliases(类型别名)---- 给类起别名

        • environments(环境集合属性对象)

          • environment(环境子属性对象)
          • transactionManager(事务管理)
          • dataSource(数据源)
        • mappers(映射器)

          • <mapper resource=" " /> ---- 使用相对于xml路径的资源

          • <mapper class=" " /> ---- 使用mapper接口类路径

            此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中

          • <package name=" "/> ---- 注册指定包下的所有mapper接口

            此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中

            idea maven 需要额外配置

            <build>
              <resources>
                <resource>
                  <directory>src/main/java</directory>
                  <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                  </includes>
                  <filtering>true</filtering>
                </resource>
                <resource>
                  <directory>src/main/resources</directory>
                  <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                  </includes>
                </resource>
              </resources>
            </build>
            
      <?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>
          <!--引入外部配置文件-->
          <properties resource="jdbc.properties"/>
      
        <typeAliases>
            <!-- 单个别名定义 -->
            <typeAlias alias="user" type="cn.itcast.mybatis.pojo.User" />
            <!-- 批量别名定义,扫描整个包下的类,别名为类名(大小写不敏感) -->
            <package name="cn.haha.mybatis.entity" />
            <package name="其它包" />
        </typeAliases>
      
          <!-- 和spring整合后 environments配置将废除    -->
          <environments default="development">
              <environment id="development">
                  <!-- 使用jdbc事务管理 -->
                  <transactionManager type="JDBC"/>
                  <!-- 数据库连接池 -->
                  <dataSource type="POOLED">
                      <property name="driver" value="${jdbc.driver}"/>
                      <property name="url" value="${jdbc.url}"/>
                      <property name="username" value="${jdbc.username}"/>
                      <property name="password" value="${jdbc.password}"/>
                  </dataSource>
              </environment>
          </environments>
          <!-- 加载映射文件 -->
          <mappers>
              <mapper resource="mapper/User.xml"></mapper>
          </mappers>
      
      </configuration>
      
    • mapper.xml

      sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载,

      #{} ---- 占位符

      ${} ---- 字符串拼接,${}里面传递简单类型时必须写value即${value},传递pojo对象或pojo包装对象则需要写对象对应属性

      <!DOCTYPE mapper
              PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      <!-- 命名空间 -->
      <mapper namespace="user">
        <!-- 配置sql语句 sql id:通过namespace.id查找到当前sql语句;parameterType:传入参数类            型;resultType:返回结果类型 -->
          <select id="findUserById" parameterType="Integer"                                         resultType="com.lirui.mybatis.dao.User">
              SELECT * FROM user WHERE id=#{IDENTITY }
          </select>
          <insert id="insertUser" parameterType="com.lirui.mybatis.dao.User">
              <!-- selectKey 标签实现主键返回 -->
              <!-- keyColumn:主键对应的表中的哪一列 -->
              <!-- keyProperty:主键对应的pojo中的哪一个属性 -->
              <!-- order:设置在执行insert语句前执行查询id的sql,孩纸在执行insert语句之后执行查询id的                sql -->
              <!-- resultType:设置返回的id的类型 -->
              <selectKey keyColumn="id" keyProperty="id" order="AFTER" resultType="Integer">
                  SELECT LAST_INSERT_ID()
              </selectKey>
              INSERT INTO user (username,birthday,sex,address) VALUES (#{username},#{birthday},#            {sex},#{address})
          </insert>
      </mapper>
      
    • 测试

      String resource = "mybatis-config.xml";
      InputStream inputStream = Resources.getResourceAsStream(resource);
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      SqlSession sqlSession = sqlSessionFactory.openSession();
        ......
      sqlSession.commit();
      sqlSession.close();
      

    Mapper动态代理方式

    只需要编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象

    • Mapper接口开发需要遵循以下规范:
      1. Mapper.xml文件中的namespace与mapper接口的类路径相同。
      2. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
      3. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
      4. Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
    public interface UserMapper {
        User findUserById(Integer id);
    }
    
    <mapper namespace="com.lirui.mybatis.mapper.UserMapper">
        <select id="findUserById" parameterType="Integer" resultType="com.lirui.mybatis.bean.User">
            SELECT * FROM user WHERE id=#{id}
        </select>
    </mapper>
    
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = userMapper.findUserById(1);
    System.out.println(user);
    

    输入映射及输出映射

    • parameterType

      • 传递简单类型

        #{...} ${value}

      • 传递pojo对象

        #{pojo对象属性} ${pojo对象属性}

      • 传递pojo包装对象

        #{pojo对象属性} ${pojo对象属性}

      • 传递多参数

        • 接口@Param("record") Orders record
        • xml文件 parameterType="map" #{record.xxx}
    • resultType

      指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功

      • 输出简单类型
      • 输出pojo对象
      • 输出pojo列表
    • resultMap

      如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。resultMap可以实现将查询结果映射为复杂类型的pojo

      <mapper namespace="com.xxx.mapper.OrderMapper">
          <resultMap id="orderMap" type="Order">
              <result property="userId" column="user_id"/>
          </resultMap>
          <select id="listOfOrder" resultMap="orderMap">
            SELECT id, user_id, number, createtime, note FROM orders
          </select>
      </mapper>
      

    动态Sql

    通过mybatis提供的各种标签方法实现动态拼接sql

    • if标签<if> xxx </if>

      <select id="queryUserByWhere" parameterType="User" resultType="User">
          SELECT * FROM user WHERE 1=1
          <if test="sex!=null and sex!=''">
              AND sex=#{sex}
          </if>
          <if test="username!=null and username!=''">
              AND username LIKE "%"#{username}"%"
          </if>
      </select>
      
    • where标签<where> xxx </where>

      可以自动添加where,同时处理sql语句中第一个and关键字

      <select id="queryUserByWhere" parameterType="User" resultType="User">
          SELECT * FROM user
          <!-- where标签可以自动添加where关键字,同时处理sql语句中第一个前and关键字 -->
          <where>
              <if test="sex!=null and sex!=''">
                  AND sex=#{sex}
              </if>
              <if test="username!=null and username!=''">
                  AND username LIKE "%"#{username}"%"
              </if>
          </where>
      </select>
      
    • SQL片段标签 <sql> xxx </sql> <include> xxx </include>

      Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。

      如果要使用别的Mapper.xml配置的sql片段,可以在include标签属性refid值添加对应的Mapper.xml的namespace

      <select id="queryUserByWhere" parameterType="User" resultType="User">
          <!-- 使用include标签加载sql片段;refid是sql片段id -->
          SELECT <include refid="userContent"/> FROM user
          <!-- where标签可以自动添加where关键字,同时处理sql语句中第一个and关键字 -->
          <where>
              <if test="sex!=null and sex!=''">
                  AND sex=#{sex}
              </if>
              <if test="username!=null and username!=''">
                  AND username LIKE "%"#{username}"%"
              </if>
          </where>
      </select>
      <sql id="userContent">
          id, username, birthday, sex, address
      </sql>
      
    • foreach标签<foreach> xxx </foreach>

      向sql传递数组或List,mybatis使用foreach解析

      <sql id="userContent">
          id, username, birthday, sex, address
      </sql>
      <select id="queryUserByIds" parameterType="QueryVo" resultType="User">
      SELECT <include refid="userContent"/> FROM user
        <where>
            <!-- foreach标签,进行遍历 -->
            <!-- collection:遍历的集合,这里是QueryVo的ids属性 -->
      
                <!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->
                <!-- open:在前面添加的sql片段 -->
                <!-- close:在结尾处添加的sql片段 -->
                <!-- separator:指定遍历的元素之间使用的分隔符 -->
                 <foreach collection="ids" item="id" open="id in (" close=")" separator=",">
                ${id}
            </foreach>
        </where>
      </select>
      

    关联查询

    • 一对一查询

    • ResultType

      定义专门的pojo类作为输出类型,pojo类中定义了sql查询结果集所有的字段

      • ResultMap

        根据表的关系,改造pojo对象,使用resultMap描述对象之间的关系

        • 定义对象

          class Many{

            class One;
           }
          
        • xml配置

          <resultMap id="ManyMapper" type="Many">
          <!-- 进行关联查询是,对象参数与列的对应不能省略,否则返回为null -->
          <id column="xxx" property="xxx"/>
          <result property="xxx" column="xxx"/>
          <association property="xxx" javaType="One">
              <id property="id" column="userId"/>
              <result property="username" column="username"/>
          </association>
          

          </resultMap>

          <select id="xxx" resultMap="orderMap">
          select xxx from Many m left join One o on m.id=o.id;
          </select>

    • 一对多查询

      • 定义对象

        class One{
          List<Many> list;
        }
        
      • xml配置

        <resultMap id="OneMapper" type="One">
            <id property="xxx" column="xxx"/>
            <result property="xxx" column="xxx"/>
        
            <collection property="xxx" ofType="Many">
                <id column="xxx" property="xxx"/>
                <result property="xxx" column="xxx"/>
            </collection>
        </resultMap>
        
        <select id="xxx" resultMap="OneMapper">
            SELECT
            xxx
            FROM
            `One` o
            LEFT JOIN `Many` m ON o.id = m.id
        </select>
        

    Sping与mybatis整合

    Spring与mybatis整合,负责数据库池及SessionFactory的创建,不管已下哪种方式都要配置数据库池及SessionFactory

    <!--加载配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--连接池-->
    <!--数据源-->
    <bean name="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="maxTotal" value="10"/>
        <property name="maxIdle" value="5"/>
    </bean>
    <!--工厂方法-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    //mybatis-config.xml
    <!--bean起别名-->
    <typeAliases>
        <package name="com.lirui.mybatis.bean"/>
    </typeAliases>
    <!--mapper代理时使用,mapper接口映射mapper.xml文件,在同个文件夹下才能实现-->
    <mappers>
        <package name="com.lirui.mybatis.mapper"/>
    </mappers>
    
    • 传统dao开发方式

      原始的DAO开发接口+实现类来完成。需要dao实现类需要继承SqlsessionDaoSupport类

      • spring生成实现类

        <bean id="userDao" class="com.mybatis.dao.UserDaoImpl">

            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>
        
      • 实现类中调用执行

        SqlSession sqlSession = super.getSqlSession();
        User user = sqlSession.selectOne("queryUserById", id);
        
    • 手动配置mapper代理

      • 创建mapper代理接口

      • 实现接口与xml文件之前的关系映射

      • spring生成实现类

        <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
            <!-- 配置Mapper接口 -->
            <property name="mapperInterface" value="cn.mybatis.mapper.UserMapper" />
            <!-- 配置sqlSessionFactory -->
            <property name="sqlSessionFactory" ref="sqlSessionFactory" />
        </bean>
        
      • Service中调用执行

        ApplicationContext context=ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        UserMapper userMapper = this.context.getBean("userMapper");
        User user = userMapper.queryUserById(1);
        
    • 扫描方式配置mapper代理

      • 创建mapper代理接口

      • 实现接口与xml文件之前的关系映射

      • spring生成实现类

        <!--Session绑定到接口-->
        <!-- Mapper代理的方式开发方式二,扫描包方式配置代理 -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <!-- 配置Mapper接口 -->
            <property name="basePackage" value="com.lirui.mybatis.mapper"/>
        </bean>
        
      • Service中调用执行

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        UserMapper userMapper=applicationContext.getBean(UserMapper.class);
        System.out.printf(String.valueOf(userMapper.findUserById(10)));
        

    Mybatis逆向工程

    相关文章

      网友评论

          本文标题:mybatis

          本文链接:https://www.haomeiwen.com/subject/ehyxbxtx.html