原生mybatis使用细节回顾

mybatis笔记

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

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

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

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

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

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

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

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

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

2、CDATA关系运算符

<![CDATA[ select * from people where id < #{id} ]]>

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>

配置了别名,即可在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操作

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>

8、ThreadLocal

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

final ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set("测试");
String result = threadLocal.get();

该对象要么是全局的,要么是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);
	}
}

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

<web-app>
	<filter>
    	<filter-name>opensession</filter-name>
        <filter-class>com.pshdhx.filter.OpenSessionInView</filter-class>
    </filter>
    <filter-mapping>
    	<filter-name>opensession</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
@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
		
	}

}

9、mybatis缓存

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

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

缓存的是一个statement对象。

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

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>

包含多个对象 使用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>

辅表联查主表,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>

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

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

11、关于mybatis中代码解读

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

接口不能实例化,怎么能调用接口的方法呢?原因是使用了代理模式。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。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值