一,jdbc使用
mybatis是对jdbc的封装,所以先复习下jdbc是如何操作数据库的,以mysql为例。
先上一张图,回忆杀。
再来一段代码,熟悉而又陌生。
@Test
public void showUser(){
//数据库连接
Connection connection = null;
//预编译的Statement,使用预编译的Statement提高数据库性能
PreparedStatement preparedStatement = null;
//结果 集
ResultSet resultSet = null;
try {
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//通过驱动管理类获取数据库链接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis", "root", "");
//定义sql语句 ?表示占位符
String sql = "select * from user where username = ?";
//获取预处理statement
preparedStatement = connection.prepareStatement(sql);
//设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
preparedStatement.setString(1, "王五");
//向数据库发出sql执行查询,查询出结果集
resultSet = preparedStatement.executeQuery();
preparedStatement.setString(1, "张三");
resultSet = preparedStatement.executeQuery();
//遍历查询结果集
while(resultSet.next()){
System.out.println(resultSet.getString("id")+" "+resultSet.getString("username"));
}
resultSet.close();
preparedStatement.close();
System.out.println("#############################");
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源 略去不写
}
}
这里提一个知识点,PrepareStatement和Statement的区别。
PrepareStatement可以开启预编译,同一个sql第一次被编译为一个函数后,函数被缓存起来,之后会被重复调用。
据此,可以问自己几个问题:
1,什么是预编译?
2,预编译由谁完成,PrepareStatement or 数据库 ?
3,预编译的结果有谁保存?
4,如何控制预编译?
参考文献:https://blog.csdn.net/Marvel__Dead/article/details/69486947
二,jdbc的问题
通过上面一波会议,貌似通过jdbc使用mysql也不是那么复杂,mybatis是不是多此一举?
貌似有道理,实则不然。
1,获取Connection的代码是重复代码;
2,sql硬编码在代码中,如果sql长、sql多,代码将惨不忍睹,可维护性差。而sql长、sql多似乎是一个真实项目的标配、常态;
3,设置参数的代码冗余;
4,获取结果的代码冗余;
据研究,相对于毫无封装,mybatis可以减少50%的代码量。
三,mybatis为我们做了哪些工作?
1,简化sql,通过动态sql技术,程序员可以专注于sql核心部分的逻辑,sql生成半自动化;
2,通过xml中的sql标签,sql中的任一部分都可以抽取出来复用;
3,自动从pojo中获取参数;
4,自动将结果封装为制定的pojo;
四,为什么是mybatis?
mybatis和hibernate都是持久层框架,hibernate是完全意义上的orm框架,mybatis是半orm框架。
也就是说,使用hibernate,只需要建表,其他hibernate都帮你搞定。
mybatis干不了这么多,它这能干第三部分讲的那几件事情。
小型项目使用hibernate,开发效率更高。
大型互联网项目呢?
一般都会选择mybatis。
原因在于,sql太重要了,优化sql是一个程序员的基本素养。
但是hibernate把生产sql的任务自己干了,优化sql变成了优化hibernate,简单的事情搞复杂了。
五,手写Mybatis框架