文章目录
1.驱动类加载
装载MySQL驱动:
Class.forName(“com.mysql.jdbc.Driver”);
需要搭配try, catch (ClassNotFoundException e)
try {
Class.forName("com.mysql.jdbc.Driver");
}catch (ClassNotFoundException e){
System.out.println(e);
}
2.Connection接口
Connection与特定数据库的连接会话。
需要搭配try, catch (SQLException e)
Connection con = DriverManager.getConnection("jdbc:mysql://host:port/database","user","password")
host是主机IP。port是端口,为3306。database为即将要连的数据库。user为用户名。password为密码。
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc","root","123456");
连接对象内部包含了Socket对象,是一i个远程连接,比较耗时~这是Connection管理的一个要点!
真正开发中,为了提高效率,都会使用连接池来管理连接对象。
3.Statement接口
用于执行静态SQL语句并返回它所生成结果的对象。用于发送简单的SQL语句(不带参数)。
常用方法:
execute() :运行SQL所有语句,返回是否有结果集,是boolean类型。
executeQuery () : 运行select语句,返回ResultSet结果集。
executeUpdate() :运行insert/update/delete操作,返回更新的行数。
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc","root","123456");
Statement sta = con.createStatement(); //获得Statement连接
String sql ="insert into t_user(username,pwd,regTime) values('赵六',666,now())"; //插入操作
sta.execute(sql);
传入参数:(较麻烦)
Statement sta = con.createStatement(); //获得Statement连接
String name = "参数"; //直接复制或传入参数,则下面的SQL语句需要使用拼字符串
String sql ="insert into t_user(username,pwd,regTime) values('"+name+"',666,now())";
sta.execute(sql);
会发生SQL注入:(缺点)
String id = "5 or 1=1"; //可传入参数
String sql = "delete from t_user where id="+id; //将删除所有记录
sta.execute(sql);
这样子用户就可以随意修改数据库,有巨大的漏洞。
因此Statement不常用。
4.PreparedSratement
继承Statement。
String sql = "insert into t_user(username,pwd) values(?,?)"; //?是占位符
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1,"赵无"); //1代表第一个问号。参数索引从1开始,而不是0
ps.setString(2,"123");
ps.execute();
如果不想理会传入参数的类型,可使用setObject()。
ps.setObject(1,"赵无");
ps.setObject(2,"123");
5.ResultSet
ResultSet与executeQuery搭配使用。
String sql = "select id,username,pwd from t_user where id>?"; //?是占位符
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1,2); //设置id为大于2
ResultSet rs = ps.executeQuery(); //executeQuery () : 运行select语句,返回ResultSet结果集
while(rs.next()){ //1代表第一列,即id。2代表第2列,即username......
System.out.println(rs.getInt(1)+"---"+rs.getString(2)+"---"+rs.getString(3));
}
6.关闭连接
Connection,Statement,ResultSet建立连接后需要关闭。
关闭顺序是后建立的连接先关闭。即ResultSet–>Statement–>Connection。
一般都是在finally里关闭连接
finally {
try {
if(rs!=null){ //rs为ResultSet
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(ps!=null){ //ps为PreparedStatement
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(con!=null){ //con为Connection
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
7.批处理
建议使用Statement。因为PrepareStatement预编译空间有限,当数量特别大时,会发生异常。
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc","root","123456");
con.setAutoCommit(false); //事务设为手动提交
Statement sta=con.createStatement();
for(int i=0;i<20000;i++){
sta.addBatch("insert into t_user(username,pwd,regTime) values ('gao"+i+"',6666,now())");
} //将处理添加进Batch
sta.executeBatch(); //执行批处理
con.commit(); //提交事务
8.时间类型
java.sql.Date 表示年月日
java.sql.Time 表示时分秒
java.sql.Timestamp 表示年月日时分秒
//java.sql.Date
//java.sql.Time
java.sql.Timestamp tsp = new java.sql.Timestamp(System.currentTimeMillis()); //当前时间,年月日时分秒
sta.setTimestamp(3,tsp);
2.对日期查询
public static long str2Data(String dataStr){ //需要对年月日时分秒的格式转换为long int类型的方法
DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
try {
long time = format.parse(dataStr).getTime();
return time;
}catch(ParseException e){
e.printStackTrace();
return 0;
}
}
public static void main(String[] arg) throws SQLException {
Connection con= null;
PreparedStatement sta = null;
try {
//加载驱动类
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc","root","123456");
sta=con.prepareStatement("select * from t_user where regTime>? and regTime<?");
java.sql.Timestamp start = new java.sql.Timestamp(str2Data("2019-10-8 20:10:10"));
java.sql.Timestamp end = new java.sql.Timestamp(str2Data("2019-10-9 20:10:10"));
sta.setObject(1,start);
sta.setObject(2,end);
ResultSet rs = sta.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("id")+"---"+rs.getTimestamp("regTime"));
}
}
}
9.Clob大文本对象
用于存储大量的文本数据。操作常常以流的方式来处理。
Mysql相关数据类型:
tinytext
text
mediumtext
longtext
sta=con.prepareStatement("insert into t_user(username,myinfo) values (?,?)");
sta.setObject(1,"欧阳");
sta.setClob(2,new FileReader(new File("D:/a.txt"))); //setClob(哪个占位符,Reader)
sta.executeUpdate();
读取Clob内的字符串:
sta=con.prepareStatement("select * from t_user where id=?");
sta.setObject(1,20017);
ResultSet rs = sta.executeQuery();
while(rs.next()){
Clob c = rs.getClob("myinfo"); //Clob类型需要使用getClob("数据库内的名称")
Reader r = c.getCharacterStream(); //读取Clob的字符串需要用流操作
int tmp = 0;
while((tmp=r.read())!=-1){ //输出流,当为-1时为到结尾。 Reader用完应该关闭
System.out.print((char)tmp);
}
}
10.Blob二进制大对象
用于存储大量的二进制数据。操作常常以流的方式来处理。
Mysql相关数据类型:
tinyblob
blob
mediumblob
longblob
sta=con.prepareStatement("insert into t_user(username,head) values (?,?)");
sta.setObject(1,"弟弟");
sta.setBlob(2,new FileInputStream("C:/Users/***/Desktop/403664807447118555.jpg")); //输入一个图像
sta.execute();
读取Blob内的二进制:
sta=con.prepareStatement("select * from t_user where id=?");
sta.setObject(1,20018);
ResultSet rs = sta.executeQuery();
while(rs.next()){
Blob c = rs.getBlob("head");
InputStream is = c.getBinaryStream();
int tmp = 0;
while((tmp=is.read())!=-1){
System.out.print(tmp);
}
}