技术帮
 

面试题1

本网站内容基本都是原创作品,未得到作者同意也欢迎转载
转载请注明出处:技术帮
说你呢,赶紧长按二维码,然后点击识别图中二维码

任何技术难题可进QQ群提问:【小崔说编程
对于提问的原则是:没有你不能问的,只有我不会答的

1.Mybatis比IBatis比较大的几个改进是什么

        a.有接口绑定,包括注解绑定sql和xml绑定Sql ,

        b.动态sql由原来的节点配置变成OGNL表达式,

        c. 在一对一,一对多的时候引进了association,在一对多的时候引入了collection

           节点,不过都是在resultMap里面配置



2.什么是MyBatis的接口绑定,有什么好处

        接口映射就是在IBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,

        我们直接调用接口方法就可以,这样比起原来了SqlSession提供的方法我们可以有更加灵活的选择和设置.



3.接口绑定有几种实现方式,分别是怎么实现的?

        接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上

        @Select@Update等注解里面包含Sql语句来绑定,另外一种就是通过xml里面写SQL来绑定,

        在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名.



4.什么情况下用注解绑定,什么情况下用xml绑定

        当Sql语句比较简单时候,用注解绑定,

        当SQL语句比较复杂时候,用xml绑定,一般用xml绑定的比较多



5.MyBatis实现一对一有几种方式?具体怎么操作的

        有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,

        通过在resultMap里面配置association节点配置一对一的类就可以完成;



        嵌套查询是先查一个表,根据这个表里面

        的结果的外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表

        的查询通过select属性配置



6.MyBatis实现一对多有几种方式,怎么操作的

        有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,通过在resultMap里面配

        置collection节点配置一对多的类就可以完成;



        嵌套查询是先查一个表,根据这个表里面的

        结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的

        查询通过select节点配置



7.MyBatis里面的动态Sql是怎么设定的?用什么语法?

        MyBatis里面的动态Sql一般是通过if节点来实现,通过OGNL语法来实现,但是如果要写的完

        整,必须配合where,trim节点,where节点是判断包含节点有内容就插入where,否则不插

        入,trim节点是用来判断如果动态语句是以and 或or开始,那么会自动把这个and或者or取

        掉 



8.IBatis和MyBatis在核心处理类分别叫什么

        IBatis里面的核心处理类交SqlMapClient,

        MyBatis里面的核心处理类叫做SqlSession 



9.IBatis和MyBatis在细节上的不同有哪些

        在sql里面变量命名有原来的#变量# 变成了#{变量}  

        原来的$变量$变成了${变量},

        原来在sql节点里面的class都换名字交type 

        原来的queryForObject queryForList 变成了selectOne selectList  

        原来的别名设置在映射文件里面放在了核心配置文件里



10.讲下MyBatis的缓存

        MyBatis的缓存分为一级缓存和二级缓存,

        一级缓存放在session里面,默认就有,二级缓存放在它的命名空间里,默认是打开的,

        使用二级缓存属性类需要实现Serializable序列化接

        口(可用来保存对象的状态),可在它的映射文件中配置<cache/>



11.MyBatis(IBatis)的好处是什么

        ibatis把sql语句从Java源程序中独立出来,

        放在单独的XML文件中编写,给程序的维护带来了很大便利。

        ibatis封装了底层JDBC API的调用细节,并能自动将结果集转换成Java Bean对象,

        大大简化了Java数据库编程的重复工作。



        因为Ibatis需要程序员自己去编写sql语句,

        程序员可以结合数据库自身的特点灵活控制sql语句,

        因此能够实现比hibernate等全自动orm框架更高的查询效率,能够完成复杂查询。



1、Mybatis基础: #{...} 和 ${...} 的区别

MyBatis将 #{…} 解释为JDBC prepared statement 的一个参数标记。而将 ${…} 解释为字符串替换。理解这两者的区别是很有用的, 因为在某些SQL语句中并不能使用参数标记(parameter markers)。

 

 

比如,我们不能在表名(table name)的位置使用参数标记。

假设有下面的代码:

 

 

Map<String, Object> parms = new HashMap<String, Object>();  
parms.put("table", "foo"); // 表名  
parms.put("criteria", 37); // 查询过滤条件  
List<Object> rows = mapper.generalSelect(parms);

 

 

 

<select id="generalSelect" parameterType="map">  
  select * from ${table} where col1 = #{criteria}  
</select>

 

 

 

MyBatis生成的SQL语句(prepared statement)如下所示:

select * from foo where col1 = ?

 

 

 

重要提示: 请注意,使用$ {…} (字符串替换)时可能会有SQL注入攻击的风险。另外,字符串替换在处理复杂类型也可能常常发生问题,如日期类型。由于这些因素,我们建议您尽可能地使用 #{…} 这种方式。

要使用LIKE语句该怎么写?

 

2、有两种使用LIKE的方法。(推荐使用)第一种方法是,在Java代码中添加SQL通配符。

示例一:

String wildcardName = "%Smi%";  
List<Name> names = mapper.selectLike(wildcardName);

 

 

<select id="selectLike">  
  select * from foo where bar like #{value}  
</select>

 

 

第二种方式是在SQL语句中拼接通配符。这种方法相对来说安全性要低一些,因为可能会被SQL注入攻击。

示例二:

String wildcardName = "Smi";  
List<Name> names = mapper.selectLike(wildcardName);

 

 

<select id="selectLike">  
  select * from foo where bar like '%' || '${value}' || '%'  
</select>

 

 

重要提示: 请注意两种方式中 $ 和 # 的使用!

 

 

3、如何执行批量插入?

 

首先,创建一个简单的insert语句:

<insert id="insertName">  
  insert into names (name) values (#{value})  
</insert>

 

 

然后在Java代码中像下面这样执行批处理插入:

List<String> names = new ArrayList<String>();  
names.add("Fred");  
names.add("Barney");  
names.add("Betty");  
names.add("Wilma");  
  
// 注意这里 ExecutorType.BATCH  
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);  
try {  
  NameMapper mapper = sqlSession.getMapper(NameMapper.class);  
  for (String name : names) {  
    mapper.insertName(name);  
  }  
  sqlSession.commit();  
} finally {  
  sqlSession.close();  
}

 

 

4、如何获取自动生成的(主)键值?

 

insert 方法总是返回一个int值 - 这个值代表的是插入的行数。而自动生成的键值在 insert 方法执行完后可以被设置到传入的参数对象中。

示例:

<insert id="insertName" useGeneratedKeys="true" keyProperty="id">  
  insert into names (name) values (#{name})  
</insert>

 

 

Name name = new Name();  
name.setName("Fred");  
  
int rows = mapper.insertName(name);  
// 完成后,id已经被设置到对象中  
System.out.println("rows inserted = " + rows);  
System.out.println("generated key value = " + name.getId());

 

 

5、在mapper中如何传递多个参数?

 

Java的反射机制并不能让框架获取到参数的名字(方法签名中只有参数类型,可以说是为了优化,也可以说设计就是如此,总之名字无意义), 所以MyBatis默认的命名为: param1,param2……

如果想给他们指定名称,可以使用 @param 注解:

import org.apache.ibatis.annotations.Param;  
public interface UserMapper {  
   User selectUser(@Param("username") String username,   
                   @Param("hashedPassword") String hashedPassword);  
}

 

 

然后,就可以在xml像下面这样使用(推荐封装为一个Map,作为单个参数传递给Mapper):

<select id=”selectUser” resultType=”User”>  
  select id, username, hashedPassword  
  from some_table  
  where username = #{username}  
  and hashedPassword = #{hashedPassword}  
</select>