Java连接Mysql(JDBC)

Java连接Mysql

JDBC (Java DataBase Connection) 是通过JAVA访问数据库.

java连接mysql数据库需要第三方的类, 大多数java的类包的后缀名都是jar压缩包.
导包: Project->property->ava build path->libaries->add external jars
中文版: 项目->属性->Java构建路径->库->添加外部JAR

mysql的第三方包网上都有, 自行百度.
如果使用的mysql的包是8.0以上的版本, 那么将不适用本文的内容,具体参见菜鸟教程

初始化驱动

	public class TestJDBC{
	public static void main(String[] args) {
		try {
			//驱动类com.mysql.jdbc.Driver
			//就在 mysql-connector-java-5.0.8-bin.jar中
			//如果没有导入包,就会抛出ClassNotFoundException
			Class.forName("com.mysql.jdbc.Driver");
			System.out.println("数据库驱动加载成功 !");
		}catch(ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

建立库连接

导入包

	import java.sql.Connection;
	import java.sql.DriverManager;
	import java.sql.SQLException;

创建与数据库的Connection连接必须提供的参数有: 数据库的ip: 127.0.0.1(本机)、端口号: 3306(mysql专用端口号)、数据库名称、编码格式、账号、密码.

	public static void main(String[] args) {
		Connection c = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			c = DriverManager
					.getConnection(
							"jdbc:mysql://127.0.0.1:3306/test1?characterEncoding=UTF-8",
							"root","mysql");
			System.out.println("连接成功,连接对象: "+c);
		}catch(ClassNotFoundException e) {
			e.printStackTrace();
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			if(c!=null)
				try {
					c.close();
				}catch(SQLException e) {
					e.printStackTrace();
				}
		}
	}
}

确保mysql数据库中有test1数据库, root是用户名, mysql是密码.
连接数据库后记得关闭连接, 养成好习惯.

执行SQL语句

Statement是用于执行SQL语句的, 增删改查.
导入包

	import java.sql.Statement;

保证在数据库中student1表的存在
先关闭Statement, 再关闭Connection

	public static void main(String[] args) {
		String name = "zhangsan";
		Connection c = null;
		Statement s = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			c = DriverManager
					.getConnection(
							"jdbc:mysql://127.0.0.1:3306/test1?characterEncoding=gbk",
							"root","mysql");
			s = c.createStatement(); //Statement是用于执行SQL语句的
//			String sql1 = "insert into student1 values(null,"+"name"+","+24+","+1+")";  使用string类型插入在数据库中无法显示
			String sql = "insert into student1 values(null,"+"'guigui'"+","+24+","+1+")";
			s.execute(sql);
			System.out.println("执行成功");
//			System.out.println("连接成功,连接对象: "+c);
		}catch(ClassNotFoundException e) {
			e.printStackTrace();
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {	//先关闭Statement, 再关闭Connection.
			if(s!=null)
				try {
					s.close();
					System.out.println("Statement关闭成功");
				}catch(SQLException e) {
					e.printStackTrace();
				}
			if(c!=null)
				try {
					c.close();
					System.out.println("Connection关闭成功");
				}catch(SQLException e) {
					e.printStackTrace();
				}
		}
	}
}

使用try-with-resource关闭连接

把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
因为Connection和Statement都实现了AutoCloseable接口, 所有也可以使用关闭流的方式.

	public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try(
        Connection c = DriverManager.getConnection(
							"jdbc:mysql://127.0.0.1:3306/test1?characterEncoding=gbk",
							"root","mysql");
		Statement s = c.createStatement();
        ){
        	String sql = "insert into student1 values(null,"+"'guigui'"+","+24+","+1+")";
			s.execute(sql);
			System.out.println("执行成功");
        }catch(SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
	}
}

在Java中的增删改查

具体过程参见上文

INSERT
SQL语句: INSERT INTO healthy VALUES(NULL, "wangliang", 81, 178.2);
	String sql = "insert into healthy values(null," + "'wangliang'" + "," + 81.0f + "," + 178.2f + ")";
    s.execute(sql);

使用常量和变量插入

	String name = "wangliang"
	int age = 24;
	String sql1 = "insert into student1 values(null,"+"'"+name+"'"+","+age+","+1+")"; 
DELETE
SQL语句: DELETE FROM healthy WHERE name = "wangliang";
	 String sql = "delete from healthy where name = 'wangliang'";
	 //字符串要用单引号 ' '
     s.execute(sql);
UPDATE
SQL语句: UPDATE healthy SET name="xiaohu" WHERE id = 3;
	String sql = "update healthy set name = 'xiaohu' where id = 3";
    s.execute(sql);
SELECT

select会返回数据, 所以和增删改有些不同之处
Java的中API的下标参数一般都是以0开始, 只有ResultSet和PreparedStatement的下标是从1开始.
查需要导入一个新的包

	import java.sql.ResultSet;
SQL语句: SELECT * FROM healthy
	String sql = "select * from healthy"
	ResultSet rs = new s.executeQuery(sql);
	while(rs.next()){
		int id = rs.getInt("id");// 使用字段名,也可以是rs.getInt(1)
        String name = rs.getString(2);// 按顺序查找
        System.out.printf("%d\t%s",id,name);
	}
	//Statement关闭的时候,会自动关闭ResultSet

SQL语句判断账号密码
使用where匹配数据, 如果有数据返回,密码正确. 反之错.
不要select全部数据再匹配, 这样不仅效率低, 内存也吃不消.

	String name = "root";
   	String password = "mysql";
    String sql = "select * from user_table where name ='"+name+"'and password = '"+password+"'";
    ResultSet rs = s.executeQuery(sql);
    if(rs.next()) System.out.println("登入成功");
    else System.out.println("账号密码错误");

