如何用java程序优雅地操纵mysql数据库?

             


前言

    学习java有四个月了吧,操纵数据库的技术也从刚接触mysql数据库时“黑框框”操作,到用程序与数据库连接的原生sql操作,到现在的hibernate全自动化操作,我个人使用数据库的方式和感觉也和以前产生了区别,虽然现在很少写原生的sql语句,很少用dbutils,dbcp等技术去操作数据库了,但是我自己回顾操作数据库的历史,心中也突然会有想总结一下数据库操作的知识,当做给自己的复习,也希望能对新手朋友产生一些启迪。

------------------------------------------------------------------------------------------------------------------

  什么是数据库:

      mysql数据库是什么?我认为数据库最重要的作用就是存储数据,这些数据是有一定条理的,有一定关系的,即关系型数据库的特性。利用面向对象的思想,一个项目对应着一个或多个数据库,一个数据库中包含一张或多张表,一个实体类对应着一张表,实体类中的属性对应着表的结构,这就是数据库的功用。

------------------------------------------------------------------------------------------------------------------

  最原始的数据库操作: 

        最原始的数据库是通过命令行进行操作的。我们在下载好mysql数据库之后,将其配置好(网上找配置配好)以后,我们会在命令行里完成我们的第一个HelloWorld,从此刻起,mysql数据库几乎都在我们的学习中起到重要的作用,也是项目开发必不可少的。

        数据库的语句分为以下三种:

        1、数据定义语言(DDL)

        2、数据操作语言(DML)

        3、数据控制语言(DCL)

       * TIP:\S查询数据库的情况:

        

        

         1、常见的DDL:数据库的创建,修改,删除以及表的创建,修改,删除

                

        2、常见的DML:对数据库中表数据的修改(增删改查)

                                                                           

    


    3、常见的DCL:数据控制语言,即对数据库事务(trasaction)的控制,包括事务的提交(commit),事务的回滚(rollback),以及权限的管理等。


------------------------------------------------------------------------------------------------------------------

使用java程序对数据库进行操作

          看完了基础的数据库操作后,我们需要使用java程序对其进行CRUD操作,我们先从最原始的方法说起:

1、只使用jdbc这一个jar包,进行最原始的数据库连接并获取结果集



测试程序:

    

package com.iteason.demo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;

import org.junit.Test;

import com.iteason.domain.User;

public class TestJdbc {
	
	@Test
	public void fun1() throws Exception{
		//仅使用jdbc这一个jar包进行数据库的操作
		//1.定义四个配置
		String driver = "com.mysql.jdbc.Driver";
	    String url = "jdbc:mysql:///test";
	    String username = "root";
	    String password = "123";
	    
	    //2、注册数据库驱动
	    Class.forName(driver);
		//3、获得connection数据库连接
	    Connection conn = DriverManager.getConnection(url,username,password);
	    //4、获得数据库连接执行平台
	    Statement stat = conn.createStatement();
	    //5、书写sql语句
	    String sql = "select * from user";
	    //6、通过执行平台去执行查的操作并返还结果集
	    ResultSet query = stat.executeQuery(sql);
	    //7、查询结果集
	    while(query.next()){
	    	System.out.println(query.getString("uid"));
	    	System.out.println(query.getString("uname"));
	    }
	    //关流
	    stat.close();
	    conn.close();
	}
}

测试结果:

    


这就是第一个最原始的j用于连接mysql数据库的ava程序,在使用过程中我们会发现,每使用一个操作都会有重复性的代码,如四个配置文件的加载,以及获取connection连接的过程,以及关流的过程,所以我们抽取这些重复的代码为一个工具类,为它命名为JDBCUtils_V1:代码如下

package cn.iteason.demo01;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
 * @description 提供JDBC连接的工具类
 * @author Eason Pang
 * @version V1.0
 */
public class JDBCUtils_V1 {
   
