• 原生mybatis使用细节回顾


    mybatis笔记

    1、${} 和#{}的区别

    #{}是获取参数的内容支持,

    ​ 索引获取;#{0},parameterType可以是int String之类的。

    ​ ${param1} 获取指定位置的参数;====== #{0}

    若是parameterType是People的话,也可以是#{id},但不是通过拼接,而是通过占位符。

    最重要的是,SQL是使用的占位符进行控制。

    ${}是字符串的拼接,不是使用的占位符,寻找的内容默认是通过get/set方法

    例如:parameterType的People ,${id} 即可拼接对应的sql语句。

    ${0} 默认拼接的就是数字0,而不是第一个参数的值。

    2、CDATA关系运算符

    3、limit运算符

    示例:

    select * from people limit 1,2; --从第2行开始,找出两行;

    mybatis进行分页时,关键字的逗号 ,之前和之后是不允许关系运算的。所以pageSize和PageNumber都必须计算好之后再进行传递;

    4、别名的使用

    mybatis.xml配置数据库的。

    <configuration><settings><setting name="logImpl" value=LOG4J />settings>
    	<typeAliases><typeAlias type="com.pshdhx.pojo.People" alias="People" />
            <package name="com.pshdhx.pojo" />typeAliases>
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    配置了别名,即可在mybatis中的resultType和parameterType中使用。

    package配置了,那么只写People也可以找的到类。

    5、系统内置别名

    就是把java.lang.Integer 包装类换成了int的小写;

    其他的也换成了消息hashmap等, list,arraylist都是换成了纯小写;

    6、mybatis的新增事务

    mybatis的自动提交是关闭的,所以需要在新增时,打开自动提交。

    每一个sqlSession,都会建立一个对数据库的连接,事务提交的设置,是针对于这个session的。

    openSession(true);

    setAutoCommit(true);

    InputStream is = Resources.getResourceAsStream("mybatis.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
    SqlSession session = factory.openSession();
    //利用SqlSession对象进行sql操作
    
    • 1
    • 2
    • 3
    • 4

    7、mybatis的动态sql

    根据不同的条件,执行不同的sql语句。

    <if>
    	1、作为判断;
    if>
    <where>
        1、去掉标签块里边的第一个and;
        2、少写一个where关键字;
        3、不用写where 1=1了;
        	<choose>
                1、choose when连用,相当于switch case,只走一个分支就结束。
                <when test="accIn != null and accIn !=''">
                    	and accIn = #{accIn}
                when>
                <when test="accOut != null and accOut !=''">
                    	and accOut = #{accOut}
                when>
        	choose>
    where>
    
    <set>
        1、生成set关键字;
        2、去掉最后的一个逗号 “,”; 
    set>
    
    select * from log
    <trim prefix="where" prefixOverrides="and"> 
        1、去掉了最前边的and
        2、给前面加了个where
        3、千万记住顺序,先去掉,后添加。
        4、suffix:在后边添加内容;
        5、suffixOverrides:去掉后边的内容;
        and accIn = #{accIn}
    trim>
    == select * from log where accIn = #{accIn};
    
    <bind name="money" value="'$'+money"/>
    <bind name="money" value="'%'+money+'%'"/>
    1、如此,传递过来的money,就自动加上了'$'符号;
    2、如此,也这样实现模糊查询;
    <foreach collection="list" open="(" close=")"  separator=",">
        1、适用于in的查询;
        2、适用于批量新增,比单条语句批量执行效率高;
    foreach>
    
    mybatis中的foreach效率比较低;
    factory.openSession(ExecutorType.BATCH);
    底层是JDBC的PreparedStatement.addBatch();
    <sql id="mysql">sql>
    <select id="">
    	<include refid="mysql">include>
    select>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    8、ThreadLocal

    作用:给线程容器绑定一个对象,只要该线程不变,在随时随地都可以取得到对象。

    final ThreadLocal<String> threadLocal = new ThreadLocal<>();
    threadLocal.set("测试");
    String result = threadLocal.get();
    
    
    • 1
    • 2
    • 3
    • 4

    该对象要么是全局的,要么是final(不允许改变)的。一旦改变线程,就无法取出对象。

    在此处的作用:SqlSessionFactory的实例化是一个比较耗费性能的过程,所以需要在类加载的时候,就给创建出来。

    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);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    我们需要在web.xml中配置下过滤器【被下边filter取缔】

    <web-app>
    	<filter>
        	<filter-name>opensessionfilter-name>
            <filter-class>com.pshdhx.filter.OpenSessionInViewfilter-class>
        filter>
        <filter-mapping>
        	<filter-name>opensessionfilter-name>
            <url-pattern>/*url-pattern>
        filter-mapping>
    web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    @WebFilter("/*")
    public class OpenSessionInView implements Filter{
    
    	@Override
    	public void init(FilterConfig filterconfig) throws ServletException {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain)
    			throws IOException, ServletException {	
    		SqlSession session = MyBatisUtil.getSession();
    		try {
    			filterchain.doFilter(servletrequest, servletresponse);
    			session.commit();
    		} catch (Exception e) {
    			session.rollback();
    			e.printStackTrace();
    		}finally{
    			MyBatisUtil.closeSession();
    		}
    	}
    
    	@Override
    	public void destroy() {
    		// TODO Auto-generated method stub
    		
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    9、mybatis缓存

    在mybatis中,默认sqlSession的缓存开启;

    同一个sqlSession对象,调用同一个sql的id语句时,会把第一次调用返回的结果缓存到内存中。

    缓存的是一个statement对象。

    <select statementType="CALLABLE/PREPARED/STATEMENT">
        prepared 是statement的子接口,它把sql注入的问题解决掉了。
        callable:调用存储过程
    select>
    
    • 1
    • 2
    • 3
    • 4

    SqlSessionFactory 缓存,又叫二级缓存,缓存对象扩展了一级,是factory对象。
    只需要在 mapper.xml 中添加

    如果不写 readOnly=”true”需要把实体类序列化(把内存中的数据,持久化到硬盘上)

    当 SqlSession 对象 close()时或 commit()时会把 SqlSession 缓存
    的数据刷(flush)到 SqlSessionFactory (二级)缓存区中

    10、resultMap

    返回的结果集中包含一个对象;association

    <resultMap type="student" id="stuMap">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="tid" column="tid"/>
        
        <association property="teacher"
        select="com.pshdhx.mapper.TeacherMapper.selById"
        column="tid">association>
    resultMap>
    
    <select id="selById" resultType="teacher"
    parameterType="int">
    select * from teacher where id=#{0}
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    包含多个对象 使用collection标签,ofType不影响;

    <resultMap type="teacher" id="mymap">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <collection property="list" ofType="student"
        select="com.bjsxt.mapper.StudentMapper.selByTid"
        column="id">collection>
    resultMap>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    辅表联查主表,mybatis自动过滤。

    <resultMap type="teacher" id="mymap1">
        <id column="tid" property="id"/>
        <result column="tname" property="name"/>
        <collection property="list" ofType="student" >
            <id column="sid" property="id"/>
            <result column="sname" property="name"/>
            <result column="age" property="age"/>
            <result column="tid" property="tid"/>
        collection>
    resultMap>
    <select id="selAll1" resultMap="mymap1">
    select t.id tid,t.name tname,s.id sid,s.name
    sname,age,tid from teacher t LEFT JOIN student s on
    t.id=s.tid;
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    只会生成两个teacher对象,每个teacher对象里边有若干个student。归根到底:

    mybatis可以通过主键判断该对象是否被加载过,如果被加载过,那么就不需要创建新的对象;否则,就创建新的对象。

    11、关于mybatis中代码解读

    LogMapper logMapper = session.getMapper(LogMapper.class);
    logMapper.selectAll();//此为接口代理的方法
    //未获取到接口对象之前的操作
    session.selectList("com.pshdhx.mapper.logMapper.selAll");
    
    • 1
    • 2
    • 3
    • 4

    接口不能实例化,怎么能调用接口的方法呢?原因是使用了代理模式。proxy。

    在mybatis.xml中提前配置好了全路径的package的扫描包,那么直接使用mapper接口类的方法即可。

    文字解释
    1、在 MyBatis 运行开始时需要先通过 Resources 加载全局配置文件;

    2、下面需要实例化 SqlSessionFactoryBuilder 构建器。帮助 SqlSessionFactory 接口实现类 DefaultSqlSessionFactory;

    3、在实例化 DefaultSqlSessionFactory 之前需要先创建 XmlConfigBuilder解析全局配置文件流,并把解析结果存放在 Configuration

    中。之后把Configuratin 传递给 DefaultSqlSessionFactory。到此 SqlSessionFactory 工厂创建成功。

    4、由 SqlSessionFactory 工厂创建 SqlSession.每次创建 SqlSession 时,都需要由 TransactionFactory 创建 Transaction。

    对象,同时还需要创建 SqlSession 的执行器 Excutor,最后实例化DefaultSqlSession,传递给 SqlSession 接口。

    5、根据项目需求使用 SqlSession 接口中的 API 完成具体的事务操作。

    ​ 如果事务执行失败,需要进行 rollback 回滚事务。

    ​ 如果事务执行成功提交给数据库.关闭 SqlSession。

  • 相关阅读:
    【Processing】图像处理框架语言(Hello,Processing!
    微信小程序中自定义模板
    基于SSM花卉商城设计与实现
    【论文阅读】点云地图动态障碍物去除基准 A Dynamic Points Removal Benchmark in Point Cloud Maps
    分布式系统架构理论与组件
    员工犯错,就应该受惩罚吗?
    App测试基础内容
    Linux学习笔记
    如何将图片识别为可编辑的Word文件
    动作捕捉(Motion Capture)文件BVH的解读笔记
  • 原文地址:https://blog.csdn.net/pshdhx/article/details/127840089