zoukankan      html  css  js  c++  java
  • Mybatis笔记

    Mybatis开始

    SQL语句输出方式

    1.在全局配置文件中,配置标签

        <settings>
            <setting name="logImpl" value="STDOUT_LOGGING"/>
        </settings>

    2.使用log4j等工具,进行输出

    mapper中传递参数方式

    #{}和${}的区别 #{}表示占位符的方式拼接sql语句 占位符为"?" ${}表示拼接字符串的方式拼接sql语句 ${}很少用

    <select id="selAll" resultType="com.bjsxt.pojo.People" parameterType="int">
            select *from People where id=#{0} //传入参数为 的时候 使用索引 占位符选择0位置第一个参数   当传入参数只有一个的时候,#{}大括号中内容可以位任意字符
            select *from People where id=#{param1}//param+数字表示第几个参数,从1开始
            select *from People where id=#{0}//此时不使用索引  单纯的id=0
    </select>
    <select id="selAll" resultType="com.bjsxt.pojo.People" parameterType="com.bjsxt.pojo.People">
            select *from People where id=#{id}
            select *from People where id=${id}//若使用拼接字符串方式,则需要传入为对象,mybatis自动在传入的对象中寻找对应名字的getset方法来获取值
    </select>
    <select id="selAll" resultType="com.bjsxt.pojo.People" parameterType="java.util.Map">
            select *from People where id=#{key} //#{}中填写map的key
    </select>

    全局配置文件解释

    1.1 <transactionManager/> type 属性可取值 1.1.1 JDBC,事务管理使用 JDBC 原生事务管理方式 1.1.2 MANAGED 把事务管理转交给其他容器,如交给Spring进行管理.原生JDBC 事务 setAutoMapping(false); 1.2 <dataSouce/>type 属性 1.2.1 POOLED 使用数据库连接池 1.2.2 UNPOOLED 不实用数据库连接池,和直接使用 JDBC 一样 1.2.3 JNDI :java 命名目录接口技术.

    例子:

    <configuration>
        <!-- default引用environment的id,当前所使用的环境 -->
        <environments default="default">
            <!-- 声明可以使用的环境 -->
            <environment id="default">
                <!-- 使用原生JDBC事务 -->
                <transactionManager type="JDBC"></transactionManager>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
                    <property name="username" value="root"/>
                    <property name="password" value="yu752949273"/>
                </dataSource>
            </environment>
        </environments>

    绝对路径

    如果是请求转发 / 表示项目根目录(WebContent) 其他重定向,<img/> <script/>,<style/>,location.href 等/都表示服务器根目录(tomcat/webapps 文件夹) 如果客户端请求的控制器,控制器转发到JSP后,jsp中如果使用相对路径,需要按照控制器的路径去找其他资源. 尽量使用绝对路径 避免相对路径与控制器路径冲突的问题

     

    mybatis与ibatis的区别

    版本

    2.x为ibatis 3.x为mybatis

    全局配置文件中

    ibatis中使用sqlMap元素,mybatis中使用mappers元素 ibatis中根元素是sqlMapConfig,mybatis中是configuration settings中属性配置不同

    ibatis中为

    <settings 属性1="属性值1" 属性2="属性值2"  属性x="属性值x"/>

    mybatis中为

    <settings>

    <setting name="属性1" value="属性值1"/>

    <setting name="属性2" value="属性值2"/>

    <setting name="属性x" value="属性值x"/>

    </settings>

    映射文件中

    ibatis中使用sqlMap元素,mybatis中使用mapper元素

    resultMap

    当返回值类型为resultMap时,需要在mapper中编写resultMap与实体类中的属性向映射,其中 一对一association 一对多,多对多collection

    <association property="" column="" select=""></association>  <!--property为映射实体类中属性 column为数据库中属性列 select为子查询id-->
    <collection property="" column="" ofType="" select=""></collection> <!--property为映射实体类中属性 column为数据库中属性列 select为子查询id  ofType为另一对多的实体类-->

    动态sql

    标签

    <where>   <set>   <if test="a!=null and a!=''">   <trim>   <bind>   <choose><when><otherwise>    <sql><include>   <foreach>

    <where>标签

    先去掉条件的第一个and 然后添加where 当where中的条件不存在时 where标签也不存在

    <select id="selByAccinAccout" resultType="log">
        select * from log
            <where>
                <if test="accin!=null and accin!=''"> 
                    and accin=#{accin}
                </if>
                <if test="accout!=null and accout!=''">
                    and accout=#{accout}
                </if>
            </where>
    </select>

    <set>标签

    先去掉条件的最后一个逗号 然后在最前面添加set 当set中的条件不存在时 set标签也不存在

    <update id="upd" parameterType="log" >
    update log
        <set>
            id=#{id},
            <if test="accIn!=null and accIn!=''">
                accin=#{accIn},
            </if>
            <if test="accOut!=null and accOut!=''">
                accout=#{accOut},
            </if>
        </set>
    where id=#{id}
    </update>

    <if>标签

    若不满足条件则该字句不存在 test等于的字符串中,若条件为多个,则用and或or连接 不是&或|

    <if test="accin!=null and accin!=''">
    and accin=#{accin}
    </if>

    <trim>标签

    prefix 在前面添加内容 prefixOverrides 去掉前面内容 suffix 在后面添加内容 suffixOverrieds 去掉后面内容 执行顺序为 先去掉内容 再添加内容

    <update id="upd" parameterType="log">
        update log
            <trim prefix="set" suffixOverrides=",">
                a=a,
            </trim>
        where id=100
    </update>

    <bind>标签

    为传递的变量拼接字符

    <bind name="aaa" value="'$'+aaa"/>

    <choose><when><otherwise>标签

        <choose>
            <when test="a!=null">
            </when>
        </choose>
        <choose>
            <when test="b!=null">
            </when>
        </choose>

    只要有一个成立,其他都不执行. 若存在多个能够成立的,则只执行成立的第一个

    choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql。

    <sql><include>标签

    sql片段 复用 <sql id="a"></sql> <include refid="a"></include>

    <foreach>标签

    <foreach collection="" item="" index="" open="" close="" separator="">

    </foreach>

    foreach 也就是遍历迭代,在SQL中通常用在 in 这个关键词的后面

    foreach元素的属性主要有 item,index,collection,open,separator,close。

    分别代表:

    item表示集合中每一个元素进行迭代时的别名,
    index用于表示在迭代过程中,每次迭代到的位置,
    open表示该语句以什么开始,
    separator表示在每次进行迭代之间以什么符号作为分隔 符,
    close表示以什么结束
     
    代码片段:
    <select id="selectByIds" resultType="com.txw.pojo.User">
            select * from user where id in
            <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
                #{item}
            </foreach>
    </select>

    而最为重要的就是collection属性了,既然是迭代就表示传入的参数是多个,这时候传入的参数就有以下几种可能:

    1. 传入的参数为list的时候

     对应的Dao中的Mapper文件是:

    public List<User> selectByIds(List<Integer> ids);
     
    xml文件代码片段:
    <select id="selectByIds" resultType="com.txw.pojo.User">
            select * from user where id in
            <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
                #{item}
            </foreach>
    </select>
    2. 传入的参数为Array的时候

    对应的Dao中的Mapper文件是:

    public List<User> selectByIds(int[] ids);

    xml文件代码片段: 

    <select id="selectByIds" resultType="com.txw.pojo.User">
            select * from user where id in
            <foreach collection="array" index="index" item="item" open="(" separator="," close=")">
                #{item}
            </foreach>
        </select>
     
    3. 传入的参数为Map的时候
    对应的Dao中的Mapper文件是:

    public List<User> selectByIds(Map<String, Object> params);

    xml文件代码片段: 

    <select id="selectByIds" resultType="com.txw.pojo.User">
            select * from user where  id in
            <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">
                #{item}
            </foreach>
        </select>
     
    map的时候需要注意的是:collection的值“ids”是存储在map中的key(比如:map.put("ids",ids));尤其需要注意;

     

    ThreadLocal线程容器

    给线程绑定一个Object容器,若线程状态不变则可以随时取出,若线程发生改变,则无法取出.

    final ThreadLocal<String> threadLocal = new ThreadLocal<>();
    threadLocal.set("测试");
    new Thread(){
        public void run() {
        String result = threadLocal.get();
        System.out.println("结果:"+result);//线程改变无法取出
        };
    }.start();
    String result = threadLocal.get();
    System.out.println("结果:"+result);//可以取出

    主要用于同一Servlet线程,静态加载SqlSessionFactory

    工具类:

    import java.io.IOException;
    import java.io.InputStream;
    ​
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    ​
    public class MyBatisUtil {
        //factory实例化的过程是一个比较耗费性能的过程.
        //保证有且只有一个factory
        private static SqlSessionFactory factory;
        private static ThreadLocal<SqlSession> tl = new ThreadLocal<>();
        static{
            try {
                InputStream is = Resources.getResourceAsStream("mybatis.xml");
                factory = new SqlSessionFactoryBuilder().build(is);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        /**
         * 获取SqlSession的方法
         */
        public static SqlSession getSession(){
            SqlSession session = tl.get();
            if(session==null){
                tl.set(factory.openSession());
            }
            return tl.get();
        }
        
        public static void closeSession(){
            SqlSession session = tl.get();
            if(session!=null){
                session.close();
            }
            tl.set(null);
        }
    }

    拦截器:

    import java.io.IOException;
    import java.io.InputStream;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import com.bjsxt.util.MyBatisUtil;
    /**
     * 最开始是由Spring框架提出的.整合Hibernate框架是使用的是OpenSessionInView
     * 
     * 
     * @author Administrator
     *
     */
    @WebFilter("/*")
    public class OpenSessionInView implements Filter{
        @Override
        public void init(FilterConfig filterconfig) throws ServletException {   
        }
        @Override
        public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain)
                throws IOException, ServletException {  
            SqlSession session = MyBatisUtil.getSession();
            try {
                filterchain.doFilter(servletrequest, servletresponse);//允许servlet执行,而允许service执行
                session.commit();
            } catch (Exception e) {
                session.rollback();
                e.printStackTrace();
            }finally{
                MyBatisUtil.closeSession();
            }
        }
        @Override
        public void destroy() {
        }
    }

    缓存

    MyBatis 中默认 SqlSession 缓存开启

    SqlSession 缓存必须是同一个SqlSession 对象

    同一个 SqlSession 对象调用同一个时,只有第一次访问数据库,第一次之后把查询结果缓存到 SqlSession 缓存区(内存)中

    缓存流程

    步骤一: 先去缓存区中找是否存在 statement(<select>) 步骤二:返回结果 步骤三:如果没有缓存 statement 对象,去数据库获取数据 步骤四:数据库返回查询结果 步骤五:把查询结果放到对应的缓存区中

    SqlSessionFactory 缓存

    比 SqlSession 缓存高一级的二级缓存,默认关闭 开启方法再mapper.xml的mapper中添加标签:

    <mapper namespace="com.bjsxt.mapper.LogMapper">
    <cache readOnly="true"></cache>
        <insert id="ins" parameterType="log">
            insert into log values(default,#{accOut},#{accIn},#{money})
        </insert>
    </mapper>

    只有当SqlSession在commit()或close()的时候才会将SqlSession缓存提交到SqlSessionFactory缓存中

    Mybatis运行原理

    运行过程中需要用到的类:

    Resource 加载Mybatis全局配置文件的IO流工具

    SqlSessionFactoryBuilder() 创建SqlSessionFactory接口的实现类

    XMLConfigBuilder 读取全局配置文件的流内容,转换为JAVA代码

    Configuration 由XMLConfigBuilder 创建,封装了全局配置文件中所有的属性信息

    DefaultSqlSessionFactory 是SqlSessionFactory接口的实现类

    Transaction 事务类 每一个Session都会创建一个Transaction对象进行事务管理

    TransactionFactory 事务工厂,负责生产事务类

    Executor Mybatis执行器 一般使用SimpleExecutor实现类,批量操作时,使用BatchExecutor 通过OpenSession的参数控制 负责执行SQL命令 相当于JDBC 中的statement对象或preparedStatement对象或callableStatement对象

    Mybatis结束

  • 相关阅读:
    ASP.NET MVC Razor 视图引擎
    Asp.net MVC3 Razor语法小记
    @RenderPage用法
    余数算法
    Linux命令行下运行java.class文件
    Java学习---9.GUI编程
    Java学习---8.线程同步
    Java学习---7.多线程
    Java学习---6.常用的容器,流
    Java学习---5.数组
  • 原文地址:https://www.cnblogs.com/yuming2018/p/11325783.html
Copyright © 2011-2022 走看看