zoukankan      html  css  js  c++  java
  • mybatis 动态sql

    接口中

    public interface AdminMapper {    
        public List<Admin> findByParams(Map<String,Object> param);
    }

    AdminMapper.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.kaishengit.mapper.AdminMapper">
        
        
        
        <select id="findByParams" parameterType="map" resultType="list" resultMap="adminMap">
            select * from admin 
            <where>
                <if test="name != null">
                    name = #{name} 
                </if>
                <if test="password != null">
                    and password = #{password}
                </if>
            </where>
        </select>
        <!-- 在代码中就可以选择性的put name或者password,因为只要有if判断成立,会自动加上where
            在第一个if不成立,第二个if成立的时候会自动把第二个条件前面的and去掉
            
            原形:
            <select id="findByParams" parameterType="map" resultType="list" resultMap="adminMap">
                select * from admin where (where后面要有一个空格,方便与后面的进行拼凑)
                <if test="name != null">
                    name = #{name} 
                </if>
                <if test="password != null">
                    and password = #{password}
                </if>
            </select>
            但是这样是有问题的,如果两个if都不成立就会多出一个where,或者第一个不成立就会多出一个and
            
            所以我们可以用上面这样的where 标签 只要有if判断成立,会自动加上where
            在第一个if不成立,第二个if成立的时候会自动把第二个条件前面的and去掉
            
            除了用where还可以用trim
            <select id="findByParams" parameterType="map" resultType="list" resultMap="adminMap">
                select * from admin 
                只要有一个if成立就添加where 并且告诉前缀是and或者or,只要在前面if不成立时 自动屏蔽and或or
                suffixOverrides(覆盖后缀),在后面一个if不成立的情况下,自动屏蔽上一个的and或者or
                <trim prefix="WHERE" prefixOverrides="AND |OR ">
                    <if test="name != null">
                        name = #{name} 
                    </if>
                    <if test="password != null">
                        and password = #{password}
                    </if>
                </trim>
            </select>
            -->
        
        <resultMap type="Admin" id="adminMap">
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <result property="password" column="password"/>
        </resultMap>
        
    </mapper>

    代码中

    public class Test {
    
        public static void main(String[] args) throws Exception {
    
            Reader reader = Resources.getResourceAsReader("mybatis.xml");
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
            
            SqlSession session = factory.openSession(true);
            
            
            
            AdminMapper mapper = session.getMapper(AdminMapper.class);
            // 动态查询 
            Map<String, Object> map = new HashMap<String, Object>();
            
            map.put("name", "admin");
            map.put("password", "000000");
            
            List<Admin> list = mapper.findByParams(map);
            for(Admin admin : list) {
                System.out.println(admin.getId());
            }
            
            
            session.close();
            
        }
    }

    xml中还提供动态的其他sql

    更新

    当if成立的时候自动在前面加set

    <update id="updateAuthorIfNecessary" parameterType="domain.blog.Author">
        update Author
        <set>
            <if test="username != null">username=#{username},</if>
            <if test="password != null">password=#{password},</if>
            <if test="email != null">email=#{email},</if>
            <if test="bio != null">bio=#{bio}</if>
        </set>
        where id=#{id}
    </update>
    <!--或者用trim 最后一个不成立的时候自动屏蔽倒数第二个的逗号
    <update id="updateAuthorIfNecessary" parameterType="domain.blog.Author">
        update Author
        <trim prefix="SET" suffixOverrides=",">
            <if test="username != null">username=#{username},</if>
            <if test="password != null">password=#{password},</if>
            <if test="email != null">email=#{email},</if>
            <if test="bio != null">bio=#{bio}</if>
        </trim>
        where id=#{id}
    </update> 

    foreach

    <select id="selectPostIn" resultType="domain.blog.Post">
    SELECT *
    FROM POST P
    WHERE ID in
    <foreachitem="item" index="index" collection="list" open="(" separator="," close=")">
    #{item}
    </foreach>
    </select>

    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------

    缓存

    <mapper namespace="com.kaishengit.mapper.NewsMapper">
    <cache/>
    ...
    </mapper>

    对象(pojo)必须是可序列化

    功效如下:
     映射语句文件中所有的select语句将被缓存
     映射语句文件中的所有insert、update、delete语句会刷新缓存
     缓存会使用least recentilyused(LRU,最近很少使用的)算法来收回
     根据时间间隔来刷新缓存,默认不刷新
     缓存会存储列表集合或对象的1024个引用
     缓存被视为read/write的缓存

     

    更改缓存
      <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
    上面配置了一个FIFO缓存,每隔60秒刷新一次缓存,存储对象或集合512个引用,
    而且缓存为只读缓存。


     eviction回收策略
     LRU:最近最少使用的,移除长时间不被使用的对象(默认)
     FIFO:先进先出:按对象进入缓存的顺序来移除他们
     SOFT:软引用:移除基于垃圾回收器状态和软引用规则的对象
     WEAK:弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
     flushInterval(刷新间隔):可以被设置为任意的正整数
      size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行
    环境的可用内存资源数目。默认值是1024。
     readOnly(只读)属性可以被设置为true 或false。只读的缓存会给所有调用者返
    回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
    可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此
    默认是false。

    -----------------------------------------------------
    -----------------------------------------------------
    -----------------------------------------------------

    MyBatisAnnotation

    对于动态sql还是要自己写配置文件,不能用 annotation

    主配置文件中

    <mappers>
        <mapper class="com.kaishengit.mapper.DeptMapper"/>
        <mapper class="com.kaishengit.mapper.UserMapper"/>
    </mappers>

    接口中 

    注解的缓存直接加@cachenamespace

    @CacheNamespace
    public interface AdminMapper {
    
        @Insert("insert into admin(name,password) values(#{name},#{password})")
        @Options(flushCache=false)
        public void save(Admin admin);
        
        @Delete("delete from admin where id = #{id}")
        public void delete(int id);
        
        @Select("select * from admin where id = #{id}")
        public Admin findById(int id);
        
        @Update("update admin set name = #{name},password=#{password} where id = #{id}")
        public void update(Admin admin);
        
        @Select("select * from admin")
        public List<Admin> findAll();
        
        @Select("select * from admin where name = #{name} and password = #{password}")
        /* 如果有多个参数,需要加注解,表明String name的这个name是给上面的大括号里面的name的 */
        public Admin findByNameAndPwd(@Param("name") String name,@Param("password") String password);
        
        
        /--------------------------------/
        
        /*多表查询
        从adminMapper中链接查询到postMapper中    */
        @Select("select * from admin where id = #{id}")
        @Results(value={
                @Result(property="id",column="id"),
                @Result(property="name",column="name"),
                @Result(property="password",column="password"),
                /*property属性名  javaType该属性的类型 
                    admin和post是一对多 many指定postMapper中链接查询的对应的方法
                    column="id"只传到postMapper中的findByAdminId方法中的参数*/
                @Result(property="posts",javaType=List.class,column="id",many=@Many(select="com.kaishengit.mapper.PostMapper.findByAdminId"))
        })
        public Admin find(int id);
        
        
    }

    然后再postMapper中要写多表查询相关的查询,因为在adminMapper中的查询语句只有 select * from admin where id = #{id}

    @CacheNamespace
    public interface PostMapper {
        //接受admin的id然后链接查询  
        @Select("SELECT * FROM post WHERE aid = #{adminId}")
        public List<Post> findByAdminId(int adminId);
        
        //从postMapper中链接查询到adminMapper中
        @Select("select * from post where id = #{id}")
        @Results(value={
                @Result(property="id",column="id"),
                @Result(property="title",column="title"),
                /* admin和post是一对多,one=@One(select="com.kaishengit.mapper.AdminMapper.findById")链接查询到
                    admin中的findById方法中,传过去的参数是aid*/
                @Result(property="admin",javaType=Admin.class,column="aid",one=@One(select="com.kaishengit.mapper.AdminMapper.findById"))
        })
        public Post findById(int id);
        
        
    }
    public class Test {
    
        public static void main(String[] args) throws Exception {
        
            Reader reader = Resources.getResourceAsReader("mybatis.xml");
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
            
            
            //没有了配置文件, 要加上这一段
            factory.getConfiguration().addMapper(AdminMapper.class);
            factory.getConfiguration().addMapper(PostMapper.class);
            
            
            SqlSession session = factory.openSession(true);
            
            
            
            session.close();
            
            
        }
    }
  • 相关阅读:
    Macbook键盘的使用基础技巧
    JSTL详解
    为了理想,因为爱情-开课第一天有感(鸡汤向)
    HK游记 Day2迪斯尼(下)
    MP20 MBO issue summary
    音频测量加权
    有没有降噪
    信源编码信源译码和信道编码和译码和加密和解密数字调制和解调和同步
    gcc
    数据挖掘|统计的艺术
  • 原文地址:https://www.cnblogs.com/itliucheng/p/4465683.html
Copyright © 2011-2022 走看看