zoukankan      html  css  js  c++  java
  • Java框架之MyBatis框架(二)

      Mybatis框架是相对于优化dao层的框架,其有效的减少了频繁的连接数据库(在配置文件xml中进行配置),将sql语句与java代码进行分离(写在XXXXmapper.xml文件中,一个表对应一个xml文件),有效的处理了各种条件(定义了输入类型pojo)并且将结果又映射到java对象中(定义了输出类型)。需要注意的是每个表对应的xml文件的地址需要在配置文件中进行配置(可以指引整个文件夹),当使用动态代理的接口mapper时,需要注意好其的四个规范!并且其可以将查询及输出结果封装到一个类,并提供了if、where、foreach标签进行优化。

    一、输入类型优化:

    开发中通过可以使用pojo传递查询条件。

    查询条件可能是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如查询用户信息的时候,将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。

    包装对象:Pojo类中的一个属性是另外一个pojo。

    需求:根据用户名模糊查询用户信息,查询条件放到QueryVo的user属性中。

    package com.oracle.pojo;
    
    public class QueryVo {
        private User user;
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        @Override
        public String toString() {
            return "QueryVo [user=" + user + "]";
        }
        
    }

    二、输出类型优化:

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

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

            resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

    三、动态Sql:

    通过mybatis提供的各种标签方法实现动态拼接sql:if/where/foreach

    <!--根据姓名和性别查询用户  使用where标签代替以前的 1=1 再加上if这样就可以即使没有一个条件一样可以执行sql语句或者有其中一个!-->
        <select id="getUserBySexAndUserName" parameterType="user" resultType="user">
                <!-- include标签加载sql片段,后面是其片段的id -->
            <include refid="get"></include>
            <!-- where标签:一是添加关键字where,二是处理第一个and关键字 -->
        <where>
        <if test="username!=null and username!=''">
                 and username like "%"#{username}"%" 
        </if>
        <if test="sex!=null and sex!=''">
                 and sex =#{sex} 
        </if>
        </where>
        </select>
        <!--SQL片段  -Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。一般用于表连接时查询多个字段的时候-->
        <sql id="get">
            select * from user 
        </sql>
        <!-- 根据多个条件查询 -->
        <select id="getUserByQuery" parameterType="Query" resultType="user">
        select * from user where id in
            <!-- foreach标签,进行遍历 -->
            <!-- collection:遍历的集合,这里是Query的ids属性 -->
            <!-- item:遍历的项目,可以随便写,但是和后面的#{}里面要一致 -->
            <!-- open:在前面添加的sql片段 -->
            <!-- close:在结尾处添加的sql片段 -->
            <!-- separator:指定遍历的元素之间使用的分隔符 -->
        <foreach collection="ids" item="i" open="(" close=")" separator=",">
            #{i}
        </foreach>
        </select>
        

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

        如果要使用别的Mapper.xml配置的sql片段,可以在refid前面加上对应的Mapper.xml的namespace。

    foreach标签:向sql传递数组或List,mybatis使用foreach解析。

    四、关联查询:

    1、一对一查询:

    <!--查询所有的订单信息以及其关联的用户信息  -->
            <!-- 因为两个表是一对一!为使用resultMap,所以在orders下添加私有的User类对应的user属性,因为无法将数据映射到user里面
            所以开始下面的手动映射 -->
        <resultMap type="orders" id="orderUserResultMap">
        <id property="id" column="id" />
        <result property="userId" column="user_id" />
        <result property="number" column="number" />
        <result property="createtime" column="createtime" />
        <result property="note" column="note" />
    
        <!-- association :配置一对一属性 -->
        <!-- property:order里面的User属性名 -->
        <!-- javaType:属性类型 -->
        <association property="user" javaType="user">
            <!-- id:声明主键,表示user_id是关联查询对象的唯一标识-->
            <id property="id" column="user_id" />
            <result property="username" column="username" />
            <result property="address" column="address" />
        </association>
    
    </resultMap>
    
    <!-- 一对一关联,查询订单,订单内部包含用户属性 -->
    <select id="getOrdersUser" resultMap="orderUserResultMap">
        SELECT
        o.id,
        o.user_id userId,
        o.number,
        o.createtime,
        o.note,
        u.username,
        u.address
        FROM
        `orders` o
        LEFT JOIN `user` u ON o.user_id = u.id
    </select>

    2、一对多查询:

    <!-- 查询所有的用户信息以及对应的订单信息 -->
        <resultMap type="user" id="getAllUser">
            <id property="id" column="id"/>
            <result property="username" column="username"/>
            <result property="birthday" column="birthday"/>
            <result property="sex" column="sex"/>
            <result property="address" column="address"/>
            <!--一对多的关系    property是指集合的属性名字  javaType是指类型   ofType是泛型的意思-->
            <collection property="list" javaType="list" ofType="orders">
                <!-- 配置主键,是关联Order的唯一标识 -->
                <id property="id" column="oid"/>
                <result property="number" column="number"/>
                <result property="createtime" column="createtime"/>
                <result property="note" column="note"/>
            </collection>
        </resultMap>
        <select id="getUserOrders" resultMap="getAllUser">
        SELECT
            u.id,
            u.username,
            u.birthday,
            u.sex,
            u.address,
            o.id oid,
            o.number,
            o.createtime,
            o.note
        FROM
            `user` u
        LEFT JOIN `orders` o ON u.id = o.user_id
            
        
        </select>
    public class User {
        private Integer id;
        private String username;
        private String birthday;
        private String sex;
        private String address;
        private List<Orders> list;//一对多,得list

    五、逆向工程:

    1、导入:

    2、修改:

    generatorConfig.xml中配置Mapper生成的详细信息:

      注意:

    1. 修改要生成的数据库表
    2. pojo文件所在包路径
    3. Mapper所在的包路径
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
      
      <generatorConfiguration>
          <context id="testTables" targetRuntime="MyBatis3">
              <commentGenerator>
                  <!-- 是否去除自动生成的注释 true:是 : false:否 -->
                  <property name="suppressAllComments" value="true" />
              </commentGenerator>
              <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
              <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                  connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root" password="root">
              </jdbcConnection>
              <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" 
                  userId="yycg" password="yycg"> </jdbcConnection> -->
      
              <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 
                  和 NUMERIC 类型解析为java.math.BigDecimal -->
              <javaTypeResolver>
                  <property name="forceBigDecimals" value="false" />
              </javaTypeResolver>
      
              <!-- targetProject:生成PO类的位置 -->
              <javaModelGenerator targetPackage="cn.oracle.ssm.po"
                  targetProject=".src">
                  <!-- enableSubPackages:是否让schema作为包的后缀 -->
                  <property name="enableSubPackages" value="false" />
                  <!-- 从数据库返回的值被清理前后的空格 -->
                  <property name="trimStrings" value="true" />
              </javaModelGenerator>
              <!-- targetProject:mapper映射文件生成的位置 -->
              <sqlMapGenerator targetPackage="cn.oracle.ssm.mapper"
                  targetProject=".src">
                  <!-- enableSubPackages:是否让schema作为包的后缀 -->
                  <property name="enableSubPackages" value="false" />
              </sqlMapGenerator>
              <!-- targetPackage:mapper接口生成的位置 -->
              <javaClientGenerator type="XMLMAPPER"
                  targetPackage="cn.oracle.ssm.mapper" targetProject=".src">
                  <!-- enableSubPackages:是否让schema作为包的后缀 -->
                  <property name="enableSubPackages" value="false" />
              </javaClientGenerator>
              <!-- 指定数据库表 -->
              <table schema="" tableName="user"></table>
              <table schema="" tableName="order"></table>
          </context>
      </generatorConfiguration>

    3、生成逆向代码:

    运行GeneratorSqlmap.java!

    生成pojo、mapper!

    注意:

    1. 逆向工程生成的代码只能做单表查询

    2. 不能在生成的代码上进行扩展,因为如果数据库变更,需要重新使用逆向工程生成代码,原来编写的代码就被覆盖了。

    3. 一张表会生成4个文件

  • 相关阅读:
    [单选题]请求文件“time.inc”,当发生错误时就终止脚本,正确的方式是:
    [单选题]条件语句的时候不应该使用哪一种控制结构
    [高德地图]学习笔记--基本结构
    nodejs实战:小爬虫
    linux实用命令(2016/11/8-永远)
    自适应响应式布局-实现原理
    解决npm安装慢的方法
    git进阶(分支与标签管理)
    git进阶(远程仓库github)
    git入门命令(只涉及本地仓库管理)
  • 原文地址:https://www.cnblogs.com/21-forever/p/11306794.html
Copyright © 2011-2022 走看看