关于Mybatis动态sql、逆向工程

1.动态sql语句
2.逆向工程(generator)
3.分页助手(pagehelper)
 
一、动态sql语句(查询条件拼接)
1.JDBC中的实现
public List<Role> findByActSql(String name,String sex,String hobby){
    String sql="select * from student";
    if(name!=null) {
        sql+="where name='+name+'";
    }
    if(sex!=null) {
        if(name!=null) {
            sql+="and sex='+sex+'";
        }else {
            sql+="where sex+='+sex+'";
        }
    }
    ......
}

2.MyBatis中的实现

要求:查询相应uname,description查询,若name和description为null,则查询所有
<select id="selectByActSql" resultType="com.zhiyou100.yj.bean.Role">
    select * from role
    <if test="uname!=null">
        where uname=#{uname}
    </if>
    <if test="description!=null">
        and description=#{description}
    </if>
</select>

缺陷:第二个条件满足,第一个条件不满足,sql语句出错

方法一:
<select id="selectByActSql" resultType="com.zhiyou100.yj.bean.Role">
    select * from role where 1=1
    <if test="uname!=null">
        and uname=#{uname}
    </if>
    <if test="description!=null">
        and description=#{description}
    </if>
</select>

方法二:
<!--if+where-->
<select id="selectByActSql_1" resultType="com.zhiyou100.yj.bean.Role">
    select * from role
    <where>    <!--包含的标签中有返回值,在第一个返回值前插入'where',剔除掉返回值前的and/or,其他返回值前的and/or保留-->
        <if test="uname!=null">
            and uname=#{uname}
        </if>
        <if test="description!=null and description!="">    <!--and or-->
            and description=#{description}
        </if>
    </where>
</select>


<!--利用trim改进if+where-->
<!--
    prefix:符合条件的第一个返回值前添加前缀set/where
    prefixOverrides:剔除掉返回值前缀
    suffix:最后的返回值后添加后缀
    suffixOverrides:剔除掉返回值后缀

-->
<select id="selectByActSql_2" resultType="com.zhiyou100.yj.bean.Role">
    select * from role
    <trim prefix="where" prefixOverrides="and  or">
        <if test="uname!=null">
            and uname=#{uname}
        </if>
        <if test="description!=null">
            and description=#{description}
        </if>
    </trim>
</select>

<!--if+set-->
<update id="updateByActSql_1" >
    update role
    <set>    <!--包含的标签中有返回值,在第一个返回值前插入'set',剔除掉最后返回值的','-->
        <if test="uname!=null">
            uname=#{uname},
        </if>
        <if test="description!=null">
            description=#{description}
        </if>
            where id=#{id}
    </set>
</update>

<!--利用trim改进if+set-->
<update id="updateByWhere2" >
    update role
    <trim prefix="set" suffixOverrides=",">
        <if test="uname!=null">
            uname=#{uname},
        </if>
        <if test="description!=null">
            description=#{description}
        </if>
            where id=#{id}
    </trim>
</update>


<!--sql片段:查询时要避免使用*,用完整的字段名,减少代码重复可以利用sql片段-->
1.定义sql片段
<sql id="rolePart">
    id,uname,description
</sql>
2.引入sql片段==>利用<include/>标签(可以是单标签)
<select id="selectAll" resultType="com.zhiyou100.yj.bean.Role">
    select <include refid="rolePart"></include> from role
</select>