PreparedStatement

和 Statement一样,PreparedStatement也是用来执行sql语句的
与创建Statement不同的是,需要根据sql语句创建PreparedStatement
除此之外,还能够通过设置参数,指定相应的值,而不是Statement那样使用字符串拼接.

	import java.sql.PreparedStatement;

	public static void main(String[] args) {
		String user = "admir";
		String password = "123456";
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        String sql = "insert into user_table values(null,?,?)";
        try(
        Connection c = DriverManager.getConnection(
							"jdbc:mysql://127.0.0.1:3306/test1?characterEncoding=gbk",
							"root","mysql");
//		Statement s = c.createStatement();
        PreparedStatement ps = c.prepareStatement(sql);
        ){
        	ps.setString(1, user);
        	//ps.setString(1, "admir");
        	ps.setString(2, password);
        	ps.setString(2, "123456");  	
        	ps.execute();
        	
        }catch(SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
	}

PreparedStatement的优点:

  • 可读性好
  • 预编译机制
  • 防止SQL注入式攻击
    PreparedStatemen使用的是参数设置, 所以可读性和维护性都比较容易; 和Statement不同, PreparedStatemen是预编译的机制, 在try中就已经预编译, 所以, 网络传输量比statement小, 数据库不需要再进行编译, 响应更快.

关于防注入攻击
如果用户提交的数据是 ‘wangliang’ OR 1=1
使用Statement进行拼接的语句将是select * from healthy where name = ‘wangliang’ OR 1=1
1=1恒成立, 那么将会把healthy表的所有数据全部查出来, 如果healthy的数据是海量的, 把几百万乃至几千万数据全部查找出来, 会让数据库负载爆, 响应变慢.

	String name = "";
	//中间过程省略
	ps.setString(1, name); //"select * from hero where name = "'wangliang' OR 1=1""
	ps.execute();

使用预编译Statement就可以杜绝SQL注入

PreparedStatement使用查询语句

execute与executeUpdate的区别

execute和executeUpdate都可以执行增加, 删除, 修改操作

    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } 
        try (Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test1?characterEncoding=GBK","root", "mysql");
            Statement s = c.createStatement();) {
 
            String sqlInsert = "insert into user_table values (null,'manager',"123456")";
            String sqlDelete = "delete from user_table where id = 5";
            String sqlUpdate = "update user_table set password = "going" where name = "manager""; 
            s.execute(sqlInsert);
            s.execute(sqlDelete);
            s.execute(sqlUpdate);
            s.executeUpdate(sqlInsert);
            s.executeUpdate(sqlDelete);
            s.executeUpdate(sqlUpdate);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

executeUpdate不能执行查询操作!
execute和executeUpdate返回的类型不同

	boolean isSelect = s.execute(sql);
	int number = s.executeUpdate(sql);

execute的返回类型是布尔型, 返回值为true代表执行的是select的SQL语句, 返回值是false代表执行的是insert, delete, update语句.
executeUpdate的返回类型是int型, 表示有多少条数据受到了影响.
再次强调, executeUpdate不能执行select操作!

表元数据查询

元数据: 数据库服务器相关的数据, 比如版本, 引擎, 字段类型.

	import java.sql.Connection;
	import java.sql.DatabaseMetaData;
	import java.sql.DriverManager;
	import java.sql.ResultSet;
	import java.sql.SQLException;
	import java.sql.Statement;

 	public static void main(String[] args) throws Exception {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
 
        try (Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test1?characterEncoding=GBK","root", "mysql");) {
            DatabaseMetaData dbmd = c.getMetaData();
  
            // 获取数据库服务器产品名称
            System.out.println("数据库产品名称:\t"+dbmd.getDatabaseProductName());
            // 获取数据库服务器产品版本号
            System.out.println("数据库产品版本:\t"+dbmd.getDatabaseProductVersion());
            // 获取数据库服务器用作类别和表名之间的分隔符 如test.user
            System.out.println("数据库和表分隔符:\t"+dbmd.getCatalogSeparator());
            // 获取驱动版本
            System.out.println("驱动版本:\t"+dbmd.getDriverVersion());
  
            System.out.println("可用的数据库列表:");
            // 获取数据库名称
            ResultSet rs = dbmd.getCatalogs();
  
            while (rs.next()) {
                System.out.println("数据库名称:\t"+rs.getString(1));
            }
  
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
  
    }

事务

事务指的是一个业务操作, 假如某一个事务操作有两个步骤: 1.在末尾添加一个新值; 2.删除首部值.
没有使用事务时, 添加值和删除值是分两步完成的, 当其中某一个有问题时(比如某一个函数写错了), 另一个操作还是会完成.
使用事务之后, 要么两个操作都成功, 要么两个操作都失败.

c.setAutoCommit(false);	//关闭自动提交
...
//业务代码
...
c.commit();				//手动提交	

通过 c.setAutoCommit(false);关闭自动提交
使用 c.commit();进行手动提交

在Mysql中,只有当表的类型是INNODB的时候,才支持事务,所以需要把表的类型设置为INNODB,否则无法观察到事务.

修改表的类型为INNODB的SQL:

alter table hero ENGINE  = innodb;

查看表的类型的SQL:

show table status from how2java; 

ORM

ORM=Object Relationship Database Mapping
对象和关系数据库的映射
一个对象对应数据库里的一条记录(不绝对)

DAO

DAO=DataAccess Object
数据访问对象
运用了ORM的思路, 把数据库相关的操作都封装在这个类里面,其他地方看不到JDBC的代码.

数据库连接池

数据库连接池与线程池的概念类似

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值