JAVA连接MYSQL数据库

本文介绍了如何使用Java连接MySQL数据库,包括加载驱动、获取连接、执行SQL语句等步骤,并强调了SQL注入问题及解决方案,提倡使用PreparedStatement。同时,讨论了将查询结果封装到实体类中,对每个表的操作进行单独封装到DAO类,以及异常处理和公共DAO父类的设计思路。

1.java连接mysql数据库

  1. 创建一个java工程。

  2. 在工程下创建一个目录library---->放jar的。

  3. mysql-connector-java-8.0.20.jar

  4. 把该jar进行解压--->一定要在程序中完成。

写程序:

public class Test01 {
    public static void main(String[] args)throws Exception {
        //1.加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2.获取连接对象
        //String url: 数据库的路径 
        //协议:数据的种类://ip:端口号/数据库名?serverTimezone=Asia/Shanghai
        //String user,账号
        //String password 密码
        String url="jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
        String user="root";
        String password="root";
        Connection connection= DriverManager.getConnection(url,user,password);

        //3.获取执行sql语句的对象。
        Statement statement=connection.createStatement();

        //4.执行sql语句。增删改
        String sql="delete from t_student where id=1";
        statement.executeUpdate(sql);
    }
}

总结:

1. 加载驱动 Class.forName("com.mysql.cj.jdbc.Driver");
2. 获取连接对象 Connection connection=DriverManager.getConnection(url,u,pass);
3. 获取执行sql语句的对象. Statement statement=connection.createStatement();
4. 执行sql语句: statement.executeUpdate(sql);

 测试---往数据库中增删改

public class demo1 {
    @Test
    public void TestDelete() throws Exception {
        //加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //获取连接对象
        String url="jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
        String user="root";
        String password="001024";
        Connection connection=DriverManager.getConnection(url,user,password);
        //获取sql语句对象
        Statement statement = connection.createStatement();
        //执行sql语句删
        String sql="delete from student where id=15";
        statement.executeUpdate(sql);
    }
    @Test
    public void TestInsert() throws Exception {
        //加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //获取连接对象
        String url = "jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
        String user = "root";
        String password = "001024";
        Connection connection = DriverManager.getConnection(url,user,password);
        //获取sql语句对象
        Statement statement = connection.createStatement();
        String sql = "insert into student values(null,'小明',18,'郑州')";
        statement.executeUpdate(sql);
    }
    @Test
    public void TestUpdate() throws Exception {
        //加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //获取连接对象
        String url = "jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
        String user = "root";
        String password = "001024";
        Connection connection = DriverManager.getConnection(url,user,password);
        //获取sql语句对象
        Statement statement  = connection.createStatement();
        String sql = "update student set name='小红',age=22,address='周口' where id=16";
        statement.executeUpdate(sql);
    }
}

 

出现的错误有哪些?

1.驱动类找不到:

原因: (1)类写错了 (2)没有把驱动jar包放入工程中并解压。

2.没有写时区或者写错了。?serverTimezones=Asia/Shanghai

3.数据库的账号或密码错误。

4.sql语句有错。 应该把sql放到数据库中执行一下

2. 查询数据库表中记录。

2.1查询所有

 public void testQuery() throws Exception { //抛出异常只是为了操作方便。真正在开发时应该try--catch
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "root");

        Statement statement = conn.createStatement();

        String sql = "select id,name,age,address from t_student";
        //执行查询sql语句 并把数据库表中记录返回到ResultSet对象中进行保存。
        ResultSet rs = statement.executeQuery(sql);

        //取出ResultSet中表的记录。rs.next() 判断指针是否可以移动。如果可以移动则返回true,否则返回false
        while (rs.next()) {
            int id = rs.getInt("id"); //指针移动并获取指定列的值。
            String name = rs.getString("name");
            String address=rs.getString("address");
            int age=rs.getInt("age");
            System.out.println("id:"+id+";name:"+name+";age:"+age+";address:"+address);
        }

    }

2.2根据id查询

 //根据条件查询数据库
    @Test
    public void testQueryByCondition() throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "root");

        Statement statement = conn.createStatement();
        String sql="select * from t_student where id=3";
        ResultSet rs = statement.executeQuery(sql);
        while (rs.next()){
            int id = rs.getInt("id"); //指针移动并获取指定列的值。
            String name = rs.getString("name");
            String address=rs.getString("address");
            int age=rs.getInt("age");
            System.out.println("id:"+id+";name:"+name+";age:"+age+";address:"+address);
        }


    }

