为什么会产生Mybatis?
JDBC详解
- 怎么看待数据库驱动。在java的API中只有相应数据库的接口,因为接口可以统一的描述功能,不同的数据库实现可以由不同的数据库厂商来实现即可,JVM其实就是一个进程,与数据库通信的底层其实就是TCP/IP协议的socket编程,但是数据库不同,那么传输的数据格式会不同。但是,他们的操作逻辑一样,需要SQL语句,然后进行编译,然后进行执行SQL语句,数据库客户端进行展示结果。
- 这里阐述了在java中如何去操作其他软件的一个实现,而且这里给我们一个非常重要的思想,注册的思想。
下面是一个典型的JDBC程序:
`public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;try { //加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); //通过驱动管理类获取数据库链接 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "mysql"); //定义sql语句 ?表示占位符 String sql = "select * from user where username = ?"; //获取预处理statement preparedStatement = connection.prepareStatement(sql); //设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值 preparedStatement.setString(1, "王五"); //向数据库发出sql执行查询,查询出结果集, //preparedStatement.execute(sql)注意:executeQuery不要将sql作为参数 resultSet = preparedStatement.executeQuery(); //遍历查询结果集 while(resultSet.next()){ System.out.println(resultSet.getString("id")+" "+resultSet.getString("username")); } } catch (Exception e) { e.printStackTrace(); }finally{ //释放资源 if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(preparedStatement!=null){ try { preparedStatement.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(connection!=null){ try { connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
}
`为什么要使用预编译的preparedStatement?
好处:- 避免sql注入
- 程序代码可读性更强,比使用sql拼接方法要可读!
- 重点:使用预编译,数据库可以减少sql编译的次数,工作原理:
Sql发出到数据库,数据库会进行sql编译,Sql编译后放入数据库缓存
下次请求相同的sql数据库不需要重新编译了,直接从数据库缓存中取出已经编译好,数据库对编译后sql放入缓存,使用占位符的预编译sql数据库会放入缓存,数据库将常用的sql放入缓存。
一般情况下对字符串拼接的sql数据库不进行预编译。
- 对上边jdbc程序问题总结:
- 将sql语句在java类中硬编码,不利于系统维护。
比如:由于需求变更,需要在数据库表中添加字段,要查询该字段的内容,需要修改java类中的sql变量。
设想解决:可以将sql语句抽取出来配置在xml文件,properties文件,如果要修改直接修改配置文件。 - 数据库连接频繁出现创建、关闭,会对数据库资源造成浪费。
设想解决:使用数据库连接池统一管理数据库连接。 - 向statement中设置参数时需要将占位符的位置序号硬编码。
设想解决:可以将参数及占位符号统一配置一下,自动进行参数设置。 - 遍历结果resultSet时,需要手动指定字段的名字,硬编码。如果添加表字段需要遍历,需要修改java代码.
设想解决:自动将select的查询结果集映射成java对象。
- 将sql语句在java类中硬编码,不利于系统维护。