Mybatis - 常见面试题

1. Mybatis都有哪些Executor执行器?之间的区别为?

有三种基本的执行器:SimpleExecutor ReuseExecutor BatchExecutor

  • SimpleExecutor:每执行一次update、select,就开启一个statement对象,用完立刻关闭
  • ReuseExecutor:执行update,select,以sql作为key查找statement对象,存在就使用,不存在就创建,用完后不关闭statement对象,而是放置在Map<String, statement>中,供下一次使用。
  • BatchExecutor:执行update(批处理不包括select),将所有sql都添加到批处理中,等待统一执行

2. #{ } 和 ${ }

  • #{}:占位符号,可以防止sql注入(替换结果会增加单引号‘’,类型转换),可接收简单类型或pojo属性值。 如果传输单个简单类型值,#{}括号中可以是value或其它名称。
  • ${}:sql拼接符号(在预编译之前已被变量替换了,不会增加单引号‘’,存在sql注入问题), 可以接收简单类型值或pojo属性值,无论传什么类型,{}中只能是value
Select * from emp where name = #{employeeName}  --> Select * from emp where name = 'Smith'; 
Select * from emp where name = ${employeeName} --> Select * from emp where name = Smith;

3. 如何获取表中 auto-increment 自增主键的值?

方式一:增加一个用户并返回主键id

<insert id="saveOne" parameterType="com.buwei.entity.User" >
      INSERT into user(name, password) value(#{name},#{password})
      <selectKey keyProperty="id" order="AFTER" resultType="int">
           select  last_insert_id()
      </selectKey>
</insert>

方式二

<insert id="saveOne" parameterType="com.buwei.entity.User"  useGeneratedKeys="true" keyProperty="id">
     INSERT into user(name, password) value(#{name},#{password})
</insert>

4. 常见的动态标签:8个

  • if 、choose、when、otherwize(后三者组合使用)
  • foreach:遍历查询
  • where:简化where条件判断,能智能的处理 and or ,至少有一个条件符合的时候,才会插入where语句并且会将条件语句前的 and 去掉。
  • trim :对包含的内容加上 prefix 或 suffix 等
  • set :主要用于更新时,update 表名 set 字段名=新值,set标签放入update标签内部,用于动态包含需要更新的列,而舍去其它的。
<select id="selectEmployeeList" resultType="com.worldly.config.entity.Employee">
        select  *  from t_emp e
        <where>
            <if test="name!=null and name!=''">
                and  e.emp_name=#{name,jdbcType=VARCHAR} [and]
            </if>
            <if test="dep!=null">
                and e.emp_dep=#{dep.id,jdbcType=INTEGER}
            </if>
        </where>
  </select>

上例中,若第一个if 为真,则把该 if 中的 and 去掉,若上述红色存在,则出现错误,需要用trim标签

5. SQL注入:

sql注入攻击就是输入参数未经过滤,直接拼接到sql语句中,解析执行,达到预想之外的行为,即执行恶意SQL语句。

  • 可将任意SQL代码插入数据库查询,使攻击者能够完全控制数据库服务器。
  • 可绕过网页或Web应用程序的身份验证和授权,并检索整个SQL数据库的内容;
  • 可使用SQL注入来添加,修改和删除数据库中的记录。

注入实例:
正常情况下,

select * from people where name = '123' and passwd='123';

情况1: 但是如果在用户名框中输入:‘ or 1=1#’,密码随便输入,也可正常登录,如下:

select * from people where name = ' or 1=1#' and passwd='546';
等价于
select * from people where name = ' or 1=1'

#可以注释掉后面的SQL语句

情况2:拼接sql

String sql = "select * from user where username = ' ' and password = ' '";

把pwd传入1’ or ‘1’ = '1,前面的1可以随便填,任意输入密码,都可正确登录。

补:PreparedStatement的参数化防注入:
因为SQL语句在程序运行前已经进行了预编译,在使用参数化查询时,数据库不会将参数的内容视为SQL的一部分来处理,而是在数据库完成SQL指令编译后,才套用参数运行,即使参数里有敏感字符如 or ‘1=1’,数据库会作为一个字段的属性值来处理而不会作为一个SQL指令。

6. Mapper实现2种方式
6.1 传统方式

// 加载配置文件
 Reader reader = Resources.getResourceAsReader("conf.xml");
 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
 SqlSession session = sessionFactory.openSession();

 String statement = "lianxi.personMapper.queryPersonById";
 Person person = session.selectOne(statement, 1);

6.2. Mapper动态代理方式

 Reader reader = Resources.getResourceAsReader("conf.xml");
 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
 SqlSession session = sessionFactory.openSession();
 		
 //动态代理方式:从sqlSession中获取Mapper接口的代理对象
 PersonMapper personMapper = session.getMapper(PersonMapper.class);
 Person person = personMapper.queryPersonById(1);
 session.close();

使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类。动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定。

7. SqlMapConfig.xml配置文件
常用标签:
properties(属性):引用java属性文件中的配置信息

  <!-- 是用resource属性加载外部配置文件 -->
  <properties resource="db.properties">
       <!-- 如果外部配置文件有该属性,则内部定义属性被外部属性覆盖 -->
       <property name="jdbc.username" value="root123" />
  </properties>

typeAliases(类型别名)

 <typeAliases>
   <!-- 单个别名定义 -->
   <typeAlias alias="user" type="cn.itcast.mybatis.pojo.User" />
   <!-- 批量别名定义,扫描整个包下的类,别名为首字母小写的类名(大小写不敏感) -->
   <package name="cn.itcast.mybatis.pojo" />
</typeAliases>

environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)

<!--事务提交方式
	JDBC:利用JDBC方式处理事务(commit rollback close)
	MANAGED:将事务交由其他组件去托管(spring jobss) 默认会关闭连接-->
<transactionManager type="JDBC"/>	

<!--数据源类型 
	UNPOOLED:传统的JDBC模式,每次访问数据库,均需要打开、关闭数据库
	POOLED:使用数据库连接池
	JNDI:从tomcat中获取一个内置的数据库连接池-->
	<dataSource type="POOLED">
			<!-- 配置数据库信息 -->
			<property name="driver" value="${mysqlDriver}"/>
			<property name="url" value="${mysqlURL}"/>
			<property name="username" value="${mysqlUser}"/>
			<property name="password" value="${mysqlPaw}"/>
	    </dataSource>

mappers(映射器)

  <mappers>
  	<!-- 加载映射文件 -->
	<!-- <mapper resource="org/mapper/personMapper.xml"/> -->
  </mappers>

注: MyBatis通过工厂模式来创造数据源DataSource,定义了抽象的工厂接口DataSourceFactory接口,通过getDataSource()方法返回数据源。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值