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();
        
        
    }
}

 

posted on 2015-04-29 13:14  itliucheng  阅读(394)  评论(0编辑  收藏  举报