JDBC
JDBC
jdbc的目标是使java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统
Java应用程序——>JDBC API——>JDBC驱动程序——>数据库

Java.sql.Driver接口是所有JDBC驱动程序需要实现的接口。
》这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现
》在程序中不需要直接访问实现了Driver接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用这些Driver实现
数据库厂商必须实现的接口,能从中获取数据库的连接
/** * JDBC URL * jdbc:mysql://localhost:3306/test * * 对于oracle数据库连接: * jdbc:oracle:thin:@localhost:1521:sid * * 对于SQLserver数据库连接: * jdbc:miscrosoft:sqlserver//localhost:1433;DatabaseName=sid * * 对于MYSQL数据库连接: * jdbc:mysql://localhost:3306/sid */
连接数据库的步骤:
1、注册驱动(只做一次)
2、建立连接(Connection)
3、创建执行SQL的语句(Statment)
4、执行语句
5、处理执行结果(ResultSet)
6、释放资源
DriverManager 是驱动的管理类
1)可以通过重载的getConnection()方法获取数据库连接,较为方便
2)可以同时管理多个驱动程序:若注册多个数据库连接,则调用getConnection()方法时传入的参数不同,即返回不同的数据库连接
String driverClass = "oracle.jdbc.OracleDriver"; String url = "jdbc:oracle:thin:@localhost:1521:orcl"; String user = "scott"; String password = "123456"; //加载数据库驱动程序(对应的Driver实现类中有注册驱动的静态代码块) //DriverManager.registerDriver((Driver) Class.forName(driverClass).newInstance()); Class.forName(driverClass); Connection conn = DriverManager.getConnection(url, user, password); System.out.println(conn);
通过配置文件jdbc.properties获取数据库连接
String driverClass = "oracle.jdbc.OracleDriver";
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String user = "scott";
String password = "123456";
//读取配置文件信息
InputStream is = getClass().getClassLoader().getResourceAsStream("jdbc.properties");
Properties pro = new Properties();
//将读取的配置文件信息传入pro
pro.load(is);
//根据值进行查询赋值
driverClass = pro.getProperty("driverClass");
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
//创建一个驱动对象 Class.forName() 加载数据库驱动
Driver driver = (Driver) Class.forName(driverClass).newInstance();
Properties info = new Properties();
info.put("user",user);
info.put("password",password);
//通过driverManager的getConnection()方法获取连接
Connection conn = DriverManager.getConnection(url, info);
return conn;
*增、删、改用Statement.executeUpdate来完成,返回整数(匹配的记录数),这类操作相当简单。
*查询用Statement.executeQuery来完成,返回的是ResultSet对象,ResultSet中包含了查询的结果。
创建与数据库的连接的标准方式是在
DriverManager上调用方法getConnection().
statement(语句对象)
》executeUpdate(String sql):
执行SQL insert,update或delete语句,返回受影响的行的数目或零;返回值为int型
》executeQuery(String sql)
执行返回单个ResultSet的SQL语句;返回类型ResultSet
》execute(String sql)
执行可以返回多个结果的SQL语句。返回类型boolean,如果返回的是更新的数目,则返回false,如果返回ResultSet,则返回true。(不常用)
//1.获取数据库连接 Connection conn = getConnection(); //2.准备插入的sql语句 String sql = "insert into student values(3,'123','123')"; //3.执行插入 //(1)获取操作与SQL语句的Statement对象 Statement state = conn.createStatement(); //(2)调用Statement对象的executeUpdate(sql)执行SQL语句进行插入 int result = state.executeUpdate(sql); System.out.println(result); //4.关闭Statement对象 state.close(); //5.关闭连接 conn.close();
PreparedStatement
* 使用PreparedStatement
* 1)why?
①使用statement需要进行拼写SQL语句。很辛苦,而且容易出错。
②可以有效地禁止SQL注入。
——SQL诸如是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入,数据中注入非法的SQL语句段
——对于Java而言,要规范SQL注入,只要用PreparedStatement取代Statement就可以了。
SQL注入
String username = "a' OR PASSWORD = "; String password = "OR '1' = '1"; String sql = "SELECT * FROM USERS WHERE USERNAME = '" + username + "' AND " + "PASSWORD = '" + password + "'"; } select * from users where username = 'a' or password = 'and password = ' or '1' = '1'
《3》PreparedStatement能最大可能提高性能
* 2)PreparedStatement:是Statement的子接口,可以传入带占位符的SQL语句,而且
* 提供了补充占位符变量的方法。
*
* 使用PreparedStatement
* ①创建PreparedStatement:
* String sql = "INSERT INTO STUDENT VALUES(?,?,?,?,?)"
* PreparedStatement ps = conn.prepareStatement(sql);
*
* ②调用PreparedStatement的setXxx(int index,Object val)设置占位符的值。
* index值从1开始
*
* 3执行SQL语句:executeQuery()或executeUpdate().注意:执行时不再需要传入SQL语句
@Test
public void test2(){
Connection conn = null;
PreparedStatement preparedStatement = null;
try {
conn = getConnection();
String sql = "insert into examstudent values(?,?,?,?,?,?,?)";
preparedStatement = conn.prepareStatement(sql);
preparedStatement.setInt(1,11);
preparedStatement.setInt(2, 2);
preparedStatement.setString(3, "43121223113");
preparedStatement.setString(4,"1245523");
preparedStatement.setString(5,"yhs");
preparedStatement.setString(6,"dwd");
preparedStatement.setInt(7,3);
int re = preparedStatement.executeUpdate();
if(re ==1){
System.out.println("插入成功!!!");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
release(preparedStatement, conn, null);
}
}
ResultSet
结果集读取数据的方法主要是getXXX(),他的参数可以使整数表示第几列(从1开始的),还可以是列名。
返回的是对应的XXX类型的值。如果对应那列时空值,XXX是对象的话返回XXX型的空值,如果XXX是数字类型,如Float等返回0,boolean返回false
结果集,封装了使用JDBC进行查询的结果
1.调用Statement对象的executeQuery(sql)可以得到结果集
2.ResultSet返回的实际上就是一张数据表,有一个指针指向数据表的第一行的前面
可以使用next()方法检测下一行是否有效,若有效该方式返回true,且指针下移。
相当于Iterator对象的hasNext()和next()方法的结合体
3.当指针对位到一行时,可以通过getXxx(index)或getXxx(columnName)
获取每一列的值,例如:getInt(1),getString("name")
4.ResultSet:当然也需要进行关闭
单条数据查询:
Connection conn = getConnection();
Statement state = conn.createStatement();
String sql = "select * from student where id=1";
ResultSet rs = state.executeQuery(sql);
if(rs.next()){
int id = rs.getInt(1);
String name = rs.getString("name");
String password = rs.getString("password");
System.out.println(id);
System.out.println(name);
System.out.println(password);
}
conn.close();
state.close();
rs.close();
多条数据查询:
Connection conn = getConnection();
Statement state = conn.createStatement();
String sql = "select * from student";
ResultSet rs = state.executeQuery(sql);
while(rs.next()){
int id = rs.getInt(1);
String name = rs.getString("name");
String password = rs.getString("password");
System.out.print(id + " ");
System.out.print(name + " ");
System.out.println(password);
}
conn.close();
state.close();
rs.close();
封装查询多个对象的方法:
ResultSetMetaData:(解决红色部分)接口
1)what:是描述ResultSet的元数据对象,即从中可以获取到结果集有多少列,列名是什么....
2) how:
<1>得到ResultSetMetaData 对象:调用ResultSet的getMetaData()方法
<2>ResultSetMetaData有哪些好用的方法
>int getColumnCount(): SQL语句包含哪些列
>String getColumnLabel(int column):获取指定的列的别名,其中索引从1开始。
获取结果集每一列的别名
for(int i=0;i<rsmd.getColumnCount();i++){
String columnLabel = rsmd.getColumnLabel(i+1);
}


