/*
*jdbc
*介绍 java database connectivity java数据库连接
*直接通过java语言操作数据库
*是一套标准,由一些接口和类组成
*学习中涉及到的类和接口
*java.sql;
*DriverManager
*Connection Statement PreparedStatement ResultSet
CallableStatement(用于调用存储过程,这个不学)
*javax.sql;
*DataSource 连接池
*驱动:两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,
通过软件可以与该设备进行通信
*操纵数据库
*下载
*创建一个java类
1)加载驱动
Class.forName("com.mysql.jdbc.Driver");
2)创建数据库连接
*DriverManager:是一个驱动管理工具类,可以将其理解为一个容器(vector)
可以管理很多个驱动
*1)两张加载驱动的方式
DriverManager.registerDriver(new Driver());
*加载了两次,载入了两个驱动,还和驱动紧密耦合,依赖于jar包
Class.forName("com.mysql.jdbc.Driver");
*只加载一个驱动即可,降低耦合,不依赖于驱动
*2)Connection con=DriverManager.getConection(String url,String user,String password);
*url作用:就是用于确定使用哪一个驱动.
*DriverManager作用:加载驱动,创建数据库连接
*url:
*主协议:jdbc:
*子协议:mysql://
*主机:localhost:
*端口:3306/
*简写的前提:主机是localhost,端口是3306
*jdbc:mysql:///数据库名
*url后面可以跟参数,比如指定编码方式
*Connection:java.sql下的一个接口,代表一个连接对象,即我们数据库的连接
*作用:
*通过connection获取操作操作sql语句的statement对象
Statement st = con.createStatement();
*可以获取执行预处理的preparedStatement对象
*可以获取执行存储过程的prepareCall()对象
*操作事物
*setAutoCommit(boolean flag):开启事物
*rollback():事物回滚
*commit():事物提交
*Statement:java.sql下的,用于执行静态sql语句
*作用:
*执行sql语句
*DML(insert update delete)
*int executeUpdate()
*通过判断返回值是否非0来确定语句是否执行成功
*DQL(select)
*RusultSet executeQuery()
*execute()可以执行任何sql语句,但是不方便
*批处理操作
*addBatch(sql) 将sql语句添加到批处理
*executeBatch() 批量执行
*clearBatch() 情况批处理
*ResultSet:java.sql中的,用于封装select语句执行后查询的结果
*public boolean next():用于判断是否有下一条记录,从长往下遍历
*true 让游标向下移动一行
*public boolean previous():用于判断是否 有上一条记录,即从下往上滚动
*但是游标默认在第一行上边,所以,要使用previous,必须和absolute配合使用
既先定位,才能使用上一条记录
*public boolean absolute():直接定位到某一条记录
*滚动结果集:
*默认结果集只能向下执行,且只能迭代一次
*要得到滚动结果集,就是在创建statement对象时,不是使用createStatement()
而是使用带参数的createStatement(int,int);
Statement createStatement(int resultSetType,int resultSetConcurrency) throws SQLException
resultSetType - 结果集类型,它是 ResultSet.TYPE_FORWARD_ONLY、ResultSet.TYPE_SCROLL_INSENSITIVE 或 ResultSet.TYPE_SCROLL_SENSITIVE 之一
resultSetConcurrency - 并发类型;它是 ResultSet.CONCUR_READ_ONLY 或 ResultSet.CONCUR_UPDATABLE 之一
第一个参数值
ResultSet.TYPE_FORWARD_ONLY 该常量指示光标只能向前移动的 ResultSet 对象的类型。
ResultSet.TYPE_SCROLL_INSENSITIVE 该常量指示可滚动但通常不受 ResultSet 底层数据更改影响的 ResultSet 对象的类型。
ResultSet.TYPE_SCROLL_SENSITIVE 该常量指示可滚动并且通常受 ResultSet 底层数据更改影响的 ResultSet 对象的类型。
第二个参数值
ResultSet.CONCUR_READ_ONLY 该常量指示不可以更新的 ResultSet 对象的并发模式。
ResultSet.CONCUR_UPDATABLE 该常量指示可以更新的 ResultSet 对象的并发模式。
*以上两个参数有三种搭配方式
*ResultSet.TYPE_FORWARD_ONLY ResultSet.CONCUR_READ_ONLY 默认
*ResultSet.TYPE_SCROLL_INSENSITIVE ResultSet.CONCUR_READ_ONLY
*ResultSet.TYPE_SCROLL_SENSITIVE ResultSet.CONCUR_UPDATABLE
*常用API
next():移动到下一行
previous():移动到前一行
absolute(int row):移动到指定行
beforeFirst():移动resultSet的最前面
afterLast() :移动到resultSet的最后面
updateRow() :更新行数据
*eg:resultSet.updateString("password",'123');
resultSet.updateRow();
必须执行updateRow()才可以执行更新
*public Object getXxx(参数):获取当前游标指向的这条记录中的列数据
*getInt,getString,getDouble,getObject...
*参数可为列的位置或者列的名字
*释放资源:java程序和任何外部设备连接后,都需要关闭资源
*connection必须关闭,如果不关,极易导致系统宕机。
*connection资源尽量晚创建,尽量早释放。
*crud:
*查询:查询全部和条件查询
*修改:
*删除
*添加
*jdbcUtils工具类简单抽取
public class JdbcUtils
{
private static final String DRIVERCLASS;
private static final String URL;
private static final String USERNAME;
private static final String PASSWORD;
static
{
DRIVERCLASS = ResourceBundle.getBundle("jdbc").getString("driverClass");
URL = ResourceBundle.getBundle("jdbc").getString("url");
USERNAME = ResourceBundle.getBundle("jdbc").getString("username");
PASSWORD = ResourceBundle.getBundle("jdbc").getString("password");
}
static
{
try
{
// 将加载驱动操作,放置在静态代码块中.这样就保证了只加载一次.
Class.forName(DRIVERCLASS);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException
{
// 2.获取连接
Connection con = DriverManager.getConnection(URL, USERNAME, PASSWORD);
return con;
}
}
**放在静态代码块是比放在构造函数中更好,因为静态代码块中只执行一次,而且一直存在于内存中
但是如果是在构造函数中,以后新建工具类对象都会再次创建连接,效率会低点
所以,静态代码块是个好东西
*jdbc API
*sql注入
*对于没有对用户输入进行充分的检查,而sql语句又是拼接而成的,
在用户输入参数时,在参数中添加一些sql关键字,达到改变sql语句运行结果的目的
也可以完成恶意攻击
eg:在输入用户名时,输入一些关键字,比如 or ,后面的密码等就不会去沿着改了
就会出现安全问题
*解决:preparedStatement
预处理statement,java.sql.Statement的一个子接口,具有预编译功能
*使用:
*在sql语句中使用?占位
*得到preparedStatement对象,传入sql语句
*为什么要传入sql语句
*因为此处先对sql语句进行预处理,后面传入的参数即使带有关键字,
系统也会将用户名和不小心传入的关键字作为一个整体,不会将其貌似关键字的东西识别成关键字
所以解决了恶意的关键字等东西的sql语句的注入
*占位符赋值:第一个?是位置,从1开始,第二个?是值
*执行sql语句:
*DML:pst.executeUpdate()
*DQL:pst.executeQuery()
这两个方法在执行的时候都不能传递参数,如果传递了,就不会执行预处理操作了
*优点:防止sql注入,可以预编译 ,不用再拼接sql语句了
*DAO:Data Access Object
*/
笔记--jdbc
最新推荐文章于 2024-08-11 14:05:21 发布