这里补一下,java连接到数据库的模板。
有四个步骤:1.加载连接器
2.声明连接哪台主机的数据库,同时指定编码
3.建立连接
4.对数据库中的内容进行操作
DBHelloWorld.java
package cn.hncu;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
//import com.mysql.jdbc.Driver; Driver类补全即可得到完成类名,用于下面的类反射
public class DBHelloWorld {
public static void main(String[] args) throws Exception {
//1.加载连接器
Class.forName("com.mysql.jdbc.Driver");//驱动
//2.声明连接哪台主机的数据库,同时指定编码
String url="jdbc:mysql://127.0.0.1:3306/abc?useUnicode=true&characterEncoding=utf-8";
//3.建立连接
Connection con= DriverManager .getConnection(url, "hncu", "1234");
//4.对数据库中的内容进行操作
Statement st=con.createStatement();//创建语句对象Statement
String sql="insert into stud values(13,'Eclipse',60,91.2);";//增
//sql="update stud set sname='MyEclipse' where sid=13";改
//sql="delete from stud where sid=13";//删
//boolean boo=st.execute(sql);
//System.out.println(boo);
//查询
sql="select * from stud;";
ResultSet rs=st.executeQuery(sql);
while(rs.next()){//第一个在数据项之上,要移下来一个。表示下一项是不是数据项,若不是则返回false
int id=rs.getInt("sid");
int id2=rs.getInt(1);//两种方法都行,一个用字段名,一个用字段序号(从1开始)
String name=rs.getString(2);
int age=rs.getInt("sage");
double score=rs.getDouble(4);
System.out.println("id="+id+",id2="+id2+",name="+name+",age="+age+",score="+score);
}
}
}
为了以后写代码的简洁性,和减少内存开销这里对连接数据库做了工厂类,模仿Hibernate做了配置文件
jdbc.properties
MySQL
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8
username=hncu
password=1234
##Oracle
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
#username=scott
#password=tiger
ConnFactory.java
package cn.hncu.pubs;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
public class ConnFactory {
private static Connection con;
private ConnFactory(){
}
static{
//为了确保每次拿的connection都一样,采用单例
try {
Properties p=new Properties();//放在src目录下 p.load(ConnFactory.class.getClassLoader().getResourceAsStream("jdbc.properties"));//读取classpath下的资源文件
String driver=p.getProperty("driver");
String url=p.getProperty("url");
String username=p.getProperty("username");
String password=p.getProperty("password");
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConn(){
return con;
}
}
JdbcDemo.java
package cn.hncu;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
import java.util.UUID;
import org.junit.Test;
import org.junit.runners.ParentRunner;
import cn.hncu.pubs.ConnFactory;
public class JdbcDemo {
//查
@Test
public void readDemo(){
Connection con=null;
try {
Class.forName("com.mysql.jdbc.Driver");//驱动----jdbc4.0开始可省略
//hibernate框架不能省
String url="jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8";//建数据库的时候指定编码,java连接的时候也指定编码,两者一致,只要不是mysql故意改动编码,都不会乱码
con=DriverManager.getConnection(url,"hncu","1234");
Statement st=con.createStatement();
ResultSet rs=st.executeQuery("select * from person2");//该方法专用于查询
while(rs.next()){
Object id0=rs.getObject("id");//若不知字段类型是什么,可用Object类型去接
String id=rs.getString(1);
String name=rs.getString("name");
String sex=rs.getString(3);
/*
* 为考虑兼容性,数据库中男女用字符0或1表示,到java中进行读取时,
* 再来修补不足,提高了数据库的可移植性,便于以后的开发和维护
*/
if(sex.equals("1")){
sex="男";
}else if(sex.equals("0")){
sex="女";
}else{
sex="不详";
}
System.out.println("id0-"+id0+",id-"+id+",name-"+name+",sex-"+sex);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
//增
@Test
public void saveDemo(){
try {
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8";//建数据库的时候指定编码,java连接的时候也指定编码,两者一致,只要不是mysql故意改动编码,都不会乱码
Connection con=DriverManager.getConnection(url,"hncu","1234");
Statement st=con.createStatement();
//增
//String sql="insert into person2 values('P03','王晓明','0')";
// String id=UUID.randomUUID().toString().replace("-", "");
// Scanner sc=new Scanner(System.in);
// System.out.println("请输入姓名:");
// String name=sc.nextLine();
// String sql="insert into person2 values('"+id+"','"+name+"','0')";
//改 UPDATE person2 SET NAME=CONCAT(NAME,'x');
//String sql="update person2 set name=concat(name,'y')";
//删
String sex="1";
String sql="delete from person2 where sex='"+sex+"'";
int rows=st.executeUpdate(sql);
System.out.println(rows+" row(s) affected");
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void saveDemo2(){
try {
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8";//建数据库的时候指定编码,java连接的时候也指定编码,两者一致,只要不是mysql故意改动编码,都不会乱码
Connection con=DriverManager.getConnection(url,"hncu","1234");
Statement st=con.createStatement();
//增
//String sql="insert into person2 values('P03','王晓明','0')";
String id=UUID.randomUUID().toString().replace("-", "");
Scanner sc=new Scanner(System.in);
System.out.println("请输入姓名:");
String name=sc.nextLine();
String sql="insert into person2 values('"+id+"','"+name+"','1')";
//改 UPDATE person2 SET NAME=CONCAT(NAME,'x');
//String sql="update person2 set name=concat(name,'y')";
//删
// String sex="1";
// String sql="delete from person2 where sex='"+sex+"'";
int rows=st.executeUpdate(sql);
System.out.println(rows+" row(s) affected");
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* Statement中的三个方法:
* execute();select,insert,update,delete都可以。返回值:当select时有ResultSet为true,其它操作没有ResultSet返回为false
* executeUpdate();专用于select操作的,返回是一个查询结果集(ResultSet对象)
* executeQuery();专用于insert,update,delete,返回一个int值:影响的行数
*/
/*
* CREATE TABLE book(
id INT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(30),
price NUMERIC(5,2),
birth DATETIME
);
INSERT INTO book VALUES(1,'MySQL',39.8,'2015-11-04 18:42:30');
INSERT INTO book VALUES(2,'Oracle',59.8,'2015-11-04 17:45:30');
INSERT INTO book(NAME,price,birth) VALUES('JavaEE',80.55,'2014-08-03 11:15:10');
//DROP TABLE book;
*/
@Test
public void resultSetDemo(){
Connection con=ConnFactory.getConn();
try {
Statement st=con.createStatement();
String sql="select * from book";
ResultSet rs=st.executeQuery(sql);
while(rs.next()){
Integer id=rs.getInt(1);
String name=rs.getString(2);
Double price=rs.getDouble(3);
String birth=rs.getDate(4)+" "+rs.getTime(4);//数据库中,birth的类型是DateTime,在java中读取时日期和时间字段是分开读的,从同一个字段用两种方法分别读取日期和时间
System.out.println(id+","+name+","+price+","+birth);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//Statement缺陷1:----当用户输入特殊字符,如name为li'ming时会挂掉
// 解决办法:用SQL转义字符 单引号 ' 或者斜杠 \ 加在特殊字符前面----用java遍历用户信息,在特殊字符前面加转义字符
@Test
public void reg(){
Connection con=ConnFactory.getConn();
Scanner sc=new Scanner(System.in);
System.out.println("请输入id: ");
String id=sc.nextLine();
System.out.println("请输入用户名: ");
String name=sc.nextLine();
try {
Statement st=con.createStatement();
//insert into stud(id,name) values('5','Rose');
String sql="insert into stud(id,name) values('"+id+"','"+name+"') ";
System.out.println("sql---->"+sql);
int rs=st.executeUpdate(sql);
System.out.println(rs+" row(s) affected");
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//Statement缺陷2:----黑客登录,在输入name时,输: aa' or 'a'='a' 就是把那个where字句判断真假给破坏掉
@Test
public void login(){
Connection con=ConnFactory.getConn();
Scanner sc=new Scanner(System.in);
System.out.println("请输入id: ");
String id = sc.nextLine();
System.out.println("请输入用户名: ");
String name = sc.nextLine();
try {
Statement st = con.createStatement();
//假定id和name在数据库中存在就代表登录成功
//insert into stud(id,name) values('5','Rose');
String sql = "select count(*) from stud where id='" + id
+ "' and name='" + name + "' ";
System.out.println("sql---->" + sql);
ResultSet rs = st.executeQuery(sql);
rs.next();
int a = rs.getInt(1);
System.out.println("count值为:"+a);
if (a <= 0) {
System.out.println("登录失败!");
return;
}
System.out.println("登录成功!");
//con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//学习PreparedStatement:它是Statement的子类,帮助Statement在执行前先处理用户的信息
@Test
public void login2(){
Connection con=ConnFactory.getConn();
Scanner sc=new Scanner(System.in);
System.out.println("请输入id: ");
String id = sc.nextLine();
System.out.println("请输入用户名: ");
String name = sc.nextLine();
try {
//利用PreparedStatement进行预处理sql语句
String sql = "select count(*) from stud where id=? and name=? ";//构造sql语句时,在需要插入用户输入的地方用占位符 ?号
PreparedStatement pst = con.prepareStatement(sql);
//为各个占位符设置参数值
pst.setString(1, id);//第一个占位符
pst.setString(2, name);
ResultSet rs = pst.executeQuery();//注意:此处不要带参数(sql)
rs.next();
int a = rs.getInt(1);
System.out.println("count值为:"+a);
if (a <= 0) {
System.out.println("登录失败!");
return;
}
System.out.println("登录成功!");
//con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//学习PreparedStatement
@Test
public void reg2(){
Connection con=ConnFactory.getConn();
Scanner sc=new Scanner(System.in);
System.out.println("请输入id: ");
String id=sc.nextLine();
System.out.println("请输入用户名: ");
String name=sc.nextLine();
try {
//insert into stud(id,name) values('5','Rose');
String sql="insert into stud(id,name) values(?,?) ";
PreparedStatement pst=con.prepareStatement(sql);
pst.setString(1, id);
pst.setString(2, name);
int rs=pst.executeUpdate();
System.out.println(rs+" row(s) affected");
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//综上 ,为考虑系统健壮性,我们以后开发时,如果sql语句需要用用户输入构造时,要用PreparedStatement来实现。如果不需要,即sql语句是写死的,用Statement即可
}
Statement缺陷:1.遇到特殊字符挂掉了
2.容易被黑掉
我这里的id和name并没有和数据库中的匹配,但是依然登录了
用PreparedStatement修补后就可以了