jdbc (Java Data Base Connectivity)
它是由一组用Java语言编写的类和接口组成。是Java访问数据库的标准规范,而生产厂商提供规范的实现类称为驱动。JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。
-----------------------------------------
JDBC原理
Java提供访问数据库的规范称为JDBC,而生产厂商提供规范的实现类称为驱动。
JDBC是接口,驱动是接口的实现,所以没有驱动是无法数据库连接和操作数据库!每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动都是由数据库生成厂商提供。
-----------------------------------------
已Mysql为例,首先引入mysql的驱动包
1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
只要让Driver类加载起来,她就会自己注册驱动了,为什么会这样呢?看看她的源码就知道了↓
public class Driver extends NonRegisteringDriver implements java.sql.Driver { static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } …… }
静态块?是的,没错。
-----------------------------------------
2.获得Connection
获取Connection需要方法 DriverManager.getConnection(url,username,password),三个参数分别为:url 网址,数据库的用户名 ,数据库的密码。
url比较复杂,下面是mysql的url:
JDBC规定url的格式由三部分组成,每个部分中间使用冒号分隔。
第一部分是jdbc,这是固定的;
第二部分是数据库名称,那么连接mysql数据库,第二部分当然是mysql了;
第三部分是由数据库厂商规定的,我们需要了解每个数据库厂商的要求,mysql的第三部分分别由数据库服务器的IP地址(localhost)、端口号(3306),以及DATABASE名称(mydb)组成。
Connection con = DriverManager.getConnection(“jdbc:mysql://localhost:3306/mydb”,”root”,”root”);-----------------------------------------
3.获得操作对象,对数据库进行操作
String sql = "SQL语句";
获取Statement语句执行平台:Statement st = con.createStatement();
st.executeUpdate(String sql); 执行insert update delete语句.返回值int类型,影响行数
executeQuery(String sql); --执行select语句.返回ResultSet
execute(String sql); --执行select返回true 执行其他的语句返回false.
ResultSet简单的理解就是一张表格,我们可以调用其boolean next()方法指向某行记录,当第一次调用next()方法时,便指向第一行记录的位置,这时就可以使用ResultSet提供的getXXX(int col)方法(与索引从0开始不同个,列从1开始)来获取指定列的数据:
Object getObject(int index) / Object getObject(String name) 获得任意对象
String getString(int index) / Object getObject(String name) 获得字符串
int getInt(int index) / Object getObject(String name) 获得整形
double getDouble(int index) / Object getObject(String name) 获得双精度浮点型
-----------------------------------------
4.释放资源
rs.close();
st.close();
con.close();
-----------------------------------------
SQL注入问题
假设有登录案例SQL语句如下:
SELECT * FROM 用户表 WHERE NAME = 用户输入的用户名 AND PASSWORD = 用户输的密码;
此时,当用户输入正确的账号与密码后,查询到了信息则让用户登录。但是当用户输入的账号为XXX 密码为:XXX’ OR ‘1’='1时,则真正执行的代码变为:
SELECT * FROM 用户表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’ OR ’1'='1’;
此时,上述查询语句时永远可以查询出结果的。那么用户就直接登录成功了,显然我们不希望看到这样的结果,这便是SQL注入问题。
为此,我们使用PreparedStatement来解决对应的问题。
PreparedStatement 预处理可以防止SQL注入哦,用法↓
String sql = "SELECT * FROM WHERE NAME =? AND PASSWORD = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString( 1 ,"root");//参数设置到sql语句的第一个问号上去 ps.setString( 2 ,"root");//参数设置到sql语句的第一个问号上去执行SQL语句:
executeUpdate(); --执行insert update delete语句.
executeQuery(); --执行select语句.
execute(); --执行select返回true 执行其他的语句返回false.
-----------------------------------------
自己制作一个JDBC工具类
使用properties配置文件,在开发中获得连接的4个参数(驱动、URL、用户名、密码)通常都存在配置文件中,方便后期维护,程序如果需要更换数据库,只需要修改配置文件即可。
properties的编辑需要注意一下几点:
1.文件后缀名为properties
2.文件内容:一行一组数据,格式“key=value”
3.value值不支持中文,如果需要使用非英文字符,将进行unicode转换。
例如properties内容:
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mydb user=root password=root自制JDBC工具类的代码如下:
public class JDBCUtils { private static String driver; private static String url; private static String user; private static String password; // 静态代码块 static { try { // 1 使用Properties处理流 // 使用load()方法加载指定的流 Properties props = new Properties(); Reader is = new FileReader("配置文件的路径+文件名"); props.load(is); // 2 使用getProperty(key),通过key获得需要的值, driver = props.getProperty("driver"); url = props.getProperty("url"); user = props.getProperty("user"); password = props.getProperty("password"); } catch (Exception e) { throw new RuntimeException(e); } } // 获得连接 public static Connection getConnection() { try { // 1 注册驱动 Class.forName(driver); // 2 获得连接 Connection conn = DriverManager.getConnection(url, user, password); return conn; } catch (Exception e) { throw new RuntimeException(e); } } }