0


Java和MySQL的连接和操作(JDBC)

一、数据库的连接

1. 引入JDBC驱动程序

1.1 如何获取驱动程序

驱动程序由数据库提供商提供下载。
MySQL 的驱动下载地址:http://dev.mysql.com/downloads/
依次点击 Connector/J -> Platform Independent ,如然后下载下面那个
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2 如何在Java project 项目应用中添加数据库驱动 jar

① 把下载好的mysql-connector-j-8.0.31.jar拷贝到该项目中
在这里插入图片描述
ps:这里的lib文件夹是自己创建的(也可不创建)

② 然后点击Add as Library -> OK,把其添加到项目类路径下
在这里插入图片描述
这样就表示成功了

2. 连接操作

2.1 方式一:
@TestpublicvoidtestConnection1()throwsSQLException{//获取Driver实现类对象Driver driver =newcom.mysql.cj.jdbc.Driver();//jdbc:mysql协议//localhost:ip地址//3306: 默认端口//student_attendance_system: 数据库名称String url ="jdbc:mysql://localhost:3306/student_attendance_system";Properties info =newProperties();//将用户名和密码封装在Property
        info.setProperty("user","root");
        info.setProperty("password","0915");Connection conn = driver.connect(url, info);System.out.println(conn);}
2.2 方式二:队方式一的迭代(目的:为了使程序不出现第三方的API,使得程序有更好的移植性)
@TestpublicvoidtestConnection2()throwsException{//1.获取Driver实现类对象Class clazz =Class.forName("com.mysql.cj.jdbc.Driver");Driver driver =(Driver) clazz.newInstance();//2. 提供数据库连接String url ="jdbc:mysql://localhost:3306/student_attendance_system";//3. 提供连接需要的用户名和密码Properties info =newProperties();
        info.setProperty("user","root");
        info.setProperty("password","0915");//4. 获取连接Connection conn = driver.connect(url, info);System.out.println(conn);}
2.3 方式三:使用DriverManager替换Driver
@TestpublicvoidtestConnection3()throwsException{//1. 获取Driver实现类对象Class clazz =Class.forName("com.mysql.cj.jdbc.Driver");Driver driver =(Driver) clazz.newInstance();//2. 提供3个类的基本信息String url ="jdbc:mysql://localhost:3306/student_attendance_system";String user ="root";String password ="0915";//注册驱动DriverManager.registerDriver(driver);//获取连接Connection conn =DriverManager.getConnection(url, user, password);System.out.println(conn);}
2.4 方式4:可以只加载,不用显示的注册驱动(Driver)
@TestpublicvoidtestConnection4()throwsException{//1. 提供3个类的基本信息String url ="jdbc:mysql://localhost:3306/student_attendance_system";String user ="root";String password ="0915";//2. 加载DriverClass clazz =Class.forName("com.mysql.cj.jdbc.Driver");//也可以省略,因为META-INF/service的java.sql.Driver已经做过了//相较于方式三,可以省略如下操作://        Driver driver = (Driver) clazz.newInstance();//注册驱动//        DriverManager.registerDriver(driver);//获取连接Connection conn =DriverManager.getConnection(url, user, password);System.out.println(conn);}
2.5 方式五:将数据库连接需要的4个基本信息声明在配置文件中,通过读取配置文件的方式,获取连接

这里要在src文件夹下建立一个文件(jdbc.properties),可以其他名字,然后在该文件下输入数据库连接需要的属性
ps:一般连数据库用这种方式

文件内容:

driver=com.mysql.cj.jdbc.Driver 
url=jdbc:mysql://localhost:3306/test
user=root
password=0915

连接代码:

@TestpublicvoidtestConnection5()throwsException{// 1. 读取配置文件的4个信息InputStream is =SqlConnectionTest.class.getClassLoader().getResourceAsStream("src/jdbc.properties");Properties pros =newProperties();
        pros.load(is);String user = pros.getProperty("user");String password = pros.getProperty("password");String url = pros.getProperty("url");String driver = pros.getProperty("driver");//2. 加载驱动Class.forName(driver);Connection conn =DriverManager.getConnection(url, user, password);System.out.println(conn);}

3. 拓展

一般在项目中,数据库连接用一个工具类来会更好,这样只要在用的时候,直接调用就好了。

工具类:

packagesrc.Util;importsrc.SqlConnectionTest.SqlConnectionTest;importjava.io.IOException;importjava.io.InputStream;importjava.sql.*;importjava.util.Properties;/**
 * @author XiaoQ
 * @create 2022-12-11 19:26
 */publicclassJDBCUtils{/**
     * @Description 获取数据库的连接
     * @return Connection
     * @author XiaoQ
     * @date 2022/12/11 20:22
     */publicstaticConnectiongetConnection()throwsException{// 1. 读取配置文件的4个消息InputStream is =SqlConnectionTest.class.getClassLoader().getResourceAsStream("src/jdbc.properties");Properties pros =newProperties();
        pros.load(is);String user = pros.getProperty("user");String password = pros.getProperty("password");String url = pros.getProperty("url");String driver = pros.getProperty("driver");//2. 加载驱动Class.forName(driver);//3. 获取连接Connection conn =DriverManager.getConnection(url, user, password);return conn;}/**
     * @Description 关闭连接和Statement
     * @return
     * @author XiaoQ
     * @date 2022/12/11 20:25
     */staticpublicvoidcloseResource(Connection conn,Statement ps){try{if(ps !=null)
                ps.close();}catch(SQLException e){thrownewRuntimeException(e);}try{if(conn !=null)
                conn.close();}catch(SQLException e){thrownewRuntimeException(e);}}/**
     * @Description 关闭连接、Statement、ResultSet
     * @return 
     * @author XiaoQ
     * @date 2022/12/12 1:51
     */staticpublicvoidcloseResource(Connection conn,Statement ps,ResultSet res){try{if(ps !=null)
                ps.close();}catch(SQLException e){
            e.printStackTrace();}try{if(conn !=null)
                conn.close();}catch(SQLException e){
            e.printStackTrace();}try{if(res !=null)
                res.close();}catch(SQLException e){
            e.printStackTrace();}}}

二、数据库的操作

1. 数据库的增、删、改操作

1.1 普通的增加操作
@TestpublicvoidinsertTest(){Connection conn =null;PreparedStatement ps =null;try{// 1. 读取配置文件的4个消息InputStream is =SqlConnectionTest.class.getClassLoader().getResourceAsStream("src/jdbc.properties");Properties pros =newProperties();
            pros.load(is);String user = pros.getProperty("user");String password = pros.getProperty("password");String url = pros.getProperty("url");String driver = pros.getProperty("driver");//2. 加载驱动Class.forName(driver);//3. 获取连接
            conn =DriverManager.getConnection(url, user, password);//        System.out.println(conn);//4. 预编译sql语句,返回PreparedStatement的实例String sql ="insert into stu values(?, ?, ?)";
            ps = conn.prepareStatement(sql);//5. 填充占位符
            ps.setString(1,"2001");
            ps.setString(2,"小黑");
            ps.setString(3,"89");//6. 执行sql语句
            ps.execute();}catch(Exception e){thrownewRuntimeException(e);}finally{//7. 资源关闭try{if(ps !=null)
                    ps.close();}catch(SQLException e){thrownewRuntimeException(e);}try{if(ps !=null)
                    conn.close();}catch(SQLException e){thrownewRuntimeException(e);}}}
1.2 使用工具类后普通的修改操作

工具类JDBCUtils具体细节上面有

@TestpublicvoidupdateTest(){Connection conn =null;PreparedStatement ps =null;try{//获取数据库连接
            conn =JDBCUtils.getConnection();//预编译sql语句,返回PreparedStatementString sql ="update stu set name = ? where id = ?";
            ps = conn.prepareStatement(sql);//填充占位符
            ps.setString(1,"小小");
            ps.setObject(2,"1003");//执行操作
            ps.execute();}catch(Exception e){
            e.printStackTrace();}finally{//关闭资源JDBCUtils.closeResource(conn,ps);}}
1.3 通用操作(增、删、改)

操作

publicstaticvoidupdate(String sql,Object...args){Connection conn =null;PreparedStatement ps =null;try{//获取数据库连接
            conn =JDBCUtils.getConnection();//预编译sql语句,返回PreparedStatement
            ps = conn.prepareStatement(sql);//填充占位符for(int i =0; i < args.length; i++){
                ps.setObject(i +1, args[i]);}//执行操作
            ps.execute();}catch(Exception e){
            e.printStackTrace();}finally{//关闭资源JDBCUtils.closeResource(conn,ps);}}

测试

@TestpublicvoidcommonUpdateTest(){//增加操作String sql ="insert into stu values(?, ?, ?)";update(sql,"1005","小达",89);//修改操作
        sql ="update stu set name = ? where id = ?";update(sql,"小朱","1005");//删除操作
        sql ="delete from stu where id = ?";update(sql,"1005");}

2. 数据库的查询操作

2.1 对一个表的普通查询操作(基础不好或初学者用这个就够了,这个比较简单且比较好理解)
publicvoidtest1(){Connection conn =null;PreparedStatement ps =null;ResultSet resultSet =null;try{//获取数据库的连接
            conn =JDBCUtils.getConnection();//预编译sql语句String sql ="select * from stu where id = ?";
            ps = conn.prepareStatement(sql);//填充占位符
            ps.setObject(1,"2066");//执行,并返回结果集
            resultSet = ps.executeQuery();if(resultSet.next()){//获取列值String id = resultSet.getString(1);//获取第一个字段String name = resultSet.getString(2);//获取第二个字段int score = resultSet.getInt(3);//获取第三个字段//把列值封装到Student对象中Student stu =newStudent(id, name, score);System.out.println(stu);}}catch(Exception e){
            e.printStackTrace();}finally{//关闭连接JDBCUtils.closeResource(conn, ps, resultSet);}}
2.2 对一个表的通用查询操作

注意:针对于表的字段于类的属性名不相同的情况:

  1. 必须在声明sql语句时,使用类的属性名来给字段起别名
  2. 使用ResultSetMetaData时,需要用getColumnLabel()来替换getCoulmnName(),获取列的别名 说明:如果sql语句没有给字段起别名,那么gewtColumnLabel()得到就是列名

操作

publicStudentqueryForStu(String sql,Object...args){Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;try{//获取数据库连接
            conn =JDBCUtils.getConnection();//sql语句的预处理
            ps = conn.prepareStatement(sql);//占位符填充for(int i =0; i < args.length; i++){
                ps.setObject(i +1, args[i]);}//执行,并返回结果集
            rs = ps.executeQuery();//获取结果集的元数据ResultSetMetaData rsmd = rs.getMetaData();//通过ResultSetMetaData获取结果集的列数int columnCount = rsmd.getColumnCount();if(rs.next()){Student stu =newStudent();for(int i =0; i < columnCount; i++){//获取列值Object columnValue = rs.getObject(i +1);//getColumnName: 获取列的列名//getColumnLabel: 获取列的别名(推荐用这个,因为如果没查询起别名的,那么别名就是字段名)String columnName = rsmd.getColumnName(i +1);//给stu对象指定的columnName属性,赋值为columnValue,通过反射//注意:如果该表的字段(这里指stu表)不和该类(这里指Student类)的属性对应相同,那么sql查询语句就要给//      查询的字段起别名,防止反射后报错Field field =Student.class.getDeclaredField(columnName);//void setAccessible(boolean flag)//为反射对象设置可访问标志。flag为true表明屏蔽java语言的访问检查,使得对象的私有属性也可以被查询和设置
                    field.setAccessible(true);//访问不符合访问权限对象的成员属性
                    field.set(stu, columnValue);}return stu;}}catch(Exception e){
            e.printStackTrace();}finally{JDBCUtils.closeResource(conn, ps, rs);}returnnull;}

测试

@TestpublicvoidtestQueryForStu(){String sql ="select * from stu where id = ?";Student student =queryForStu(sql,"2066");System.out.println(student);

        sql ="select name from stu where id = ?";
        student =queryForStu(sql,"2001");System.out.println(student);}
2.3 针对不同表的查询,返回一条纪录(泛型)

操作:

/**
     * @Description 针对不同表的通用查询,返回一条记录
     * @return T
     * @author XiaoQ
     * @date 2022/12/12 0:50
     */public<T>TgetInstance(Class<T> clazz,String sql,Object...args){Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;try{//获取数据库连接
            conn =JDBCUtils.getConnection();//sql语句的预处理
            ps = conn.prepareStatement(sql);//占位符填充for(int i =0; i < args.length; i++){
                ps.setObject(i +1, args[i]);}//执行,并返回结果集
            rs = ps.executeQuery();//获取结果集的元数据ResultSetMetaData rsmd = rs.getMetaData();//通过ResultSetMetaData获取结果集的列数int columnCount = rsmd.getColumnCount();if(rs.next()){T t = clazz.newInstance();for(int i =0; i < columnCount; i++){//获取列值Object columnValue = rs.getObject(i +1);//getColumnName: 获取列的列名//getColumnLabel: 获取列的别名(推荐用这个,因为如果没查询起别名的,那么别名就是字段名)String columnName = rsmd.getColumnLabel(i +1);//给stu对象指定的columnName属性,赋值为columnValue,通过反射//注意:如果该表的字段(这里指stu表)不和该类(这里指Student类)的属性对应相同,那么sql查询语句就要给//      查询的字段起别名,防止反射后报错Field field = clazz.getDeclaredField(columnName);//void setAccessible(boolean flag)//为反射对象设置可访问标志。flag为true表明屏蔽java语言的访问检查,使得对象的私有属性也可以被查询和设置
                    field.setAccessible(true);//访问不符合访问权限对象的成员属性
                    field.set(t, columnValue);}return t;}}catch(Exception e){
            e.printStackTrace();}finally{JDBCUtils.closeResource(conn, ps, rs);}returnnull;}

测试

@Testpublicvoidtest(){String sql ="select * from stu where id = ?";Student student =getInstance(Student.class, sql,"1001");System.out.println(student);

        sql ="select t_id id, t_name name, salary from teacher where t_id = ?";Teacher teacher =getInstance(Teacher.class, sql,"4563");System.out.println(teacher);}
2.4 针对不同表的通用查询,返回多条记录(泛型)

操作

/**
     * @Description 对不同表的通用查询,返回多条记录
     * @return List<T>
     * @author XiaoQ
     * @date 2022/12/12 1:00
     */public<T>List<T>getForList(Class<T> clazz,String sql,Object...args){Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;try{//获取数据库连接
            conn =JDBCUtils.getConnection();//sql语句的预处理
            ps = conn.prepareStatement(sql);//占位符填充for(int i =0; i < args.length; i++){
                ps.setObject(i +1, args[i]);}//执行,并返回结果集
            rs = ps.executeQuery();//获取结果集的元数据ResultSetMetaData rsmd = rs.getMetaData();//通过ResultSetMetaData获取结果集的列数int columnCount = rsmd.getColumnCount();//创建集合对象ArrayList<T> list =newArrayList<T>();while(rs.next()){T t = clazz.newInstance();//处理结果集一行数据中的每一列:给t对象指定的属性赋值for(int i =0; i < columnCount; i++){//获取列值Object columnValue = rs.getObject(i +1);//getColumnName: 获取列的列名//getColumnLabel: 获取列的别名(推荐用这个,因为如果没查询起别名的,那么别名就是字段名)String columnName = rsmd.getColumnLabel(i +1);//给stu对象指定的columnName属性,赋值为columnValue,通过反射//注意:如果该表的字段(这里指stu表)不和该类(这里指Student类)的属性对应相同,那么sql查询语句就要给//      查询的字段起别名,防止反射后报错Field field = clazz.getDeclaredField(columnName);//void setAccessible(boolean flag)//为反射对象设置可访问标志。flag为true表明屏蔽java语言的访问检查,使得对象的私有属性也可以被查询和设置
                    field.setAccessible(true);//访问不符合访问权限对象的成员属性
                    field.set(t, columnValue);}
                list.add(t);}return list;}catch(Exception e){
            e.printStackTrace();}finally{JDBCUtils.closeResource(conn, ps, rs);}returnnull;}

测试

@Testpublicvoidtest1(){String sql ="select * from stu";List<Student> list =getForList(Student.class, sql);
        list.forEach(System.out::println);

        sql ="select t_id id, t_name name, salary from teacher where salary < ?";List<Teacher> list1 =getForList(Teacher.class, sql,1000);
        list1.forEach(System.out::println);}
标签: mysql java 数据库

本文转载自: https://blog.csdn.net/weixin_52068218/article/details/128281120
版权归原作者 %xiao Q 所有, 如有侵权,请联系我们删除。

“Java和MySQL的连接和操作(JDBC)”的评论:

还没有评论