系列文章目录
一、基础面试题
二、Mybatis面试题
文章目录
Mybatis面试题
1、Mybatis和JDBC的区别
1.1 JDBC
Java DataBase Connectivity(Java数据库连接),是一中使用Java程序操作数据库的技术。
是官方定义的一套操作所有关系型数据库的规范(接口)。
也就是JDBC是Java提供的一个操作数据库的API。
1.1.1 使用JDBC的步骤
1、注册驱动
DriverManager.registerDriver(new Driver());
2、创建连接【连接数据库的四大参数:驱动、路径、用户名、密码】
String url = "jdbc:mysql://localhost:3306/day19_db";
String username = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url, username, password);
3、编写SQL语句
String sql = "select * from user where username='柯南' and password='admin'";
4、获取执行SQL语句的对象
Statement stmt = conn.createStatement();
5、发送SQL语句,得到结果
ResultSet rs = stmt.executeQuery(sql);
6、处理结果集
while(rs.next()){
System.out.println("用户名:" + rs.getString("username")+", 密码:" + rs.getString("password") + ", 余额:" + rs.getFloat("balance"));
}
7、释放资源
rs.close();
stmt.close();
conn.close();
1.1.2 注册驱动时的问题
驱动注册了两次
DriverManager.registerDriver(new Driver());
在new Driver()对象时,会先执行Driver类的静态代码块,而静态代码块中,已经注册了驱动,所以,加载Driver类即可完成驱动的注册。
Class.forName("com.mysql.jdbc.Driver");
1.1.3 使用Statement造成SQL注入的问题
用户输入的内容作为SQL语句语法的一部分,改变了原有SQL的结构(意义全变了),这种问题称之为SQL注入!
解决:使用预编译对象,PreparedStatement对象
基本用法:
// SQL语句结构:只不过这个用户名和密码的值不确定!使用占位符?来表示!
// String sql = "select * from user where username='jack' and password='123456'"
String sql = "select * from user where username=? and password=?"
// 1.获得一个预编译SQL语句对象,会绑定指定sql语句的结构!
PreparedStatement pstmt = conn.prepareStatement(sql);
// 2.为占位符赋值!
pstmt.setString(1,username); // 为第1个占位符username赋值!
pstmt.setString(2,password); // 为第2个占位符password赋值!
// 3.执行sql语句时,PreparedStatement调用方法不要带参数sql
ResultSet rs = pstmt.executeQuery();
怎么解决的?
1、sql语句涉及的数据不再使用字符串拼接,而是使用占位符 ?
2、需要传入sql语句,让sql语句的结构与执行sql语句对象绑定
3、给占位符设置值,让预编译对象发送sql
1.1.4 最终的代码流程
1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
2、获得连接
conn = DriverManager.getConnection("jdbc:mysql:///day19_db", "root", "root");
3、编写sql语句
String sql = "insert into user values(null,?,?,?)";
4、获得预编译对象,并给占位符赋值
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "王锋");
pstmt.setString(2, "123456");
pstmt.setFloat(3, 1000);
5、执行sql
int rows = pstmt.executeUpdate();
6、处理结果集
if (rows > 0) {
System.out.println("添加成功!");
}
7、释放资源
1.2 Mybatis
1、优化获取和释放
2、可以把SQL语句放在配置文件中统一进行管理,以后修改配置文件,也不需要重新进行编译部署。
3、可以生成动态SQL语句。
4、能够对结果集进行映射。
在使用JDBC进行查询时,返回一个结果集ResultSet,我们需要从结果集中取出结果封装为需要的类型。
而在Mybatis中我们可以直接将结果映射为我们需要的类型,比如JavaBean对象、一个Map、一个List等等。
2、#{}和${}的区别
2.1 #{}
1、表示占位符,相当于JDBC的?
,底层是PreparedStatement对象,SQL只编译一次,没有SQL注入的问题。
2、当#{}传入的参数是一个简单类型(8中基本类型+String)时,#{}里面可以随便写,但是建议写成接口方法的参数名。
2.2 ${}
1、$ {}表示字符串的拼接,底层使用的Statement对象,每次SQL都会重新编译,并且存在SQL注入问题。
2、当$ {}传入的参数是一个简单类型时,${}里面只能写value。
模糊查询
一般模糊查询使用concat(“%”,#{name},“%”)。
3、PreparedStatement和Statement的区别
3.1 PreparedStatement的预编译
PreparedStatement pstmt = conn.prepareStatement(sql);
创建预编译对象的时候,数据库就已经接收到了这条slq语句
select * from user where username=? and password=?
并且对它进行编译,而预编译对象会引用编译的结果。
这就像是java中已经写好了一个方法,预留了几个参数。
3.2 相同点
都可以用来执行SQL语句
3.3 不同点
1、Statement不安全,不能进行预编译,不能使用占位符,容易造成SQL语句的拼接错误,从而造成SQL注入。
2、PreparedStatement是安全的,可以与编译SQL语句,可以使用占位符,并且批量处理SQL语句效率高。