MyBatis动态SQL、分页插件、缓存及逆向工程
1.MyBatis动态SQL
1.1 if语句+where
where标签可以去掉前面多余的and/or。
<select id="queryAccount" resultType="Account">
select * from account
<where>
<if test="name !=null and name !=''">
and name like concat('%',#{name},'%')
</if>
<if test="isdeleted!=null">
and isdeleted=#{isdeleted}
</if>
</where>
</select>
1.2 choose+when+otherwise
这对组合相当于 switch+case+default。
<select id="queryAccount1" resultType="Account">
select * from account where 1=1
<choose>
<when test="name != null and name !=''">
and name like concat('%',#{name},'%')
</when>
<when test="isdeleted!=null">
and isdeleted=#{isdeleted}
</when>
<otherwise>
<![CDATA[and money <1000 ]]>
</otherwise>
</choose>
</select>
1.3 trim
这里使用了前缀添加where,删除and
<!--trim-->
<select id="queryAccount2" resultType="Account">
select * from account
<trim prefix="where" prefixOverrides="and">
<choose>
<when test="name != null and name !=''">
and name like concat('%',#{name},'%')
</when>
<when test="isdeleted!=null">
and isdeleted=#{isdeleted}
</when>
<otherwise>
<![CDATA[and money <1000 ]]>
</otherwise>
</choose>
</trim>
</select>
1.4 foreach
属性 | 描述 |
---|---|
collection | 要做foreach的对象,作为入参时,List<?>对象默认用list代替作为键,数组对象有array代替作为键,Map对象没有默认的键。 当然在作为入参时可以使用@Param(“keyName”)来设置键,设置keyName后,list,array将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子: 如果User有属性List ids。入参是User对象,那么这个collection = "ids" 如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = "ids.id" 上面只是举例,具体collection等于什么,就看你想对那个元素做循环。 该参数为必选。 |
separator | 元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。 |
open | foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选。 |
item | 循环体中的具体对象。支持属性的点路径访问,如item.age,item.info.details。 具体说明:在list和数组中是其中的对象,在map中是value。 该参数为必选。 |
close | foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。 |
index | 在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。 |
Dao中代码:
<update id="insertRole">
insert into role values
<foreach collection="pidArr" index="index" item="pid" separator=",">
(#{param1},#{pid})
</foreach>
</update>
2.分页插件
2.1 导入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.11</version>
</dependency>
2.2 使用分页插件 在mybatis配置文件中加入如下代码
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
2.3 测试代码完成分页
Reader resourceAsReader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsReader);
SqlSession session = build.openSession();
AccountDao mapper = session.getMapper(AccountDao.class);
//开启分页
PageHelper.startPage(2,2);
List<Account> accounts = mapper.queryAccount1(new Account());
PageInfo<Account> pageInfo = new PageInfo<Account>(accounts);
System.out.println("总页数"+pageInfo.getPages());
System.out.println("总条数:"+pageInfo.getTotal());
System.out.println("当前显示的页码:"+pageInfo.getPageNum());
System.out.println("当前页码的数据:"+pageInfo.getList());
3.MyBatis的缓存
MyBatis自带一级缓存和二级缓存,一级缓存默认开启,二级缓存需要手动开启。
3.1 一级缓存
Mybatis的一级缓存是指Session缓存。一级缓存的作用域默认是一个SqlSession。Mybatis默认开启一级缓存。
也就是在同一个SqlSession中,执行相同的查询SQL,第一次会去数据库进行查询,并写到缓存中;
第二次以后是直接去缓存中取。
当执行SQL查询中间发生了增删改的操作,MyBatis会把SqlSession的缓存清空。
一级缓存的范围有SESSION和STATEMENT两种,默认是SESSION,如果不想使用一级缓存,可以把一级缓存的范围指定为STATEMENT,这样每次执行完一个Mapper中的语句后都会将一级缓存清除(不推荐这么做)。同样,也可以在Java中使用 session.clearCache() 清除掉一级缓存。
<setting name="localCacheScope" value="STATEMENT"/>
举个栗子:
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = build.openSession();
AccountMapper mapper = session.getMapper(AccountMapper.class);
List<Account> account = mapper.selectAll();
System.out.println(account);
List<Account> account1 = mapper.selectAll();
System.out.println(account1);
控制台输出:
我们使用session.clearCache() 清除掉一级缓存
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = build.openSession();
AccountMapper mapper = session.getMapper(AccountMapper.class);
List<Account> account = mapper.selectAll();
System.out.println(account);
//清空一级缓存
session.clearCache();
List<Account> account1 = mapper.selectAll();
System.out.println(account1);
不难看出,清空一级缓存后sql语句执行了两次。
3.2 二级缓存
Mybatis的二级缓存是指mapper映射文件。二级缓存的作用域是同一个namespace下的mapper映射文件内容,多个SqlSession共享。Mybatis需要手动设置启动二级缓存。
<settings>
<setting name="cacheEnabled" value="true" />
</settings>
接着在想要使用二级缓存的Mapper映射文件中配置:
<mapper namespace="com.xxx.dao.AccountMapper">
<!--开启二级缓存-->
<cache/>xxx
如果不想整个Mapper映射下的语句都使用二级缓存,则可以使用 useCache 属性,true为打开,false为关闭。
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap" useCache="true">
select
<include refid="Base_Column_List" />
from account
where id = #{id,jdbcType=INTEGER}
</select>
4.Mybatis Generator(MyBatis逆向工程)
4.1 导入依赖
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>
4.2 配置 generator.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>
<!--读取数据库连接信息-->
<properties resource="db.properties"/>
<!--mysql驱动jar所在的绝对路径 必须低于8.0以下 -->
<classPathEntry location="D:\apache-maven-3.6.3\maven-repssitort\mysql\mysql-connector-java\5.1.6\mysql-connector-java-5.1.6.jar" />
<context id="DB2Tables" targetRuntime="MyBatis3">
<!--关闭注释-->
<commentGenerator>
<property name="suppressAllComments" value="false" />
</commentGenerator>
<!--连接数据库的信息(可以通过资源文件读取)-->
<jdbcConnection driverClass="${driverName}"
connectionURL="${url}"
userId="${username}"
password="${username}">
</jdbcConnection>
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!--实体类生成的路径-->
<javaModelGenerator targetPackage="com.xxx.entity" targetProject="./src/main/java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!--映射文件生成的路径-->
<sqlMapGenerator targetPackage="mapper" targetProject="./src/main/resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!--dao生成的路径-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.xxx.dao" targetProject="./src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!--数据库的表信息-->
<table schema="day05" tableName="account" domainObjectName="Account"
enableUpdateByExample="false" enableSelectByExample="false" enableDeleteByExample="false"
enableCountByExample="false"
>
<property name="useActualColumnNames" value="true"/>
<generatedKey column="ID" sqlStatement="mysql" identity="true" />
<columnOverride column="DATE_FIELD" property="startDate" />
<ignoreColumn column="FRED" />
<columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />
</table>
</context>
</generatorConfiguration>
4.3 测试
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("generator.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);
基本的增删改查方法都能自动生成,下班!!