3. sql注入问题

 //演示sql注入的安全问题
    public static void main(String [] args) throws Exception{
        Scanner scanner=new Scanner(System.in); //Scanner类有没有讲过。
        System.out.print("请输入账号:");
        String username = scanner.nextLine();
        System.out.print("请输入密码:");
        String password = scanner.nextLine(); //你输入的账号和密码 nextLine() 可以输入空格 回车任认为结束  next()输入空格后认为输入结束。
        boolean b = sqlSafe(username, password);
    }

    //根据name查询数据 abc  演示的根据账号和密码查询数据库表记录 如果能查询表示登录成功 否则登录失败
    private static boolean sqlSafe(String name,String password) throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "root");

        Statement statement = conn.createStatement();
        //这里的admin 是不是一个死数据  123456 也是一个死数据
        String sql="select * from t_user where username='"+name+"' and password='"+password+"'";
        System.out.println(sql);
        ResultSet rs = statement.executeQuery(sql);

        while (rs.next()){
            System.out.println("登录成功");
            return true;
        }

        System.out.println("登录失败");
        return false;

    }

可以发现: 你的账号可以随便输入 你的密码也可以随便输入 但是 在输入密码时 or '4'='4 只要这个条件成立,那么你就能登录成功。 这个就是sql注入的安全问题。只要根据条件做sql。那么就会出现sql注入安全问题。

3.1 使用prepareStatement来解决sql注入的问题。

 public static void main(String [] args) throws Exception{
        Scanner scanner=new Scanner(System.in); //Scanner类有没有讲过。
        System.out.print("请输入账号:");
        String username = scanner.nextLine();
        System.out.print("请输入密码:");
        String password = scanner.nextLine(); //你输入的账号和密码 nextLine() 可以输入空格 回车任认为结束  next()输入空格后认为输入结束。
        boolean b = sqlSafe02(username, password);
    }

    private static boolean sqlSafe02(String name,String password) throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "root");

        //使用PrepareStatement 这里的? 是占位符。
        String sql="select * from t_user where username=? and password=?";
        PreparedStatement ps = conn.prepareStatement(sql);//预编译sql
        //为占位符赋值。根据占位符的类型使用不同的方法来赋值
        ps.setString(1,name); //1表示第一个占位符  name:表示第一个占位符的值
        ps.setString(2,password);

        //执行sql语句
        ResultSet rs = ps.executeQuery();
        while (rs.next()){
            System.out.println("登录成功");
            return true;
        }
        System.out.println("登录失败");
        return false;
    }

 4.把查询的结果封装到相应的实体上

如何把查询的结果封装起来:

1. 把数据库中每张表封装成一个类---简称实体类。
2. 把表中的列封装成实体类中的属性。
3. 表中的每条记录封装成实体类的对象。
4. 表中多条记录封装成集合ArrayList。 

@Test
    public void testSelect() throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, user, password);
        String sql = "select * from tb_dept"; //因为这里没有占位符 所以可以不用为占位符赋值
        PreparedStatement ps= connection.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();

        List<Dept> list = new ArrayList<>(); //集合存放数据库表中所有记录
        while (rs.next()){
            int id = rs.getInt("id");
            String name = rs.getString("name");
            //创建一个实体类对象 存储表中的一条记录。
            Dept d = new Dept();
            d.setId(id);
            d.setName(name);

            list.add(d);
        }
        System.out.println(list); //正常再开发中应该把该对象list返回给前端。
    }
 @Test
    public void testSelectOne() throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, user, password);
        String sql = "select * from tb_dept where id=?"; //这里根据id查询的结果一定是一条记录。因为id是主键。
        PreparedStatement ps= connection.prepareStatement(sql);
        ps.setInt(1,9);

        ResultSet rs = ps.executeQuery();
        Dept d=null;//声明部门实体类对象。
        while (rs.next()){
            d =  new Dept(); //因为进入该语句表示从数据库中查询到相应的记录了。
            int id = rs.getInt("id");
            String name = rs.getString("name");
            d.setId(id);
            d.setName(name);
        }

        System.out.println(d); //以后可以把d返回给前端调用者

    }

 5.把对每一张表的操作封装到相应的类上

思考: 我们如果把所有表的操作都写在一个类中,那么该类的代码会变得越来越容重,对应后期维护也不方便,真正再企业开发时我们会对每张表得操作都封装一个对应得操作类。

后缀都是Dao -----Data access Object 数据访问对象层

public class DeptDao {

    private String driverName="com.mysql.cj.jdbc.Driver";
    private String url="jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
    private String user="root";
    private String password="root";

