JDBC学习

JDBC(Java Database Connectivity)是java连接数据库的规范,可以使用Java语言连接数据库完成增删查改操作.

JDBC的核心思想是Java中定义了访问数据库的接口,可以为多种关系型数据库提供统一的访问方式,有数据库厂商提供驱动实现类.

JDBC操作步骤

1.导包

        导入相应的驱动jar包.

2.注册驱动

        使用Class.forName("com.mysql.jdbc.Driver");手动加载字节码文件到JVM中.

3.连接数据库

        通过DriverManger.getConnection(url,user,password)获取数据库连接对象

        URL:jdbc:mysql://localhost:3306/database

        username:root

        password:12356

                URL:统一资源定位符,由协议,IP,端口,sid(程序实例名称)组成.

4.准备sql语句

        String sql="               ";

        数据库DML语句

        插入语句:insert into 表名(name,age,gender,address)values('库里','35','男','旧金山')

        修改语句:update 表名set name='汤普森',age=33,address='洛杉矶' where id=1=2

        删除语句:delete from 表名 where id=2;

        数据库DDL语句(建表)

        建立球员表:create table player( id int primary key auto_inscrement,name varchar(10),age int,gender varchar(3),address varchar(20))

        数据库DQL语句(查询)

        select id='编号','name '姓名', age'年龄',gender '性别',address '地址'from 表名

5.通过连接对象获取执行对象Statement

Statement stmt= conn.createStatement();

Statement弊端:

        1)存储在字符串拼接sql语句,不安全.

        2)执行效率低,频繁和数据库交互.

        因此引入PreparedStatement(预编译对象),是Statement子接口.

PreparedStatement特点:

        1)不存在字符串拼接.

        2)执行效率高.

//获取执行对象---->预编译对象PreparedStatement
//PreparedStatement prepareStatement(String sql):将上面的参数化sql发送给数据库
//将sql语句存储到了预编译对象中
        PreparedStatement stmt = conn.prepareStatement(sql);

//给占位符赋值
//通用setXXX(占位符号索引值,实际值) ; // 占位符号索引值是从1开始,第一个?就是1,第二个?就是 2
        //举例:setString(1,username)
        stmt.setString(1,username);
        stmt.setString(2,password);

6.执行sql语句

executeQuery:一般执行DQL查询语句,返回ResultSet.

        

ResultSet rs = stmt.executeQuery();
System.out.printIn(rs);


executeUpdate:一般执行DML语句(增删改)DDL语句(建表)(这些操作更新数据库,所以是update),返回int,被改变的语句的行数。

int count=stmt.executeUpdate(sql)
System.out.printIn(count);


execute,不确定是什么类型的SQL语句时可以用这个方法。

7释放资源

public class JDBCDemo {
    public static void main(String[] args) throws Exception {

        //1)导入驱动mysql的jar包
        //2)注册驱动
        Class.forName("com.mysql.jdbc.Driver") ;

       // DriverManager.registerDriver(new com.mysql.jdbc.Driver());

        //3)创建数据库的连接对象Connection
        //jdk提供的DriverManager:驱动管理类(管理jdbc的驱动的)
        //public static Connection getConnection(String url,String user,String password)throws SQLException
        //参数url: 统一资源定义符号  组成  协议:端口号:库名   --->jdbc:mysql://localhost:3306
        //参数user: 登录msyql的用户名 root用户
        //参数password:登录mysql的密码
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/ee_2208_02",
                "root",
                "123456"
        );


        //4)准备好sql
        String sql = "insert into account(name,balance) values('库里',2000)  " ;

        //5)通过连接对象获取执行对象Statment
        //Statement createStatement()throws SQLException创建一个Statement对象,用于将SQL语句发送到数据库
        Statement stmt = conn.createStatement();

        //6)执行sql语句   (插入操作)
        //Statement执行器里面---->
        //int executeUpdate(String sql)throws SQLException 通用的执行通用添加,删除,修改
        int count = stmt.executeUpdate(sql);
        System.out.println("影响了"+count+"行") ;

        //7)释放资源 (系统资源需要被释放的)
        stmt.close();
        conn.close();
    }
}

封装工具类

