JDBC

作者: 牛倩贱 | 来源:发表于2019-08-19 22:27 被阅读0次

    JDBC总结:

    1.jdbc入门

    2.抽取工具类

    3.jdbc与java代码联系的基本sql语句操作

    4.JDBC JUnit  增删改查操作

    5.Dao模式

    6.PrepareStatement 的增删改查操作


    1.JDBC入门程序

            先在SQLyog中创建数据库student,然后创建表,最后再和java程序进行连接。在项目目录下创建lib文件夹,找到mysql-connector-java-5.1.7-bin.jar文件粘贴进去。

            步骤分析:1.注册驱动  DriverManager.registerDriver(new com.mysql.jdbc.Driver());

                              2.建立连接 2.建立连接,将代码和student数据库连接起来。参数一:协议+数据库名字;参数二:                                用户名;参数三:密码;

                            Connection conn =DriverManager.getConnection("jdbc:mysql://localhost/student", "root", "root");

                                3.创建statement对象;Statement st = conn.createStatement();

                                4.执行查询,得到结果集

                                  //先写sql语句,在写查询函数

                                  String sql = "select * from t_student";

                                  //查询一个数据库,肯定会返回一个东西回来,用其接收一下就OK

                                  ResultSet rs = st.executeQuery(sql);

                                5.遍历查询到的每一条数据记录

                                6.释放对象资源

    初步代码如下:

    package com.jdbc.two;

    import java.sql.Connection;

    import java.sql.DriverManager;

    import java.sql.ResultSet;

    import java.sql.SQLException;

    import java.sql.Statement;

    public class JDBCtest {

    public static void main(String[] args) {

    try {

    //1.注册驱动

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

    //2.建立连接,将代码和student数据库连接起来

    //参数一:协议+数据库名字;参数二:用户名;参数三:密码

    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/student", "root", "root");

    //3.创建statement对象

    Statement st = conn.createStatement();

    //4.执行查询,得到结果集

    //先写sql语句,在写查询函数

    String sql = "select * from t_student";

    //查询一个数据库,肯定会返回一个东西回来,用其接收一下就OK

    ResultSet rs = st.executeQuery(sql);

    //要接受每一条数据,要遍历ResultSet

    //5.遍历查询每一条数据,ResultSet里有个方法next()方法

    while(rs.next()){

    int id = rs.getInt("id");

    String name = rs.getString("name");

    int age = rs.getInt("age");

    System.out.println("id="+id+"==name=="+name+"==age=="+age);

    }

    //释放对象,要反顺序释放

    rs.close();

    st.close();

    conn.close();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    }

    }


    2.JDBC程序优化改动

    a.首先将释放资源那部分,按照文档要求写进finally里面,当然写在finally里面之后那三个对象就得放在外面了,否则找不到声明,然后抓三个释放资源的异常,最好在写一个判空操作,防止执行到后面空指针。由于释放资源的过程比较繁琐且重复较多,所以可以写一个工具类来帮助我们更好的提高代码的可读性。

    工具类代码如下:package com.jdbc.two;

    import java.sql.Connection;

    import java.sql.ResultSet;

    import java.sql.SQLException;

    import java.sql.Statement;

    //jdbc工具类

    public class JDBCUtil {

    public static void relese(Connection conn,Statement st,ResultSet rs){

    closeRs(rs);

    closeSt(st);

    closeConn(conn);

    }

    //释放资源,按相反的顺序释放rs,st,conn

    private static void closeRs(ResultSet rs){

    try {

    if(rs != null){

    rs.close();

    }

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    rs = null;

    }

    }

    private static void closeSt(Statement st){

    try {

    if(st != null){

    st.close();

    }

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    st=null;

    }

    }

    private static void closeConn(Connection conn){

    try {

    if(conn != null){

    conn.close();

    }

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    conn = null;

    }

    }

    }


    3.JDBC工具类注册驱动,因为Driver这个类中有静态代码块,只要类加载了就会执行,所以等同于注册了两次,所以要修改为下面的那种

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

    Class.forName("com.mysql.jdbc.Driver");

    4.JDBC工具类连接对象整合

    5.JDBC工具类创建properties配置文件,因为修改数据库或者协议等等,如果每次在代码中修改容易出错,所以创建一个配置文件,用于辅助,配置文件代码如下:

    driverClass = com.mysql.jdbc.Driver

    url = jdbc:mysql://localhost/student

    name = root

    password = root

    6.JDBC工具类读取配置文件

            在读取配置文件时,需要注意的是,如果文件在src目录下就要用类加载器的方式来读取:

    InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("JDBC.properties");

            如果配置文件在项目根目录下,代码如下:

    InputStream is = new FileInputStream("JDBC.properties")


    7.工具类代码改善完成版

    package com.jdbc.two;

    import java.io.InputStream;

    import java.sql.Connection;

    import java.sql.DriverManager;

    import java.sql.ResultSet;

    import java.sql.SQLException;

    import java.sql.Statement;

    import java.util.Properties;

    //jdbc工具类

    public class JDBCUtil {

    static String driverClass = null;

    static String url = null;

    static String name = null;

    static String password = null;

    //配置文件properties要求在类加载时,所以写在静态代码块里

    static{

    try {

    //创建一个属性配置对象

    Properties properties = new Properties();

    //使用类加载器,去读取src底下的资源文件,对应文件位于src目录下

    InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("JDBC.properties");

    //导入输入流

    properties.load(is);

    //读取属性

    driverClass = properties.getProperty("driverClass");

    url = properties.getProperty("url");

    name = properties.getProperty("name");

    password = properties.getProperty("password");

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    //调用释放各个对象资源的方法,做一整合,统一调用

    public static void relese(Connection conn,Statement st,ResultSet rs){

    closeRs(rs);

    closeSt(st);

    closeConn(conn);

    }

    //方法重载以下,以便进行添加或其他数据库操作时使用 

    public static void relese(Connection conn,Statement st){

    closeSt(st); closeConn(conn);

    }

    //连接对象整合

    //获取连接对象

    public static Connection getconn(){

    Connection conn = null;

    try {

    /*//1.注册驱动,因为Driver这个类中有静态代码块,只要类加载了就会执行,所以等同于注册了两次,所以要修改为下面的那种

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

    Class.forName("com.mysql.jdbc.Driver");

    //2.建立连接,将代码和student数据库连接起来

    //参数一:协议+数据库名字;参数二:用户名;参数三:密码

    conn = DriverManager.getConnection("jdbc:mysql://localhost/student", "root", "root");*/

    //注册驱动

    Class.forName(driverClass);

    //建立连接

    conn = DriverManager.getConnection(url, name, password);

    } catch (Exception e) {

    }

    return conn;

    }

    //释放资源,按相反的顺序释放rs,st,conn

    private static void closeRs(ResultSet rs){

    try {

    if(rs != null){

    rs.close();

    }

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    rs = null;

    }

    }

    private static void closeSt(Statement st){

    try {

    if(st != null){

    st.close();

    }

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    st=null;

    }

    }

    private static void closeConn(Connection conn){

    try {

    if(conn != null){

    conn.close();

    }

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    conn = null;

    }

    }

    }


    8.JDBC与java代码的关联基本操作(sql语句)

    练习1:查询表中数据,代码如下:

    package com.jdbc.CRUD.test;

    import java.sql.Connection;

    import java.sql.ResultSet;

    import java.sql.Statement;

    import com.jdbc.CRUD.util.JDBCUtil;

    public class CRUDtest {

    public static void main(String[] args) {

    Connection conn = null;

    Statement st = null;

    ResultSet rs = null;

    try {

    //1.驱动注册建立连接(获取连接对象)

    conn = JDBCUtil.getconn();

    //2.根据连接对象,得到Statement

    st = conn.createStatement();

    //3.执行sql语句,返回ResultSet结果集

    String sql = "select * from t_student";

        rs = st.executeQuery(sql);

    //4.遍历结果集,接收数据

    while(rs.next()){

    String name = rs.getString("name");

    int age = rs.getInt("age");

    System.out.println(name+"    "+age);

    }

    } catch (Exception e) {

    e.printStackTrace();

    //5.释放资源

    }finally{

    JDBCUtil.relese(conn, st, rs);

    }

    }

    }


    9.使用JUnit执行单元测试(测试查询)

    例:测试上面的代码跑不跑的下去

    package com.jdbc.CRUD.test;

    import java.sql.Connection;

    import java.sql.ResultSet;

    import java.sql.Statement;

    import org.junit.Test;

    import com.jdbc.CRUD.util.JDBCUtil;

    /*使用junit执行单元测试

    * 1.定义一个类,Testxxx,类里面的方法一般也写testxxx

    * 2.添加JUnit支持

    * (右键工程,Build Path,Add Libraries,JUnit,next)

    * 这时工程目录下就已经有JUnit了

    * 3.使用测试,在所写方法的上面写上@Test

    *  @Test

    *  public void testQuery(){

    *  .............

    *  }

    * */

    public class TestDemo {

    @Test

    public void testQuery(){

    //将要测试的代码放进来

    Connection conn = null;

    Statement st = null;

    ResultSet rs = null;

    try {

    //1.驱动注册建立连接(获取连接对象)

    conn = JDBCUtil.getconn();

    //2.根据连接对象,得到Statement

    st = conn.createStatement();

    //3.执行sql语句,返回ResultSet结果集

    String sql = "select * from t_student";

        rs = st.executeQuery(sql);

    //4.遍历结果集,接收数据

    while(rs.next()){

    String name = rs.getString("name");

    int age = rs.getInt("age");

    System.out.println(name+"    "+age);

    }

    } catch (Exception e) {

    e.printStackTrace();

    //5.释放资源

    }finally{

    JDBCUtil.relese(conn, st, rs);

    }

    }

    }

    10.JUnit添加

    执行添加时Statement对象st的方法就不能是查询时候的excuteQuery了,要变为excuteUpdate;excuteUpdate(sql)返回的是添加了多少行的行数,所以用int来接收,就也不是以前的ResultSet对象了。

    代码如下:

    @Test

    public void testInsert(){

    Connection conn = null;

    Statement st = null;              //这里没有ResultSet了所以下面释放资源的时候也就不能继续调用哪个以前                                                  的方法了,需要在工具类里,重载一个Relese方法,public static void                                                        relese(Connection conn,Statement st){ closeSt(st); closeConn(conn); }

    try {

    //1.驱动注册建立连接(获取连接对象)

    conn = JDBCUtil.getconn();

    //2.根据连接对象,得到Statement

    st = conn.createStatement();

    //3.执行添加

    String sql = "insert into t_student values(null,'fanhaolan',20)";

    //因为executeUpdate方法返回的是添加的行数,所以如果大于0则添加成功,否则失败,用int接收

    int result = st.executeUpdate(sql);

    //4.查看结果,是否成功

    if(result>0){

    System.out.println("添加成功");

    }else{

    System.out.println("添加失败");

    }

    } catch (Exception e) {

    e.printStackTrace();

    }finally{

    JDBCUtil.relese(conn, st);

    }

    11.Junit,删除&更新

    删除:方法也是excuteUpdate(sql)

    sql语句,String sql  = delete from t_student where name='fanhaolan';

    int result = st.executeUpdate(sql);

    //4.查看结果,是否成功

    if(result>0){

    System.out.println("删除成功");

    }else{

    System.out.println("删除失败");

    }

    更新://Junit修改

    //String sql = "update t_student set age = 26 where name = 'fanhaolan'";

    12.JDBC    Dao模式

    以查询为例:

    新创建一个数据库User,创建表t_user,所以在等会写代码的时候一定要修改配置文件中的数据库名字

    a.先写一个接口,里面写增删改查的大方法,

    package com.jdbc.Dao;

    public interface UserDao {

    /*查询所有 * */

    void findAll();

    }

    b.在写一个类去实现这个接口,将里面的方法区重写,使其赋予你想赋予的功能(查询)

    package com.jdbc.Dao.impl;

    import java.sql.Connection;

    import java.sql.ResultSet;

    import java.sql.Statement;

    import com.jdbc.Dao.UserDao;

    import com.jdbc.util.JDBCUtil;

    public class UserDaoImpl implements UserDao{

    Connection conn = null;

    Statement st = null;

    ResultSet rs = null;

    @Override

    public void findAll() {

    try {

    //1.获取连接对象

    conn = JDBCUtil.getconn();

    //2.创建Statement对象

    st = conn.createStatement();

    //3.sql语句,得到结果集

    String sql = "select * from t_user";    //记得修改配置文件内数据库的名字,因为这里是新创建的数据库

    rs = st.executeQuery(sql);

    while(rs.next()){

    String username = rs.getString("username");

    String password = rs.getString("password");

    System.out.println(username+"  "+password);

    }

    } catch (Exception e) {

    e.printStackTrace();

    }finally{

    JDBCUtil.relese(conn, st, rs);

    }

    }

    }

    c.最后在写一个测试类,父类的对象指向子类的引用,用Junit完成测试

    package com.jdbc.test;

    import org.junit.Test;

    import com.jdbc.Dao.UserDao;

    import com.jdbc.Dao.impl.UserDaoImpl;

    public class TestUserDaoImpl {

    @Test

    public void testfindAll(){

    UserDao dao = new UserDaoImpl();

    dao.findAll();

    }

    }

    13.JDBC Statement安全问题引出PrepareStatement

            登录问题里,一定要先去查询数据库,然后匹配给定的用户名和密码等等,才能登录成功,但是Statement对象的执行,是先拼接sql语句,然后在一起执行,如果传入的参数变量中带有了数据库的关键字如or,那么他会一并的认为是关键字而不是字符串,假如写了String sql = "select * from t_user where username = '"+ username +"'and password = '"+ password +"'";目的是为了匹配登录的,但如果最后将传入的参数写成dao.login("admin",'1234567' or '1=1');这样写虽然我们自己知道这肯定是错误的,但是数据库会把这句话最终翻译成select * from t_user where username = 'admin' and password = '1234567' or '1=1';所以上述代码password的意思是1234567或1=1成立都可登录成功,也正是因为这样,才有了PrepareStatement。

            PrepareStatement,该对象就是替换前面的Statement对象,String sql = "select * from t_user where username = ? and password = ?";

    预先对sql语句执行语法的校验,?对应的内容,不管以后传什么参数进来,都会把它看成字符串

    还是以登录为例,代码书写为:

                                a.获取连接对象

                                b.创建PrepareStatement对象

                                    ..........

    //1.获取连接对象

    conn = JDBCUtil.getconn();

    //2.创建PrepareStatement对象

    String sql = "select * from t_user where username = ? and password = ?";

    //预先对sql语句执行语法的校验,?对应的内容,不管以后传什么参数进来,都会把它看成字符串

    PreparedStatement ps = conn.prepareStatement(sql);

    ps.setString(1, username);

    ps.setString(2, password);

    rs = ps.executeQuery();

    if(rs.next()){

    System.out.println("登录成功");

    }else{

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

    }

    14.JDBC PrepareStatement增删改查的所有写法代码

    package com.jdbc.Dao.impl;

    import java.sql.Connection;

    import java.sql.PreparedStatement;

    import java.sql.ResultSet;

    import java.sql.Statement;

    import com.jdbc.Dao.UserDao;

    import com.jdbc.util.JDBCUtil;

    public class UserDaoImpl implements UserDao{

    Connection conn = null;

    Statement st = null;

    ResultSet rs = null;

    @Override

    public void findAll() {

    try {

    //1.获取连接对象

    conn = JDBCUtil.getconn();

    //2.创建Statement对象

    st = conn.createStatement();

    //3.sql语句,得到结果集

    String sql = "select * from t_user";

    rs = st.executeQuery(sql);

    while(rs.next()){

    String username = rs.getString("username");

    String password = rs.getString("password");

    System.out.println(username+"  "+password);

    }

    } catch (Exception e) {

    e.printStackTrace();

    }finally{

    JDBCUtil.relese(conn, st, rs);

    }

    }

    @Override

    public void login(String username, String password) {

    Connection conn = null;

    Statement st = null;

    ResultSet rs = null;

    try {

    //1.获取连接对象

    conn = JDBCUtil.getconn();

    //2.创建PrepareStatement对象

    String sql = "select * from t_user where username = ? and password = ?";

    //预先对sql语句执行语法的校验,?对应的内容,不管以后传什么参数进来,都会把它看成字符串

    PreparedStatement ps = conn.prepareStatement(sql);

    ps.setString(1, username);

    ps.setString(2, password);

    rs = ps.executeQuery();

    if(rs.next()){

    System.out.println("登录成功");

    }else{

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

    }

    } catch (Exception e) {

    e.printStackTrace();

    }finally{

    JDBCUtil.relese(conn, st, rs);

    }

    }

    @Override

    public void insert(String username, String password) {

    Connection conn = null;

    PreparedStatement ps = null;

    try {

    conn = JDBCUtil.getconn();

    String sql = "insert into t_user values(null,?,?)";

    ps = conn.prepareStatement(sql);

    ps.setString(1, username);

    ps.setString(2, password);

    int result = ps.executeUpdate();

    if(result>0){

    System.out.println("添加成功");

    }else{

    System.out.println("添加失败");

    }

    } catch (Exception e) {

    e.printStackTrace();

    }finally{

    JDBCUtil.relese(conn, st);

    }

    }

    @Override

    public void delete(int id) {

    Connection conn = null;

    PreparedStatement ps = null;

    try {

    conn = JDBCUtil.getconn();

    String sql = "delete from t_user where id = ? ";

    ps = conn.prepareStatement(sql);

    ps.setInt(1, id);

    int result = ps.executeUpdate();

    if(result>0){

    System.out.println("删除成功");

    }else{

    System.out.println("删除失败");

    }

    } catch (Exception e) {

    e.printStackTrace();

    }finally{

    JDBCUtil.relese(conn, ps);

    }

    }

    @Override

    public void update(int id, String username) {

    Connection conn = null;

    PreparedStatement ps = null;

    try {

    conn = JDBCUtil.getconn();

    String sql = "update t_user set username = ? where id = ? ";

    ps = conn.prepareStatement(sql);

    ps.setString(1, username);

    ps.setInt(2, id);

    int result = ps.executeUpdate();

    if(result>0){

    System.out.println("修改成功");

    }else{

    System.out.println("修改失败");

    }

    } catch (Exception e) {

    e.printStackTrace();

    }finally{

    JDBCUtil.relese(conn, ps);

    }

    }

    }

    相关文章

      网友评论

          本文标题:JDBC

          本文链接:https://www.haomeiwen.com/subject/hcdbjctx.html