    //根据id查询部门信息
    public Dept findOne(int id) throws Exception{
        Class.forName(driverName);
        Connection connection = DriverManager.getConnection(url, user, password);
        String sql = "select * from tb_dept where id=?"; //这里根据id查询的结果一定是一条记录。因为id是主键。
        PreparedStatement ps= connection.prepareStatement(sql);
        ps.setInt(1,id);

        ResultSet rs = ps.executeQuery();
        Dept d=null;//声明部门实体类对象。
        while (rs.next()){
            d =  new Dept(); //因为进入该语句表示从数据库中查询到相应的记录了。
            d.setId(rs.getInt("id"));
            d.setName(rs.getString("name"));
        }
        return d;
    }

    //查询操作--查询所有
    public List<Dept> findAll() throws Exception{
        List<Dept> list=new ArrayList<>();
        Class.forName(driverName);
        Connection connection = DriverManager.getConnection(url,user,password);
        String sql= "select * from tb_dept";
        PreparedStatement ps=connection.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();

        while (rs.next()){
            //创建一个实体类对象 存储表中的一条记录。
            Dept d = new Dept();
            d.setId(rs.getInt("id"));
            d.setName(rs.getString("name"));
            list.add(d);
        }
        return list;
    }

    //增加操作--要不要传递参数
    public void insertDept(Dept dept) throws Exception{ //把前端输入得部门信息封装到相应得实体类。
        Class.forName(driverName);
        Connection connection = DriverManager.getConnection(url,user,password);
        String sql = "insert into tb_dept values(null,?)";
        PreparedStatement ps = connection.prepareStatement(sql);
        ps.setObject(1,dept.getName());
        ps.executeUpdate();
    }

    //删除操作--根据id删除
    public void delete(int id)throws Exception{
        Class.forName(driverName);
        Connection connection = DriverManager.getConnection(url,user,password);
        String sql = "delete from tb_dept where id=?";
        PreparedStatement ps = connection.prepareStatement(sql);
        ps.setObject(1,id);
        ps.executeUpdate();
    }
}

 总结:

 再数据库中每张表封装了一个实体类和一个操作类。
   实体类---与表中列对应得类。
   操作类---对该表进行相应操作得类。--对表得增删改查。

包名: com.xxx.entity[实体类包]  com。xxx.dao[操作类包]

6. 使用try-catch-finally来处理异常

