Java程序员有可能连接多种数据库软件,如果没有JDBC接口,每一种数据库都有可能提供一套不同的方法, 对于Java程序员而言学习成本变大, 使用JDBC接口把方法名在接口中定义好,各个数据库厂商根据此接口实现里面的方法,这样Java程序员只需要学习JDBC接口的方法调用即可, 如果完全按照JDBC接口的标准写代码 就算将来换了数据库 代码都不需要改变.
创建maven工程
引入MySQL的jar包, 从苍老师文档服务器中找到 配置文件下载中的pom.xml常用配置 点击进去找到MySQL驱动 , 把下面代码复制到工程的pom.xml里面的 里面, 保存 出现奶瓶即可.
mysql
mysql-connector-java
8.0.15
//1. 注册驱动 通过反射技术加载Driver类
//通知编译器使用的是MySQL数据库
//如果是5.1.6 com.mysql.jdbc.Driver
Class.forName("com.mysql.cj.jdbc.Driver");
//2. 获取数据库链接对象
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/newdb3?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true",
"root", "root");
System.out.println(conn);
//3. 创建SQL执行对象 专门执行SQL语句的对象
Statement s = conn.createStatement();
//4. 执行SQL语句
String sql = "create table jdbct1(id int,name varchar(10))";
s.execute(sql);//执行方法 execute是执行的意思
System.out.println("创建完成!");
//5. 关闭资源
conn.close();
//创建读取配置文件的对象
Properties p = new Properties();
//通过类加载器获取配置文件输入流
InputStream ips = DBUtils.class.getClassLoader()
.getResourceAsStream("jdbc.properties");
//让对象和输入流关联
p.load(ips);
//开始读取数据
String driver = p.getProperty("db.driver");
String url = p.getProperty("db.url");
String name = p.getProperty("db.username");
String password = p.getProperty("db.password");
如果没有数据库连接池,一万次业务请求会需要用到一万次数据库连接, 频繁的开关连接非常浪费资源,使用连接池后可以将连接重用, 避免了频繁开关连接,从而达到了提高执行效率的目的
如何使用连接池
–下载连接池相关的jar包
com.alibaba
druid
1.1.21
往SQL语句中写值的地方写进去SQL语句的一部分,导致原有SQL语句的逻辑反生改变.这就称为SQL注入
SQL注入是网站存在的安全漏洞,应避免在网站中出现此漏洞
通过预编译的SQL执行对象(PreparedStatement) 解决SQL注入问题
如果SQL语句中包含变量则使用PreparedStatement,如果SQL语句中没有变量则使用Statement
public class DBUtils {
private static DruidDataSource ds;
static {
//创建读取配置文件的对象
Properties p = new Properties();
//通过类加载器获取配置文件输入流
InputStream ips = DBUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
//让对象和输入流关联
try {
p.load(ips);
} catch (IOException e) {
e.printStackTrace();
}
//开始读取数据
String driver = p.getProperty("db.driver");
String url = p.getProperty("db.url");
String name = p.getProperty("db.username");
String password = p.getProperty("db.password");
//读取最大连接数量和初始连接数量 配置文件中只能读取字符串
String maxSize = p.getProperty("db.maxActive");
String initSize = p.getProperty("db.initialSize");
//创建连接池对象
ds = new DruidDataSource();
//设置连接信息
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(name);
ds.setPassword(password);
//设置初始和最大数值
ds.setInitialSize(Integer.parseInt(initSize));
ds.setMaxActive(Integer.parseInt(maxSize));
}
public static Connection getConn() throws Exception {
//返回连接池里面的连接对象
return ds.getConnection();
}
}
public class Demo05 {
public static void main(String[] args) {
//获取连接对象
try(Connection conn = DBUtils.getConn();) {
String sql1 = "insert into user values(null,'aaa','123')";
String sql2 = "insert into user values(null,'bbb','123')";
String sql3 = "insert into user values(null,'ccc','123')";
//由于SQL语句没有变量,都是写死得值 所以使用Statement
Statement s = conn.createStatement();
//将3条SQL合成一次批量操作
s.addBatch(sql1);
s.addBatch(sql2);
s.addBatch(sql3);
//执行批量操作
s.executeBatch();
System.out.println("执行完成!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class Demo06 {
public static void main(String[] args) {
//获取连接对象
try (Connection conn = DBUtils.getConn(); ) {
String sql = "insert into user values(null,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
for (int i = 1; i <= 100; i++) {
ps.setString(1, "name"+i);
ps.setString(2, "pw"+i);
//添加到批量操作
ps.addBatch();
//每隔20次执行一次,避免内存溢出
if(i%20==0) {
ps.executeBatch();
}
}
//执行批量操作
ps.executeBatch();
System.out.println("执行完成!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
小练习:
public class Demo07 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入查询的页数: ");
int page = sc.nextInt();
System.out.println("请输入查询的条数: ");
int size = sc.nextInt();
//获取连接对象
try (Connection conn = DBUtils.getConn();) {
//查出和页数对应的用户信息(id,username,password)
String sql = "select * from user limit ?,?";
PreparedStatement ps = conn.prepareStatement(sql);
//limit 跳过的条数,请求的条数 (page-1)*size=跳过的条数
ps.setInt(1, (page-1)*size);
ps.setInt(2, size);
ResultSet rs = ps.executeQuery();
while(rs.next()) {
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
System.out.println(id+":"+username+":"+password);
}
} catch (Exception e) {
e.printStackTrace();
}
sc.close();
}
}
现在MySQL的一个数据库里创建两个表格
create table team(id int primary key auto_increment,name varchar(20))charset=utf8;
create table player(id int primary key auto_increment,name varchar(20),teamId int)charset=utf8;
然后写java代码
//往用户表中插入数据 并且获取自增的主键值
String sql = "insert into user values(null,?,null)";
//SQL语句中有变量 使用预编译SQL执行对象
//1. sql语句后面添加Statement.RETURN_GENERATED_KEYS
PreparedStatement ps = conn.prepareStatement(sql
,Statement.RETURN_GENERATED_KEYS);
//替换问号
ps.setString(1, name);
//执行SQL语句
ps.executeUpdate();
System.out.println("执行完成!");
//2. 获取装着主键值的结果集
ResultSet rs = ps.getGeneratedKeys();
rs.next();//游标往下挪一下
int id = rs.getInt(1);//如果结果集中只查询了一个数据 直接写1
System.out.println("自增id:"+id);