一,数据库连接
步骤
1.加载驱动(Driver):
Class.forName("Driver的全路径"); //可以不写
2.连接数据库
首先声明url地址
String url = "jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characherEncoding=utf8";
3.获取连接对象:使用 DriverManager
Connection conn = DriverManager.getConnection(url,"默认mysql名字","密码");
package com.jdbc.connect;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/*
测试数据库连接
*/
public class JdbcConnect {
public static void main(String[] args) throws Exception {
//1.加载驱动(jdbc4.0过后就可以省略)
Class.forName("com.mysql.jdbc.Driver");
System.out.println("驱动加载成功");
//2.连接数据库
/*
需要使用DriverManager
静态方法:获取数据库连接对象
1.static Connection getConnection(url,root,password)
*/
String url = "jdbc:mysql://localhost:3306/hqyj?useUnicode=true&characterEncoding=utf8";
//获取连接对象
Connection conn = DriverManager.getConnection(url,"root","123456");
//关闭连接
conn.close();
}
}
二,java对数据库的增删改查
SQL语句分类:
DDL:创表,创库
DML:增删改语句
DQL:查询
DCL:用于用户权限设置
1.增删改:executeUpdate
操作
①连接数据库后,编写SQL语句对象
Statement sta = conn.prepareStatement(SQL语句);
②编写SQL语句
String sql = "数据库SQL语句";
③通过executeUpdate发送SQL对象
int i = sta.executeUpdate();
④关闭连接
conn.close();
sta.close();
package com.jdbc.dml;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/*
*/
public class DatabaseTest {
public static void main(String[] args) throws Exception {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//连接数据库
String url = "jdbc:mysql://localhost:3306/hqyj?useUnicode=true&characterEncoding=utf8";
Connection conn = DriverManager.getConnection(url,"root","123456");
//编写sql语句对象
Statement sta = conn.createStatement();
// String sql = "insert into course values('04','生物','01') ";
// String sql = "delete from course where cid = 04";
// String sql = "update course set Cname = '化学'where cid = 01";
String sql = "select * from course";
//发送sql语句,返回影响行数
int i = sta.executeUpdate(sql);
// System.out.println("成功插入" +i + "行数据");
//关闭连接
conn.close();
sta.close();
}
}
2.查询:executeQuery
连接数据库后用executeQuery发送SQL对象
再用while(返回值.next())循环获取查询结果
package com.jdbc.dql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/*
DQL语句:查询
*/
public class DatabaseTest {
static{
//加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//连接数据库
String url = "jdbc:mysql://localhost:3306/hqyj?useUnicode=true&characterEncoding=utf8";
Connection conn = null;
Statement sta = null;
ResultSet set = null;
try {
//获取连接对象
conn = DriverManager.getConnection(url, "root", "123456");
//创建sql对象
sta = conn.createStatement();
//编写sql语句
String sql = "select * from course";
//发送sql语句 返回值ResultSet 存储的是查询到的结果集
set = sta.executeQuery(sql);
//获取查询到的结果
while (set.next()){
//获取id
String cid = set.getString("Cid");
//获取名称
String cname = set.getString("Cname");
//获取编号
String tid = set.getString("Tid");
//打印结果
System.out.println(cid + "-" + cname + "-" +tid);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
//关闭资源
if (conn != null){
conn.close();
}
if (sta != null){
sta.close();
}
if (set != null){
set.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
注:使用createStatement不安全,因此改进使用prepareStatement
使用prepareStatement实现登录注册功能
在对数据库插入控制台输入的数据时:用占位符"?"表示要传的值,然后用set设置值
使用prepareStatement在最后发送SQL对象时,不用再添加SQL
package com.jdbc.dql;
import javax.sound.midi.Soundbank;
import java.sql.*;
import java.sql.Date;
import java.util.Scanner;
/*
登录:通过账号密码登录
sql:select *from user where name= '' and password = '';
根据ResultSet的next方法判断是否查到了数据,如果true登陆成功,否则账号或密码输入错误
*/
public class DatabaseTest02 {
public static void main(String[] args) throws Exception{
/* //登录
System.out.println("请输入账户名");
Scanner sc = new Scanner(System.in);
String name = sc.next();
System.out.println("请输入密码");
Scanner sc2 = new Scanner(System.in);
String password = sc2.next();
boolean result = login(name, password);
if (result){
System.out.println("登录成功");
}else {
System.out.println("账号或密码错误");
}*/
//注册
System.out.println("请输入账户名");
Scanner sc3 = new Scanner(System.in);
String nm = sc3.next();
System.out.println("请输入密码");
Scanner sc4 = new Scanner(System.in);
String psd= sc4.next();
System.out.println("请输入时间");
Scanner sc5 = new Scanner(System.in);
String date= sc5.next();
boolean enroll = enroll(nm,psd,date);
if (enroll){
System.out.println("注册成功");
}else{
System.out.println("注册失败");
}
}
//登录
public static boolean login(String name, String password) throws Exception {
boolean result = false;
//创建连接
String url = "jdbc:mysql://localhost:3306/hqyj?useUnicode=true&characterEncoding=utf8";
//获取连接对象
Connection conn = DriverManager.getConnection(url, "root", "123456");
//编写sql语句 会发生SQL注入
// String sql = "select * from user where name='" + name + "' and passward = '" + password + "'";
//编写sql语句,使用?占位符来表示传的值
String sql = "select * from user where name=? and passward = ?";
//创建PreparedStatement对象
PreparedStatement pre = conn.prepareStatement(sql);
//设置SQL语句中占位符?的值
pre.setString(1,name);//1表示给第一个占位符?设置值
pre.setString(2,password);//2表示给第二个占位符?设置值
//发送SQL语句
ResultSet set = pre.executeQuery();
//判断是否查询到结果
conn.close();
pre.close();
//判断是否查询到结果
if (set != null){
result = true;
}else {
result = false;
}
return result;
}
//注册
public static boolean enroll (String name,String password,String date)throws Exception{
boolean result = false;
//创建连接
String url = "jdbc:mysql://localhost:3306/hqyj?useUnicode=true&characterEncoding=utf8";
//获取连接对象
Connection conn = DriverManager.getConnection(url, "root", "123456");
String sql = "INSERT into user VALUES(null,?,?,?)";
//创建PreparedStatement对象
PreparedStatement pre = conn.prepareStatement(sql);
//设置SQL语句中占位符?的值
pre.setString(1,name);
pre.setString(2,password);
pre.setDate(3,Date.valueOf(date));
//发送SQL语句
int set = pre.executeUpdate();
conn.close();
pre.close();
//判断是否查询到结果
if (set != 0){
result = true;
}else {
result = false;
}
return result;
}
}
createStatement和prepareStatement的区别
1、prepareStatement是预编译处理的,也叫jdbc存储过程,对于批量处理可以大大提高效率;同时对象的开销比createStatement大,对于一次性操作并不会带来额外的好处;但是能避免SQL注入的安全问题;
2、createStatement对象,适用于在对数据库只执行一次性存取需求,可能造成SQL注入,不安全;
三,JDBC连接工具类
分两种
1.直接使用
步骤:
1.导包之后创建jdbc.properties文件
driver = com.mysql.jdbc.Driver//Driver类地址
url = jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf8
username = 用户名
pass = 用户密码
2.然后创建工具类层util包,创建JdbcUtils 类实现以下操作
package com.jdbc.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/*
JDBC连接工具类
*/
public class JdbcUtils {
//使用Properties对象来存储配置文件中的信息
static Properties pro = new Properties();
static {
try {
//1.获取到配置文件中配置的信息
InputStream in = Thread.currentThread().
getContextClassLoader().
getResourceAsStream("jdbc.properties");//配置文件名
//2.使用Properties对象来存储配置文件中的信息
//加载流
pro.load(in);
//此时,Properties中就存储了配置文件中的信息
//3.获取到Properties中信息,通过键名来获取值
//获取驱动的全路径
String path = pro.getProperty("driver");
//加载驱动
Class.forName(path);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取数据库的连接对象
public static Connection getConnection(){
//获取用户名
String name = pro.getProperty("username");
//获取密码
String pass = pro.getProperty("pass");
//获取连接路劲
String url = pro.getProperty("url");
try {
//返回连接对象
return DriverManager.getConnection(url,name,pass);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//关闭所有资源
public static void closeAll(Connection conn, PreparedStatement pre, ResultSet set){
try {
if (conn != null){
conn.close();
}
if (pre != null){
pre.close();
}
if (set != null){
set.close();
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
2.使用数据库连接池
步骤:
1.导包之后创建druid.properties文件
driver = com.mysql.jdbc.Driver//Driver类地址
url = jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf8
username = 用户名
password = 密码
initialSize=5 //初始化连接大小
maxActive=5 //最大连接数
2. 创建然后创建工具类层util包,创建DruidUtils 类实现以下操作
package com.jdbc.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
//连接池工具类
public class DruidUtils {
//使用Properties对象来存储配置文件中的信息
static Properties pro = new Properties();
static {
try {
//1.获取到配置文件中配置的信息
InputStream in = Thread.currentThread().
getContextClassLoader().
getResourceAsStream("druid.properties");//配置文件名
//2.使用Properties对象来存储配置文件中的信息
//加载流
pro.load(in);
//此时,Properties中就存储了配置文件中的信息
//3.获取到Properties中信息,通过键名来获取值
//获取驱动的全路径
String path = pro.getProperty("driver");
//加载驱动
Class.forName(path);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection(){
try {
//向连接池获取Connection对象
//连接池加载配置文件信息
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//获取连接
return ds.getConnection();
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
使用数据库连接池提高了数据库性能,而且最后不需要关闭资源比较方便
四,触发器
创建触发器
语法:
CREATE TRIGGER 触发器名字
[BEFORE/AFTER] [INSERT/UPDATE/DELETE]
ON 表名
for each row --表示行级触发器
#触发器触发后要做的事情
BEGIN
--sql语句(必须加;)
end
查看触发器
SHOW TRIGGERs
删除触发器
drop trigger test2
#触发器的创建
/*
*/
CREATE TRIGGER test
AFTER INSERT
on orders
for each row
BEGIN
#更新水果表中水果的数量,new.count表示订单表中即将要减少的count
UPDATE fruit set f_count=f_count-new.count where f_name=new.name;
end
#查看触发器
SHOW TRIGGERs
#插入一条订单记录
insert into orders values(null ,'西瓜',50);
CREATE TRIGGER test3
AFTER delete
on orders
for each row
BEGIN
#更新水果表中水果的数量,old.count表示订单表中即将要新增的count
UPDATE fruit set f_count=f_count+old.count where f_name=old.name;
end
delete from orders where name='西瓜'
#记录日志
create trigger test2
after update
on fruit
for each row
begin
insert into fruit_log values(null,old.f_name,old.f_count,(new.f_count-old.f_count),new.f_count,now());
end
update fruit set f_count=500 where f_name='西瓜'
update fruit set f_count=200 where f_name='哈密瓜'
#删除触发器
drop trigger test2