public List<Dept> findAll() {
        List<Dept> list = new ArrayList<>();
        try {
            Class.forName(driverName);
            connection = DriverManager.getConnection(url, user, password);
            String sql = "select * from tb_dept";
            ps = connection.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                //创建一个实体类对象 存储表中的一条记录。
                Dept d = new Dept();
                d.setId(rs.getInt("id"));
                d.setName(rs.getString("name"));
                list.add(d);
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        } finally {
            try {
                if(rs!=null){
                     rs.close();
                }
                if(ps!=null){
                     ps.close();
                }
                if(connection!=null){
                     connection.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        return list;
    }

 7.抽取一个dao的公共的父类。

1.实体类

public class Emp {
    private int id;
    private String name;
    private int age;
    private String job;
    private int salary;
    private Date entryDate;
    private int managerId;
    private int deptId;
    //getter setter toString 方法
}

 2.公共父类

public class BaseDao {
    //公共属性
    private String driverName="com.mysql.cj.jdbc.Driver";
    private String url="jdbc:mysql://localhost:3306/my0426?serverTimezone=Asia/Shanghai";
    private String user="root";
    private String password="001024";
    protected Connection connection=null;
    protected PreparedStatement preparedStatement=null;
    protected ResultSet resultSet=null;
    //获取连接对象方法
    public Connection getConnection()throws Exception{
        Class.forName(driverName);
        connection= DriverManager.getConnection(url,user,password);
        return connection;
    }
    //关闭资源方法
    public void closeAll(){
        try {
            if (resultSet!=null) {
                resultSet.close();
            }
            if (preparedStatement!=null){
                preparedStatement.close();
            }
            if (connection!=null){
                connection.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //增删改的方法
    public void edit(String sql,Object ... params){
        try {
            connection=getConnection();
            preparedStatement=connection.prepareStatement(sql);
            for (int i=0;i<params.length;i++){
                preparedStatement.setObject(i+1,params[i]);
            }
            preparedStatement.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
    }
}

 3.操作类

public class EmpDao extends BaseDao{
    //添加操作
    public void empInsert(Emp emp){
        String sql="insert into tb_emp values(null,?,?,?,?,?,?,?)";
        edit(sql,emp.getName(),emp.getAge(), emp.getJob(),
                emp.getSalary(),emp.getEntryDate(),emp.getManagerId(),emp.getDeptId());
    }
    //删除操作
    public void empDelete(int id){
        String sql="delete from tb_emp where id=?";
        edit(sql,id);
    }
    //修改操作
    public void empUpdate(Emp emp){
        String sql="update tb_emp set name=?,age=?,job=?,salary=?," +
                "entryDate=?,managerId=?,dept_id=? where id=?";
        edit(sql,emp.getName(),emp.getAge(), emp.getJob(), emp.getSalary(),
                emp.getEntryDate(),emp.getManagerId(),emp.getDeptId(),emp.getId());
    }
    //根据id查询
    public Emp empFineOne(int id){
        Emp emp =null;
        try {
            connection=getConnection();
            String sql="select * from tb_emp where id=?";
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setObject(1,id);
            resultSet = preparedStatement.executeQuery();
            while(resultSet.next()){
                emp=new Emp();
                emp.setId(resultSet.getInt("id"));
                emp.setName(resultSet.getString("name"));
                emp.setAge(resultSet.getInt("age"));
                emp.setJob(resultSet.getString("job"));
                emp.setSalary(resultSet.getInt("salary"));
                emp.setEntryDate(resultSet.getDate("entryDate"));
                emp.setManagerId(resultSet.getInt("managerId"));
                emp.setDeptId(resultSet.getInt("dept_id"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return emp;
    }
    //查询所有
    public List<Emp> empFineAll(){
        List<Emp> list = new ArrayList<>();
        try {
            connection=getConnection();
            String sql="select * from tb_emp";
            preparedStatement=connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            while(resultSet.next()){
                Emp emp = new Emp();
                emp.setId(resultSet.getInt("id"));
                emp.setName(resultSet.getString("name"));
                emp.setAge(resultSet.getInt("age"));
                emp.setJob(resultSet.getString("job"));
                emp.setSalary(resultSet.getInt("salary"));
                emp.setEntryDate(resultSet.getDate("entryDate"));
                emp.setManagerId(resultSet.getInt("managerId"));
                emp.setDeptId(resultSet.getInt("dept_id"));
                list.add(emp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return list;
    }
}

 4.测试类

package com.qy151.test;
import java.sql.Date;
import com.qy151.dao.EmpDao;
import com.qy151.entity.Emp;
import org.junit.Test;

import java.util.List;

public class Test1 {
    EmpDao dao = new EmpDao();
    //测试添加
    @Test
    public void testInsert(){
       // Date date=new Date("1990-02-04");
        //long time=date.getTime();
       // Date sqlDate=new Date(time);
        String s = "2000-10-09";
        Date sqlDate = Date.valueOf(s);
        Emp emp = new Emp();
        emp.setName("代克");
        emp.setAge(20);
        emp.setJob("开发");
        emp.setSalary(14000);
        emp.setEntryDate(sqlDate);
        emp.setManagerId(2);
        emp.setDeptId(1);
        dao.empInsert(emp);
    }
    //测试删除
    @Test
    public void testDelete(){
        dao.empDelete(16);
    }
    //测试修改
    @Test
    public void testUpdate(){
        String s ="1998-02-04";
        Date sqlTime =Date.valueOf(s);
        Emp emp = new Emp();
        emp.setId(18);
        emp.setName("王发财");
        emp.setAge(20);
        emp.setJob("销售");
        emp.setSalary(4000);
        emp.setEntryDate(sqlTime);
        emp.setManagerId(2);
        emp.setDeptId(1);
        dao.empInsert(emp);
    }
    //测试根据id查询
    @Test
    public void testFineOne(){
        Emp e = dao.empFineOne(2);
        System.out.println(e.getId()+"\t"+e.getName()+"\t"+e.getAge()+"\t"+e.getJob()+"\t"+e.getSalary()+
                "\t"+e.getEntryDate()+"\t"+e.getManagerId()+"\t"+e.getDeptId());
    }
    //测试查询所有
    @Test
    public void testFineAll(){
        List<Emp> list = dao.empFineAll();
        for(Emp e:list){
            System.out.println(e.getId()+"\t"+e.getName()+"\t"+e.getAge()+"\t"+e.getJob()+"\t"+e.getSalary()+
                    "\t"+e.getEntryDate()+"\t"+e.getManagerId()+"\t"+e.getDeptId());
        }
        //System.out.println(list);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值