MyBaits入门第二部分
- 动态sql----简化sql语句动态拼串操作
- 缓存
动态sql----简化sql语句动态拼串操作
if标签—OGNL表达式
环境搭建:
Lock类:
public class main {
static SqlSessionFactory sqlSessionFactory;
static public void initSqlSessionFactory() throws IOException {
String resource = "MyBaits-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public static void main(String[] args) throws IOException
{
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(true);
try{
LockDao lock = sqlSession.getMapper(LockDao.class);
Lock l1=new Lock();
l1.setId(1);
l1.setName("%锁");
l1.setPrice(1000);
Lock l = lock.getLockByCondition(l1);
System.out.println(l);
}finally
{
sqlSession.close();
}
}
}
LockDao接口类:
public interface LockDao {
public Lock getLockByCondition(Lock lock);
}
LockDao.xml:
<?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="Com.MyBaits.KeyDao.LockDao">
<!--if标签-->
<select id="getLockByCondition" resultType="Com.MyBaits.KeyAndLock.Lock">
SELECT l.id,l.lockName name,l.price FROM `lock` l where
<!--
test="" :编写判断条件
id!=null :取出传入的javaBean属性中的id的值,判断其是否为空
-->
<if test="id!=null">
id > #{id} and
</if>
<!--空串"" and; &&==>xml中使用需要进行转义 ""===>使用也需要转义-->
<if test="name!=null and name!=""">
lockName like #{name} and
</if>
<if test="price!=null">
<!--这里的<也需要进行转义-->
price < #{price}
</if>
</select>
</mapper>
MyBaits-config.xml:
<!--写好的sql映射文件需要使用mappers注册起来-->
<mappers>
<mapper resource="LockDao.xml"/>
</mappers>
main:
public class main {
static SqlSessionFactory sqlSessionFactory;
static public void initSqlSessionFactory() throws IOException {
String resource = "MyBaits-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public static void main(String[] args) throws IOException
{
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(true);
try{
LockDao lock = sqlSession.getMapper(LockDao.class);
Lock l1=new Lock();
l1.setId(1);
l1.setName("%锁");
l1.setPrice(1000);
Lock l = lock.getLockByCondition(l1);
System.out.println(l);
}finally
{
sqlSession.close();
}
}
}
结果:
where标签
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
写了where标签后,后自动在sql语句后面拼接一个where
我们查询的条件就放在where标签中,每个and写在前面,where自动帮我们取出多余的and
<?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="Com.MyBaits.KeyDao.LockDao">
<!--if标签-->
<select id="getLockByCondition" resultType="Com.MyBaits.KeyAndLock.Lock">
SELECT l.id,l.lockName `name`,l.price FROM `lock` l
<where>
<!--
test="" :编写判断条件
id!=null :取出传入的javaBean属性中的id的值,判断其是否为空
-->
<if test="id!=null">
id > #{id} and
</if>
<!--空串"" and; &&==>xml中使用需要进行转义 ""===>使用也需要转义-->
<if test="name!=null and name!=""">
lockName like #{name} and
</if>
<if test="price!=null">
<!--这里的<也需要进行转义-->
price < #{price}
</if>
</where>
</select>
</mapper>
trim标签
截取字符串
prefix="" :前缀,为我们下面的sql语句整体添加一个前缀
prefixOverrides="" :取出整体字符串前面可能多余的字符
suffix="" :为整体添加一个后缀
suffixOverrides="":取出整体字符串后面可能多用的字符
下面自动帮我们添加一个where前缀,去掉整体最开始的and和最后的and
<?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="Com.MyBaits.KeyDao.LockDao">
<!--if标签-->
<select id="getLockByCondition" resultType="Com.MyBaits.KeyAndLock.Lock">
SELECT l.id,l.lockName `name`,l.price FROM `lock` l
<trim prefix="where" prefixOverrides="and" suffixOverrides="and">
<if test="id!=null">
and id > #{id}
</if>
<if test="name!=null and name!=""">
and lockName like #{name}
</if>
<if test="price!=null">
and price < #{price} and
</if>
</trim>
</select>
</mapper>
foreach标签
LockDao接口类:
public interface LockDao {
public List<Lock> getLockByCondition(@Param("list") List<Integer> listId);
}
LockDao.xml:
<?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="Com.MyBaits.KeyDao.LockDao">
<!--if标签-->
<select id="getLockByCondition" resultType="Com.MyBaits.KeyAndLock.Lock">
SELECT l.id,l.lockName `name`,l.price FROM `lock` l WHERE id IN
/*对应list集合来说,key默认为list,我们也可以自己指定参数的key值*/
<foreach collection="list" close=")" item="id_item" open="(" separator=",">
#{id_item}
</foreach>
</select>
</mapper>
main:
public class main {
static SqlSessionFactory sqlSessionFactory;
static public void initSqlSessionFactory() throws IOException {
String resource = "MyBaits-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public static void main(String[] args) throws IOException
{
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(true);
try{
LockDao lock = sqlSession.getMapper(LockDao.class);
List<Integer> idList=new LinkedList<Integer>();
idList.add(1);
idList.add(2);
idList.add(3);
idList.add(4);
idList.add(5);
List<Lock> lockList = lock.getLockByCondition(idList);
for(Lock l:lockList)
{
System.out.println(1);
}
}finally
{
sqlSession.close();
}
}
}
chose标签—当做if…else或者switch使用
LockDao.xml :
<?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="Com.MyBaits.KeyDao.LockDao">
<!--if标签-->
<select id="getLockByCondition" resultType="Com.MyBaits.KeyAndLock.Lock">
SELECT l.id,l.lockName `name`,l.price FROM `lock` l
<where>
<choose>
<when test="id !=null">id=#{id}</when>
<otherwise>id=2</otherwise>
</choose>
</where>
</select>
</mapper>
LockDao接口:
public interface LockDao {
public Lock getLockByCondition(@Param("id") Integer id);
}
如果传入对象,那么在使用属性名的时候可以识别
传入基本数据类型时,防止如下错误发生:There is no getter for property named id in class java.lang.Integer ,给参数设置key名
字段部分更新-----》if结合set
<update id="UpdateLock">
update `lock`
<set>
<if test="id<=5 and id >=1">
<if test="name!=null">lockName=#{name},</if>
<if test="price!=null">price=#{price},</if>
</if>
</set>
<where>
id=#{id}
</where>
</update>
OGNL表达式
不仅可以直接调用属性,还可以调用方法
OGNL表达式里面的集合伪属性
//前提,list是集合
<if test="list.size>0"></if>
不仅可以判断参数,还可以判断_parameter和_databasedId
bind标签
bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>
sql标签配合include标签完成对重复sql语句的抽取
要在带注解的映射器接口类中使用动态 SQL,可以使用 script 元素
缓存
一级缓存
一级缓存失效情况
手动清空缓冲的函数:
sqlSession.clearCache();
二级缓存: namespace级别的缓存,隔一段时间会自动刷新缓存
只有在sqlSession关闭或提交后,才会把数据从一级缓存中,搬家来到二级缓存
第一步:配置文件中开启二级缓存
<!--开启全局缓存开关-->
<setting name="cacheEnabled" value="true"/>
第二步:在需要使用二级缓存的映射文件中使用cache配置缓存
<!--使用二级缓存-->
<cache></cache>
第三步: POJO对象需要实现序列化接口
二级缓存cache标签里面的相关属性
缓存的查询顺序
缓存原理----每一个dao有他自己的二级缓存
缓存有关的设置
整合第三方缓存—这里整合ehcache—java进程内的缓存框架
1.导入依赖
<!--ehcache第三方专业缓存框架的依赖-->
<!--ehcache的核心包-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.8</version>
</dependency>
<!--ehcache的整合包-->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.3</version>
</dependency>
<!--除了log4j,还需要导入slf4j的日志包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
<scope>test</scope>
</dependency>
2.ehcache要工作需要一个配置文件,文件名叫ehcache.xml,放在类路径的根目录下
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<!--持久化磁盘路径-->
<diskStore path="java.io.tmpdir"/>
<!--默认缓存设置-->
<defaultCache maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="0"
overflowToDisk="true"
maxElementsOnDisk="10000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="FIFO"
/>
<!--
<cache name 缓存名唯一标识
maxElementsInMemory="1000" 内存中最大缓存对象数
eternal="false" 是否永久缓存
timeToIdleSeconds="3600" 缓存清除时间 默认是0 即永不过期
timeToLiveSeconds="0" 缓存存活时间 默认是0 即永不过期
overflowToDisk="true" 缓存对象达到最大数后,将其写入硬盘
maxElementsOnDisk="10000" 磁盘最大缓存数
diskPersistent="false" 磁盘持久化
diskExpiryThreadIntervalSeconds="120" 磁盘缓存的清理线程运行间隔
memoryStoreEvictionPolicy="FIFO" 缓存清空策略
FIFO 先进先出
LFU less frequently used 最少使用
LRU least recently used 最近最少使用
/>
-->
<cache name="testCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true"
memoryStoreEvictionPolicy="FIFO">
</cache>
</ehcache>