在实际JDBC的使用中,存在大量重复代码,因此可以将传统的JDBC代码重构,抽取出通过的工具类,以后连接任何数据库,释放资源都可以使用这个工具类.

封装获取连接,释放资源的两个方法:

        public static Connection  getConnection(){}

        public static void closeAll(Connection conn,Statement stmt,ResultSet rs){}

跨平台工具类实现

        在src目录下新建db.properties文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb
user=root
password=1234

        

1.JdbcUtils

public class JdbcUtils {

    //提供几个属性
    private static String url = null ;
    private static String user = null ;
    private static String password = null ;
    private static String driverClass= null ;
    //构造方法私有化
    private JdbcUtils(){}

    //提供静态代码块
    //JdbcUtils 类一加载,static{}就加载了,
    static{

        try {
            //1)读取src下面的配置文件jdbc.properties
            InputStream inputStream = JdbcUtils.class.getClassLoader().
                    getResourceAsStream("jdbc.properties");
            //2)将配置文件的内容加载到属性集合列表Properties
            //创建一个空的属性集合列表
            Properties prop = new Properties() ;
            prop.load(inputStream);
            //System.out.println(prop);
            //3)通过配置文件的key获取value
            //4)就给上面的成员变量赋值
            driverClass = prop.getProperty("driverClass");
            url = prop.getProperty("url") ;
            user = prop.getProperty("user") ;
            password = prop.getProperty("password") ;

            //注册驱动
            Class.forName(driverClass) ;

        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    //对外提供静态方法
    //定义一个方法:获取连接对象
    public static Connection getConnection(){

        try {
            //需要用到驱动管理类,获取连接对象
            Connection conn = DriverManager.getConnection(url, user, password);
            return conn ;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return  null ;
    }

    /**
     * 释放资源 针对DQL语句,select语句
     * @param rs  释放结果集对象
     * @param stmt 释放执行对象
     * @param conn 释放连接对象
     */
    public static void close(ResultSet rs,Statement stmt,Connection conn){
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    /**
     * 释放资源,针对DML语句:update,delete,insert操作的
     * @param stmt 释放执行对象
     * @param conn 释放连接对象
     */
    public static void close(Statement stmt,Connection conn){
       close(null,stmt,conn);//复用上面的close,第一个参数为null
    }


    public static void main(String[] args) {

        Connection connection = JdbcUtils.getConnection();
        System.out.println(connection);
    }


}

2.德鲁伊连接池(Druid)

1.导入德鲁伊jar包

2.准备好连接池配置文件

3.创建连接池对象

4.创建数据源

jar包

public class JdbcUtils_WithDruid {

    //成员变量的位置
    private static ThreadLocal<Connection> t1 = new ThreadLocal<>() ;//类一加载,创建线程
    private static DataSource ds ; //数据源---->里面空的
    //无参构造方法私有化
    private JdbcUtils_WithDruid(){}
    //静态代码块
    static{
        try {
            //1)读取src下面的 德鲁伊的配置文件
            //创建集合列表
            Properties prop = new Properties() ;
            //读取druid.properties
            InputStream inputStream = JdbcUtils_WithDruid.class.getClassLoader().
                    getResourceAsStream("druid.properties");

            //将资源文件输入流中的内容加载到属性列表中
            prop.load(inputStream);
            System.out.println(prop);


            //2)将配置文件进行加载---DruidDataSource自动封装这些7个参数
            //通过DruidDataSourceFactory 创建数据源
            ds = DruidDataSourceFactory.createDataSource(prop);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //定义方法----获取数据源的方法
    public static DataSource getDataSource(){
        return  ds ;
    }

    //定义一个获取连接对象
    public static Connection getConnection(){
        Connection conn = null ;
        try {
            //现在模拟多线程场景
            //1)从当前线程获取连接对象   ThreadLocal<Connection>----> Connection get()
           conn  = t1.get();
            //2)判断当前线程中的连接对象如果为null,
            if(conn==null){
                //说明没有连接对象
                //从连接池中获取连接对象
                Connection connection = ds.getConnection();
                //将连接池获取连接对象,绑定在当前线程中
                //ThreadLocal<Connection>----> set(Connection conn)
                t1.set(connection);
                return connection ;
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return  conn ;

    }



    /**
     * 释放资源 针对DQL语句,select语句
     * @param rs  释放结果集对象
     * @param stmt 释放执行对象
     * @param conn 释放连接对象
     */
    public static void close(ResultSet rs, Statement stmt, Connection conn){
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();//释放--->归还给连接池
                //从当前线程中解绑
                //ThreadLocl--->remove()
                t1.remove();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    /**
     * 释放资源,针对DML语句:update,delete,insert操作的
     * @param stmt 释放执行对象
     * @param conn 释放连接对象
     */
    public static void close(Statement stmt,Connection conn){
        close(null,stmt,conn);//复用上面的close,第一个参数为null
    }


    public static void main(String[] args) {
        DataSource dataSource = JdbcUtils_WithDruid.getDataSource();
        System.out.println(dataSource);

        Connection connection = JdbcUtils_WithDruid.getConnection();
        System.out.println(connection);
    }
}

Java连接数据库的方式(JDBC)控制事务

java.sql.Connection接口
void setAutoCommit(boolean autoCommit) throws SQLException
是否开启手动提交,参数true,就是自动提交,false,禁用自动提交,手动提交----->相当于mysql的指令 start transaction;
void rollback() throws SQLException撤销在当前事务中所做的所有更改----->事务回滚方法---->相当于msyql指令 rollback;
void commit()throws SQLException使上次提交/回滚之后所做的所有更改都将永久性  (提交事务)---->mysql的指令 commit;
Jdbc控制事务:当某个业务执行过程中需要同时指定多个sql(添加/删除/修改)需要将这个多个sql看成一个整体,他们要么同时执行成功,要么同时执行失败

转账实例


public class JdbcDemo {
    public static void main(String[] args) {

        //不使用JDBC控制事务

        //现在使用JDBC控制事务
        Connection conn = null ;
        PreparedStatement ps = null ;
        PreparedStatement ps2 = null ;
        try {
            //获取数据库连接对象
            conn = JdbcUtils.getConnection();
            //开启事务
            //void setAutoCommit(boolean autoCommit) throws SQLException
            conn.setAutoCommit(false) ;//禁用自动提交
            //sql语句
            String sql1 = "update account set balance = balance -? where id= ? " ;
            String sql2 = "update account set balance = balance +? where id = ?" ;

            //获取预编译对象
            ps = conn.prepareStatement(sql1);
            //赋值
            ps.setInt(1,500);
            ps.setInt(2,3);

            //将sql2进行发送数据库,获取预编译对象
            ps2 = conn.prepareStatement(sql2);
            //赋值
            ps2.setInt(1,500) ;
            ps2.setInt(2,4);

            //通过预编译对象执行sql
            int count = ps.executeUpdate();

            //操作过程中,给一段代码(有问题的代码)
            //int i = 10 /0 ;//除数不能0  try中的某行代码一出问题,就执行catch语句,处理异常


            int count2 = ps2.executeUpdate();

            System.out.println(count+"---"+count2);

          //更新完上面的所有操作,正常提交数据
            conn.commit();
            System.out.println("转账成功");

        } catch (ArithmeticException throwables) {

            try {
                //回滚事务
                //void rollback() throws SQLException撤销在当前事务中所做的所有更改---
                conn.rollback();
                //回滚完之后,手动提交
                conn.commit();
            } catch (SQLException e) {
                e.printStackTrace();
            }

            throwables.printStackTrace(); //交个jvm处理  将异常信息打印控制台
            //System.out.println("出问题了...除数为0");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            //System.out.println("SQL语句出问题了");
        } finally {
            //释放资源
            JdbcUtils.close(ps,conn);
            JdbcUtils.close(ps2,conn);

        }
    }
}

JDBC综合实例

数据库建立学生表,建立idea项目利用Java连接数据库执行对数据库对象的增删查改.

1.建立项目与数据库与相关配置文件

建立数据库

CREATE DATABASE ccc;
USE ccc;
CREATE TABLE student(
	id INT PRIMARY KEY AUTO_INCREMENT , 
	NAME VARCHAR(10),
	age INT,		   
	gender VARCHAR(3),		  
	address VARCHAR(20),
	birthday DATE
	);
	
INSERT INTO student(NAME,age,gender,address,birthday)
VALUES('库里',23,'男','夏洛特','1996-02-06'),
('汤普森',26,'男','洛杉矶','1997-02-23'),
('普尔',17,'男','明尼苏达','1991-02-08'),
('维金斯',35,'男','密尔沃基','1993-02-06'),
('鲁尼',48,'男','芝加哥','1996-02-09'),
('库明加',15,'男','旧金山','1999-11-06')
SELECT * FROM student ;

配置文件:

        driverClassName=com.mysql.jdbc.Driver

        url=jdbc:mysql://localhost:3306/ccc

        username=root password=123456

        initialSize=5

        maxActive=10

        maxWait=3000

 2.导入相关jar包

 3.建立学生类(pojo)

package com.qf.pojjo;

public class Student {
    private int id;
    private String name;
    protected  int age;
    private String gender;
    public String address;

    public Student() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

4.建立Daoimpl项与DAO接口

package com.qf.dao;

import com.qf.pojjo.Student;

import java.sql.SQLException;
import java.util.List;

public interface StudentDao {
    //查询所有学生
    List<Student> findAll()throws SQLException;
    //模糊查询
    List<Student>findStudentByName(String name)throws  SQLException;
    //通过编号查询学生
    Student findStudentById(int id)throws SQLException;
    //添加学生
    int registerStudent(Student student)throws SQLException;
    //通过id删除学生
    void deleteStudent(int id)throws SQLException;

    //修改学生
    void updateStudent(Student student)throws SQLException;
}
package com.qf.dao.Impl;

import com.qf.dao.StudentDao;
import com.qf.pojjo.Student;
import com.qf.utils.JdbcUtils_WithDruid;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class StudentDaoImpl implements StudentDao {
    //查询所有学生
    @Override
    public List<Student> findAll() throws SQLException {
        Connection conn = JdbcUtils_WithDruid.getConnection();
        String sql ="select * from student";
        PreparedStatement ps =conn.prepareStatement(sql);
        ResultSet rs =ps.executeQuery();
        List<Student>list =new ArrayList<>();
        Student s =null;
        while(rs.next()){
            s=new Student();
            s.setAge(rs.getInt("id"));
            s.setId(rs.getInt("id"));
            s.setGender(rs.getString("gender"));
            s.setName(rs.getString("name"));
            s.setAddress(rs.getString("address"));


            list.add(s);
        }
        JdbcUtils_WithDruid.close(rs,ps,conn);
        return list;
    }
    //模糊查询
    @Override
    public List<Student> findStudentByName(String name) throws SQLException {
        Connection conn = JdbcUtils_WithDruid.getConnection();
        String sql="select * from student where name like ?";
        PreparedStatement ps=conn.prepareStatement(sql);
        ps.setString(1,name);
        ResultSet rs = ps.executeQuery();
        List<Student>list =new ArrayList<>();
        Student s = null;
        while (rs.next()){
            s=new Student();
            s.setAddress(rs.getString("address"));
            s.setName(rs.getString("name"));
            s.setAge(rs.getInt("age"));
            s.setId(rs.getInt("id"));
            s.setGender(rs.getString("gender"));
            list.add(s);

        }
        JdbcUtils_WithDruid.close(rs,ps,conn);

        return list;
    }
        //通过编号查询学生实体
    @Override
    public Student findStudentById(int id) throws SQLException {
        Connection conn=JdbcUtils_WithDruid.getConnection();
        String sql = "select * from student where id=? ";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1,id);
        Student s =null;
        ResultSet rs =ps.executeQuery();
        while (rs.next()){
            s=new Student();
            s.setGender(rs.getString("gender"));
            s.setAge(rs.getInt("age"));
            s.setId(rs.getInt("id"));
            s.setName(rs.getString("name"));
            s.setAddress(rs.getString("address"));
        }
        JdbcUtils_WithDruid.close(rs,ps,conn);
        return s;
    }
    //添加学生
    @Override
    public int registerStudent(Student student) throws SQLException {
        Connection conn=JdbcUtils_WithDruid.getConnection();
        String sql ="insert into student(name,age,gender,address) values(?,?,?,?)";
        PreparedStatement ps =conn.prepareStatement(sql);
        ps.setString(1,student.getName());
        ps.setInt(2,student.getAge());
        ps.setString(3,student.getGender());
        ps.setString(4,student.getAddress());

        int count =ps.executeUpdate();

        JdbcUtils_WithDruid.close(ps,conn);
        return count;



    }
    //删除员工
    @Override
    public void deleteStudent(int id) throws SQLException {
        Connection conn =JdbcUtils_WithDruid.getConnection();
        String sql ="delete from student where id=?";
        PreparedStatement ps =conn.prepareStatement(sql);
        ps.setInt(1,id);
        int count =ps.executeUpdate();
        System.out.println(count);
        JdbcUtils_WithDruid.close(ps,conn);


    }
    //修改学生
    @Override
    public void updateStudent(Student student) throws SQLException {
        Connection conn =JdbcUtils_WithDruid.getConnection();
        String sql ="update student set address =?,age=?,gender=?,name=? where id=?";
        PreparedStatement ps=conn.prepareStatement(sql);
        ps.setString(1,student.getAddress());
        ps.setInt(2,student.getAge());
        ps.setString(3,student.getGender());
        ps.setString(4,student.getName());
        ps.setInt(5,student.getId());
        int count =ps.executeUpdate();
        System.out.println(count);
        JdbcUtils_WithDruid.close(ps,conn);


    }
}

5.创建Urils文件(德鲁伊)

package com.qf.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JdbcUtils_WithDruid {
    private static ThreadLocal<Connection> t1 =new ThreadLocal<>();
    private static DataSource ds;
    private JdbcUtils_WithDruid(){}
    static {
        try {
            Properties prop =new Properties();
            InputStream inputStream =JdbcUtils_WithDruid.class.getClassLoader().getResourceAsStream("druid.properties");
            prop.load(inputStream);
            System.out.println(prop);
            ds = DruidDataSourceFactory.createDataSource(prop);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public static DataSource getDataSourse(){return ds;}
    public static Connection getConnection(){
        Connection conn =null;
        try {
            conn=t1.get();
            if(conn==null){
                Connection connection =ds.getConnection();
                t1.set(connection);
                return connection;
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return conn;
    }



    public static void close(ResultSet rs, Statement stmt,Connection conn){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
                t1.remove();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }


    public static void close(Statement stmt,Connection conn){close(null,stmt,conn);}


    public static void main(String[] args){
        DataSource dataSource =JdbcUtils_WithDruid.getDataSourse();
        System.out.println(dataSource);

        Connection connection =JdbcUtils_WithDruid.getConnection();
        System.out.println(connection);
    }
}

6.创建测试类

package com.qf.test;

import com.qf.dao.Impl.StudentDaoImpl;
import com.qf.dao.StudentDao;
import com.qf.pojjo.Student;
import org.junit.Before;
import org.junit.Test;

import java.sql.SQLException;
import java.util.List;

public class StudentTest {
    private StudentDao sd;
    @Before
    public void init(){ sd=new StudentDaoImpl(); }
    //测试查询所有学生
    @Test
    public void testFindAll()throws SQLException{
        List<Student> students=sd.findAll();
        if (students!=null){
            for (Student s:students){
                System.out.println(s);
            }
        }

    }
    //测试模糊查询
    @Test
    public void testFindStudentByName() throws SQLException{
        List<Student> students=sd.findStudentByName("%库%");
        if(students!=null){
            for(Student s:students){
                System.out.println(s);
            }
        }
    }
    //测试根据id查询学生
    @Test
    public void testFindStudentById() throws SQLException{
        Student student =sd.findStudentById(1);
        if(student!=null){
            System.out.println(student);
        }
    }
    //测试添加学生
    @Test
    public void testAddStudent() throws SQLException{
        Student student = new Student();
        student.setName("迪温琴佐");
        student.setAddress("密尔沃基");
        student.setGender("男");
        student.setAge(26);
        sd.registerStudent(student);
    }
    //测试删除学生
    @Test
    public void testdeleteStudent() throws SQLException{
        sd.deleteStudent(5);
    }
    //测试修改学生
    @Test
    public void testUpdateStudent()throws  SQLException{
        Student s =new Student();
        s.setAge(11);
        s.setId(1);
        s.setAddress("旧金山");
        s.setName("库日天");
        s.setGender("女");
        sd.updateStudent(s);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值