public <T> T testResultSetMetaData(Class<T> clazz,String sql,Object...args){
Connection conn = null;
PreparedStatement preparedstatement = null;
ResultSet resultset = null;
T entity = null;
try {
conn = getConnection();
preparedstatement = conn.prepareStatement(sql);
//对sql占位符进行赋值
for(int i=0;i<args.length;i++){
preparedstatement.setObject(i+1,args[i]);
}
resultset = preparedstatement.executeQuery();
ResultSetMetaData metaData = resultset.getMetaData();
Map<String,Object> map = new HashMap<String,Object>();
while(resultset.next()){
for(int i=0;i<metaData.getColumnCount();i++){
String columnLabel = metaData.getColumnLabel(i+1);
Object obj = resultset.getObject(i+1);
map.put(columnLabel, obj);
System.out.println(columnLabel + " " +obj);
}
}
if(map.size()>0){
entity = clazz.newInstance();
//遍历Map对象,利用反射为Class对象对应的属性赋值
for(Map.Entry<String, Object> entry : map.entrySet()){
String fieldName = entry.getKey();
Object value = entry.getValue();
BeanUtil
}
}
} catch (Exception e) {
// TODO: handle exception
}finally{
release(preparedstatement, conn, resultset);
}
return null;
}

浙公网安备 33010602011771号