MyBatis
一,JDBC
1.什么是JDBC
Java DataBase connectivity (Java语言连接数据库)
2.JDBC本质
JDBc是sUN公司制定的一套接口(interface)接口都有调用者和实现者。
面向接口调用、面向接口写实现类,这都属于面向接口编程。
建议:
nimal a = new cat() ;
Animal a = new Dog()
Public voia feea ()
不建议:
Dog d = new Dog ( ;cat c = new cati ) ;
3.JDBc编程六步(需要背会)
第一步:注册驱动
第二步:获取连接
第三步:获取数据库操作对象(专门执行sql语句的对象)
第四步:执行Sql语句(这里执行查询语句方法和其他不一样)
- 查询操作(sql="select 查询信息 from 表名 [where 查询条件] ")
//4.创建sql语句
String sql="select * from user";
//5.执行SQL语句
ResultSet rs=stmt.executeQuery(sql);
- 添加操作(sql="insert into 表名[(属性1,属性二] values(属性1值,属性二值) ")
//5.执行SQL语句
ResultSet rs=stmt.executeUpdate(sql)
- 删除操作(sql="delete from 表名 [where 删除条件] )
//5.执行SQL语句
ResultSet rs=stmt.executeUpdate(sql)
- 修改操作(sql=“update 表名 set 修改属性=修改属性的值 [where 修改条件]” )
//5.执行SQL语句
ResultSet rs=stmt.executeUpdate(sql)
第五步:处理查询结果集
第六步:释放资源
4.JDBC实例操作
前提工作:
1)启动mysql服务
2)在数据库软件中建立数据库连接,并且创建表格,例如user表
3)在表格中写入两三条数据
4.1 JDBC实例操作(方法一)
package com;
import java.sql.*;
public class Jdbc_1 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
//1.注册驱动
//String driver="com.mysql.jdbc.Driver";
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String ur1 ="jdbc:mysql://localhost:3306/jdbc";
String user ="root";
String password = "root" ;
conn=DriverManager.getConnection(ur1,user,password);
//3.获取操作对象
stmt=conn.createStatement();
//4.创建sql语句
String sql="select * from user ";
//5.执行SQL语句
ResultSet rs=stmt.executeQuery(sql);
while (rs.next()){
String na=rs.getString("name");
String pas=rs.getString("password");
System.out.println("name:"+na+" passsword:"+pas);
}
}catch (Exception e){
e.printStackTrace();
} finally {
//6.释放资源
try {
if(stmt!=null){
stmt.close();
}
}catch (SQLException e){
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
}catch (SQLException e){
e.printStackTrace();
}
}
}
}
4.2 JDBC实例操作 Statement(方法二)【- - -重点使用- - -】
从属性资源文件中读取数据库连接操作
- 创建资源文件,例如jdbc.properties文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
user=root
password=root
- 执行代码块
package com;
import java.sql.*;
import java.util.ResourceBundle;
/*
使用资源文件jdbc.properties
方法一 Statement
*/
public class Jdbc_2 {
public static void main(String[] args) {
//使用资源绑定器绑定属性配置文件
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
//获取数据
String driver=bundle.getString ( "driver" ) ;
String ur1 = bundle.getString ( "url");
String user = bundle.getString ( "user" );
String password = bundle.getString ( "password") ;
Connection conn = null;
Statement stmt = null;
try {
//1.注册驱动
Class.forName(driver);
//2.获取连接
conn= DriverManager.getConnection(ur1,user,password);
//3.获取操作对象
stmt=conn.createStatement();
//4.创建sql语句
String sql="select * from user";
//5.执行SQL语句
ResultSet rs=stmt.executeQuery(sql);
while (rs.next()){
String na=rs.getString("name");
String pas=rs.getString("password");
System.out.println("name:"+na+" passsword:"+pas);
}
}catch (Exception e){
e.printStackTrace();
} finally {
//6.释放资源
try {
if(stmt!=null){
stmt.close();
}
}catch (SQLException e){
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
}catch (SQLException e){
e.printStackTrace();
}
}
}
}
4.3 JDBC实例操作 PreparedStatement(方法三)【- - -重点使用- - -】
-
当前程序存在的问题?:
用户名:fdsa
密码:fdsa’ or ‘1’='1登录成功
这种现象被称为SQL注入(安全隐患)。(黑客经常使用) -
导致sql注入的根本原因是什么?
用户输入的信息中含有sql语句的关键字,并且这些关键字参与sql语句的编译过程,导致sql语句的原意被扭曲,进而达到sq1注入。 -
解决sol注入的关键是什么?
用户提供的信息中即使含有sql语句的关键字,但是这些关键字并没有参与编译。不起作用。
使用 PreparedStatement()方法预编译
创建资源文件,例如jdbc.properties文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
user=root
password=root
执行代码块
package com;
import javax.annotation.Resource;
import java.sql.*;
import java.util.ResourceBundle;
/*
使用资源文件jdbc.properties
方法二 PreparedStatement
*/
public class Jdbc_3 {
public static void main(String[] args) {
//使用资源绑定器绑定属性配置文件
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
//获取数据
String driver=bundle.getString ( "driver" ) ;
String ur1 = bundle.getString ( "url");
String user = bundle.getString ( "user" );
String password = bundle.getString ( "password") ;
Connection conn = null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
//1.注册驱动
Class.forName(driver);
//2.获取连接
conn= DriverManager.getConnection(ur1,user,password);
//3.创建sql语句
String sql="select * from user where name=? ";
//4.对sql语句预编译处理
ps=conn.prepareStatement(sql);
//赋值(第一个问号下标是1,其他的同理)
ps.setString(1,"a");
//5.执行SQL语句
rs=ps.executeQuery();
//输出结果集合
while (rs.next()){
String na=rs.getString("name");
String pas=rs.getString("password");
System.out.println("name:"+na+" passsword:"+pas);
}
}catch (Exception e){
e.printStackTrace();
} finally {
//6.释放资源
try {
if(rs!=null){
rs.close();
}
}catch (SQLException e){
e.printStackTrace();
}
try {
if(ps!=null){
ps.close();
}
}catch (SQLException e){
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
}catch (SQLException e){
e.printStackTrace();
}
}
}
}
4.4 对比一下statement和Prepa redstatement?
-
PreparedStatement效率较高一些。
-
Preparedstatement会在编译阶段做类型的安全检查。
-
Preparedstatement使用限制较大,适合一些常规操作,比如查询学生成绩信息从大到小排列就不行
-
Statement存在sql注入问题,Preparedstatement解决了sql注入问题。
-
Statement是编译一次执行一次。PreperedStatement是编译一次,可执行x次。
5.JDBC事物机制
- JDBc中的事务是自动提交的,什么是自动提交?
只要执行任意一条DML语句,则自动提交一次。这是JDBC默认的事务行为。但是在实际的业务当中,通常都是N条DML语句共同联合才能完成的,必须保证他们这些DML语句在同一个事务中同时成功或者同时失败。 - 将JDBC的自动提交机制改为手动提交
- a.开启事物
conn.setAutoCommit(false); - b.提交事物
conn.commit(); - c.回滚事物
conn.rollback();
- a.开启事物
实例一:还是在两次操作之间添加一个异常,阻止了第二次的操作,虽然第一次操作看起来是可以执行,但是由于将两次操作放在一个事物行为中,只能同时成功或者同时失败。
/*
这里人工添加制作一个异常,
*/
String s=null;
s.toString();
- 这里人工添加制作一个异常删除掉,不要异常,两次操作将会全部成功
- 必须两次操作都能成功运行,才能都成功(两个操作捆绑在一起的),否则失败
import java.sql.*;
import java.util.ResourceBundle;
public class Jdbc_4 {
public static void main(String[] args) {
//使用资源绑定器绑定属性配置文件
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
//获取数据
String driver=bundle.getString ( "driver" ) ;
String ur1 = bundle.getString ( "url");
String user = bundle.getString ( "user" );
String password = bundle.getString ( "password") ;
Connection conn = null;
PreparedStatement ps=null;
try {
//1.注册驱动
Class.forName(driver);
//2.获取连接
conn= DriverManager.getConnection(ur1,user,password);
//将JDBC的自动提交机制改为手动提交
conn.setAutoCommit(false);//a.开启事物
//3.创建sql语句
String sql="update user set password=? where name=? ";
//4.对sql语句预编译处理
ps=conn.prepareStatement(sql);
//执行第一次
//赋值(第一个问号下标是1,其他的同理)
ps.setString(1,"111");
ps.setString(2,"a");
//5.执行SQL语句
//int rs=ps.executeUpdate();
ps.executeUpdate();
/*
这里人工添加制作一个异常,
*/
String s=null;
s.toString();
//执行第二次
//赋值(第一个问号下标是1,其他的同理)
ps.setString(1,"222");
ps.setString(2,"b");
//5.执行SQL语句
ps.executeUpdate();
//如果程序执行到这里,说明以上程序没有异常,事物结束,手动提交数据
//b.提交事物
conn.commit();
}catch (Exception e){
//c.回滚事物,遇到异常跳过
try {
conn.rollback();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
e.printStackTrace();
} finally {
//6.释放资源
try {
if(ps!=null){
ps.close();
}
}catch (SQLException e){
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
}catch (SQLException e){
e.printStackTrace();
}
}
}