	public static Connection getConnection(){
		Connection conn =null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection("jdbc:mysql:///test"
					,"root","123");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
	}
	//释放资源
	public static void release(Connection con,PreparedStatement pstmt,ResultSet rs){
		if(rs != null){
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(pstmt != null){
			try {
				pstmt.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(con != null){
			try {
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

用这个第一代工具类,   我们可以简化重复性代码的书写:

	@Test
	public void fun2() throws SQLException{
		 //获取连接
		Connection conn = JDBCUtils_V1.getConnection();
		//获得执行平台
		Statement stat = conn.createStatement();
		//书写sql语句
		 String sql = "select * from user";
	        //通过执行平台去执行查的操作并返还结果集
	        ResultSet query = stat.executeQuery(sql);
	        //查询结果集
	        while(query.next()){
	    	System.out.println(query.getString("uid"));
	    	System.out.println(query.getString("uname"));
	    }
	    //关流
	    query.close();
	    stat.close();
	    conn.close();
	}
}

在使用过程中我们发现,如果我们需要改变操作的数据库,我们需要修改工具类的源代码,而修改源代码并不是一个好的选择,所以我们需要创建一个properties配置文件,用来存储我们的配置信息,让工具类读取,如果我们需要修改数据库的配置信息,我们只需要修改properties配置文件而不需要修改工具类的源代码了,所以衍生出第二代工具类,我把他命名为JDBCUtils_V2

package cn.iteason.demo01;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;
/**
 * @description 使用properties配置文件进行配置
 * @author Eason Pang
 * @version V2.0
 */
public class JDBCUtils_V2 {
	//1.定义四个常量
	private static String driver;
    private static String url;
    private static String username;
    private static String password;
    static{
    	//2.调用ResourceBundle的getBundle方法绑定properties配置文件
    ResourceBundle bundle = ResourceBundle.getBundle("db");
    driver = bundle.getString("driver");
    url = bundle.getString("url");
    username = bundle.getString("username");
    password = bundle.getString("password");
    }
	public static Connection getConnection(){
		Connection conn =null;
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url
					,username,password);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
	}
	//释放资源
	public static void release(Connection con,PreparedStatement pstmt,ResultSet rs){
		if(rs != null){
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(pstmt != null){
			try {
				pstmt.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(con != null){
			try {
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

以下是存储在src下的配置文件db.properties的写法:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///test
username=root
password=123


二、使用连接池和DBUtils进行连接

    以上介绍的两种均为平时开发不使用的,因为过于麻烦,而查询出来的结果集还需要自己去获取,所以第三种方式就是使用apache的DBUtils jar包和DBCP连接池去操作数据库,这也是平时最常用的组合(连接池还可以为C3P0连接池),以下导的四个jar包:其中jdbc包是核心连接包,提供最基础的连接方法和驱动,是连接池和dbutils使用的基础,而dbcp和pool是DBCP连接池所需的jar包,dbutils为DBUtils的jar包,用于简化开发。



提供连接池的工具类:JDBCUTils_V3

package com.iteason.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;
import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
/**
 * @description 建立数据源方法,用于apac commons QueryRunner()进行绑定数据源
 * @author Eason Pang
 * @version V3.0
 */
public class JDBCUtils_V3 {
	//1.定义四个常量
	private static String driver;
    private static String url;
    private static String username;
    private static String password;
    public static BasicDataSource dataSource = new BasicDataSource();
    

    
    static{
    	//2.调用ResourceBundle的getBundle方法绑定properties配置文件
    ResourceBundle bundle = ResourceBundle.getBundle("db");
    driver = bundle.getString("driver");
    url = bundle.getString("url");
    username = bundle.getString("username");
    password = bundle.getString("password");
    }
	public static Connection getConnection(){
		Connection conn =null;
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url
					,username,password);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
	}
	//释放资源
	public static void release(Connection con,PreparedStatement pstmt,ResultSet rs){
		if(rs != null){
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(pstmt != null){
			try {
				pstmt.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(con != null){
			try {
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	static {
		//对连接池对象 进行基本的配置
		dataSource.setDriverClassName(driver); // 这是要连接的数据库的驱动
		dataSource.setUrl(url); //指定要连接的数据库地址
		dataSource.setUsername(username); //指定要连接数据的用户名
		dataSource.setPassword(password); //指定要连接数据的密码
		
	}
	
	/*
	 * 返回连接池对象
	 */
	public static DataSource getDataSource(){
		return dataSource;
	}
}

以下是使用V3工具类+DBUtils的代码,也是今后最常使用的代码之一:

@Test
	public void fun3() throws SQLException{
		//使用dbcp连接池获得连接,并且使用dbutils
		//绑定数据源
		QueryRunner runner = new QueryRunner(JDBCUtils_V3.getDataSource());
		String sql = "select * from user";
		List<User>list = runner.query(sql,new BeanListHandler<User>(User.class));
		System.out.println(list);
	}
}

运行结果:



可以看到,使用jdbc+dbcp+dbutils开发后,dao层需要书写的代码量减少了很多,查询的结果可以自动封装成对象,十分方便开发。



三、hibernate框架

    再来简单地介绍以下hibernate框架。hibernate框架是一款优秀的持久层框架,它采用的是ORM进行关系查询,让程序员以面向对象的方式进行查询,使用criteria查询则可以不写一行sql代码:

    

package com.iteason.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import com.iteason.domain.User;

public class hibernateTest {
	
	@Test
	public void fun1(){
		//获得配置
		Configuration conf = new Configuration().configure();
		//获得session工厂
		SessionFactory sf = conf.buildSessionFactory();
		//获得session
		Session session = sf.openSession();
		//开启事务
		Transaction tr = session.beginTransaction();
		
		//criteria查询
		Criteria criteria = session.createCriteria(User.class);
		List<User> list = criteria.list();
		System.out.println(list);
	}
}

查询结果:



        今天就简单地回顾以下这些关于数据库的知识,所有的关于数据库的操作我都只写了查询,因为只是为了大致地回顾以下这几个月来写sql的过程和变化,从繁到简,从自己写sql语句到hibernate的自动封装,其实都离不开最是原始的jdbc,今天就写到这里了,写得也是挺烂的,写的时候才发现自己其实挺多不清楚,顺便找了本mysql数据库的书复习了一遍,这些东西都不是什么高科技的东西,也不知道有没有人看,希望看到这篇“文章”的朋友永不言败,逆风的方向,更适合飞翔。


猜你喜欢

转载自blog.csdn.net/pbrlovejava/article/details/80342527