<!--choose+when+otherwise:类似java中的switch/ifelse-->
<select id="selectByLike" resultType="com.zhiyou100.yj.bean.Role">
    select * from role
    <trim prefix="where">
        <choose>
            <when test="uname!=null">    <!--模糊查询concat字符串拼接-->
                uname like concat('%',#{uname},'%')    
            </when>
            <otherwise>
                description like concat('%',#{description},'%')
            </otherwise>
        </choose>
    </trim>
</select>


<!--foreach标签遍历(数组,集合...)-->
1.遍历集合,每次调用方法,导致与数据库多次交互
    public void deleteById(int id);
2.foreach标签遍历
    public void deletebyIds(@param("ids")List<Integer> ids);    //集合中的元素是对象==>Integer

    <select id="selectByCondition2"   resultType="com.zhiyou100.yj.bean.Role">
        select <include refid="AllPart"/> from role
        <if test="ids.size>0">
            <where>
                <!--
                collection:集合名称
                open:以什么开始
                close:以什么结束
                separator:每个元素用什么间隔
                item:每次遍历的值赋予的变量名
                -->
                <foreach collection="ids" open="id in ("  close=")" separator="," item="ids">
                    #{ids}
                </foreach>
            </where>
        </if>
    </select>
二、MyBatis逆向工程
 
1.导入mybatis-generator的jar包
2.创建generator.xml配置文件(由表自动生成dao,bean,mappper.xml文件)    注意:对应xml文件需手动添加到config.xml
<?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>
<!-- mysql驱动jar所在位置:绝对路径 -->
    <classPathEntry location="C:\Users\BirdXtd\Desktop\API\jar包\mysql-connector-java-5.1.47.jar"/>
<!-- 数据源信息 -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
<!-- 为了防止生成的代码中有很多注释,比较难看,加入下面的配置控制 -->
    <commentGenerator >
        <property name="suppressDate" value="true"/>
        <property name="suppressAllComments" value="true"/>
    </commentGenerator>
  
    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
        connectionURL="jdbc:mysql://localhost:3306/user"
        userId="root"
        password="root">
    </jdbcConnection>
    
    <javaTypeResolver >
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>

<!-- 生产的实体类所在的位置 -->
    <javaModelGenerator targetPackage="com.zhiyou100.yj.bean"  targetProject="./src">
        <property name="enableSubPackages" value="true" />
        <property name="trimStrings" value="true" />
    </javaModelGenerator>
<!-- 生成的映射文件所在的位置 -->
    <sqlMapGenerator targetPackage="com.zhiyou100.yj.mapper"   targetProject="./resources">
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>
<!-- 生产的dao文件所在的位置 -->
    <javaClientGenerator type="XMLMAPPER"  targetPackage="com.zhiyou100.yj.dao"  targetProject="./src">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>

<!-- 某张表与实体类的对象关系
      schem:该表所在的数据库
      tablename:表名
      domainObjectName:实体类名
-->
    <table schema="user" tableName="role" domainObjectName="Role"
    enableCountByExample="false" enableSelectByExample="false"  enableUpdateByExample="false" enableDeleteByExample="false">
        <!--禁止生成复杂方法-->
        <property name="useActualColumnNames" value="true"/>
        <generatedKey column="ID" sqlStatement="DB2" identity="true" />
        <columnOverride column="DATE_FIELD" property="startDate" />
        <ignoreColumn column="FRED" />
        <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />
    </table>
  </context>
</generatorConfiguration>

3.运行generator(ctrl+shift+o:快捷导包)

//新建测试类
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

public class TestGenerator {
    public static void main(String[] args) throws Exception {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File("mybatisGenerator.xml");
        ConfigurationParser cp = new  ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new  DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new  MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
      }
}
三、mybatis分页助手
1.引入jar包:jsqlparser及pagehelper
2.配置拦截器插件
<!--
    plugins在config.xml文件中的位置必须符合要求,否则会报错,顺序如下:
    properties?, settings?,
    typeAliases?, typeHandlers?,
    objectFactory?,objectWrapperFactory?,
    plugins?,
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
    <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
        <property name="param1" value="value1"/>
    </plugin>
</plugins>

3.测试

@Test
    void testSelectAll() {
        //设置分页,当前页码和每页显示的记录数
        int pageNum=1;
        int pageSize=3;
        PageHelper.startPage(pageNum,pageSize);
        //执行sql功能
        List<Role> roles = roleDao.selectAll();
        //查询结果封装到pageInfo对象中
        PageInfo<Role> pageinfo=new PageInfo<>(roles);
        System.out.println(pageinfo);
      }

    /*问题备注:
    Result Maps collection already contains value for xxxxxx   
    原因:mybatisGenerator生成xml的时候,可能xml的内容不会被覆盖,而是追加到后面,导致xml里面有两份甚至更多的一样的内容,造成重复注入
    解决:在生成xml前,把mapper标签里面的所有标签删除*/
原文地址:https://www.cnblogs.com/BoxMonster/p/11443388.html