java开发JDBC

数据库
    SQL的分类
        DDL: 数据库的定义, 与数据库/表结构: create, drop, alter
        DML: 数据操纵语言: 操作表数据 insert update delete
        DCL: 数据控制语言: 设置用户的访问权限  安全
        DQL: 数据查询语言: select  from where
    数据库
        创建数据库: create database 数据库的名字
        删除数据库
            drop database 数据库名字
        修改数据库:
            alter database character set 字符集
        查看数据库:
            show databases; 查看所有数据库
            查看数据库定义: show create database 数据库名字
            select database();  查看当前正在使用的数据库
        选中数据库
            use 数据库的名字
    表结构的操作
        创建表
            create table 表名(
           列名 列的类型(长度) 约束,    
           列名2 列的类型(长度) 约束
           );

            列的约束
                主键约束: primary key
                唯一约束: unique
                非空约束: not null
        删除表
            drop table 表名
        修改表
            添加列
                alter table 表名 add 列名 列的类型 列的约束
            修改列
                alter table 表名 modify 列名 列的类型 列的约束
            修改列名
                alter table 表名 change 旧列名 新列名 列的类型 列的约束
            删除列
                alter table 表名 drop 列名
            修改表的字符集
                alter table 表名 character set 字符集
            修改表名
                rename table  旧表名 to 新的表名
        查看表
            show tables ; 查看当前数据库中所有的表名
            show create table 表名: 查看表的定义结构/创建语句
            desc 表名 : 查看表的结构
    表中数据的CRUD操作
        插入数据
            insert into 表名(列名1,列名2)values(值1,值2);
            insert into 表名 values(值1,值2);
            批量插入:insert into 表名values(值1,值2),(值1,值2),(值1,值2);
        删除数据
            delete from 表名 [where 条件]
            truncate table 表名: 先删除表,再重建表
        更新数据
            update 表名 set 列名=值, 列名=值 [where 条件]
        查询数据
            通用格式: select [distinct] [*] [列名1,列名2] from 表名 where 条件 group by ..having 条件过滤 order by 排序
            关系运算符
                <> 不等于
                != 不等于
            逻辑运算符
                and or not
            in 在范围中
            模糊查询 like
                _  表示的单个字符
                % 表示的是多个字符
            别名查询 as
            聚合函数
                sum : 求和
                avg()  : 平均值
                count() : 统计数量
                max() : 最大值
                min() : 最小值
            排序 order by
                asc  : ascend
                desc : descend
            分组 group by

 

  注意:建多表之间的建表原则   

一对多:商品与分类        
建表原则:在多的一方添加一个外键,指向一的一方的主键

多对多:老师,学生,课程
建表原则:建立一个中间表,将多对多的关系拆分成一对多的关系。中间表至少要有两个外键分别指向那两个表的主键

一对一:班级与班长,公民与身份证,国家与国企
建表原则:1:将一对一的情况按一对多处理,在任意一个表里添加一个外键,且外键必须是唯一的,并指向另一个表
          2:直接将两个表合成一个表
          3:将两个表的主键连接起来,让两个表里面的主键相等

实际用的不是很多:(拆表操作)
通常是将个人常用信息与不常用信息分开,减少表的臃

     

         

创建用户表(用户ID,账号,密码,电话)
CREATE TABLE USER(
  uid INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(30),
  PASSWORD VARCHAR(30),
  phone VARCHAR(11)
);
INSERT INTO USER VALUES(NULL,'admin','admin','10014');
INSERT INTO USER VALUES(NULL,'林俊杰','123456','10075');
INSERT INTO USER VALUES(NULL,'中国移动','456465','10086');
INSERT INTO USER VALUES(NULL,'中国联通','789789','10010');

SELECT*FROM USER;

 

订单表(订单编码,总价,订单时间,地址,外键用户id)
  CREATE TABLE orders(
  oid INT PRIMARY KEY AUTO_INCREMENT,
  sumprice INT NOT NULL,
  otime TIMESTAMP,
  address VARCHAR(100),
  uno INT,
  FOREIGN KEY(uno)REFERENCES USER(uid)    
  );
 
  INSERT INTO orders VALUES(NULL,'200',NULL,'西安',1);
  INSERT INTO orders VALUES(NULL,'250',NULL,'青海',1);
 
  SELECT*FROM orders;

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1:安装mysql

2:建一个数据库 student

3:   建一个表t_stu

JDBC

JAVA Database Connectivity java 数据库连接

  • 为什么会出现JDBC

SUN公司提供的一种数据库访问规则、规范, 由于数据库种类较多,并且java语言使用比较广泛,sun公司就提供了一种规范,让其他的数据库提供商去实现底层的访问规则。 我们的java程序只要使用sun公司提供的jdbc驱动即可。

使用JDBC的基本步骤

  1. 注册驱动

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

  2. 建立连接

    //DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb"); //2. 建立连接 参数一: 协议 + 访问的数据库 , 参数二: 用户名 , 参数三: 密码。 conn = DriverManager.getConnection("jdbc:mysql://localhost/student", "root", "root");

  3. 创建statement

    //3. 创建statement , 跟数据库打交道,一定需要这个对象 st = conn.createStatement();

  4. 执行sql ,得到ResultSet

    //4. 执行查询 , 得到结果集 String sql = "select * from t_stu"; rs = st.executeQuery(sql);

遍历结果集

//5. 遍历查询每一条记录 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);

  1. 释放资源

if (rs != null) {
        try {
            rs.close();
        } catch (SQLException sqlEx) { } // ignore 
        rs = null;
    }

	...

这里遇到几个异常问题:

java.lang.UnsupportedClassVersionError: org/apache/lucene/store/Directory : Unsupported major.minor version 52.0

是因为使用的jar包版本不对。这个5.2是什么呢?

  JDK不同的版本,编译出的class文件是不同的。通过查看分析class文件前几个字节,可以找到对应的关系,详细的参考官方,细微的版本之间可能有差异:

J2SE 7 = 51 (0x33 hex),

J2SE 6.0 = 50 (0x32 hex),

J2SE 5.0 = 49 (0x31 hex),

JDK 1.4 = 48 (0x30 hex),

JDK 1.3 = 47 (0x2F hex),

JDK 1.2 = 46 (0x2E hex),

JDK 1.1 = 45 (0x2D hex).

所以可以轻易的看出5.2是jdk8,而我的创建的工程使用的JDK7,所以将项目的JRE版本修改为JDK8即可

问题二:

Establishing SSL

这个问题就是因为由于mysql版本过高创建连接的时候会出现如下报告

解决办法:在mysql连接上加上&useSSL=true

如下:private static String url="jdbc:mysql://localhost/student?characterEncoding=utf8&useSSL=false";

ssl是一种加密技术在客户端连接数据库的中间做了加密,TCP/IP层中。

ssl的百度百科

Tue May 16 09:08:59 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.

问题三:

java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.

问题:

采用代码插入数据早8小时(比如现在时间是21:10:25,那么插入数据库中的数据时13:10:25)

者从数据库中取出数据时迟8小时(比如数据库中的时间是07:30,那么查询出来在页面显示的时间为15:30)

这都是因为安装mysql的时候时区设置的不正确
mysql默认的是美国的时区,而我们中国大陆要比他们迟8小时,采用+8:00格式

SHOW VARIABLES LIKE '%time_zone%';

SET GLOBAL time_zone='+8:00';

怎末解决

完整代码(最初版):

package jdbcDemo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/*
简易版
*/
public class MainTest {
	private static String url="jdbc:mysql://localhost/student?characterEncoding=utf8&useSSL=false";
	private static String user="admin";
	private static String password="admin";
	public static void main(String[] args) {
		ResultSet data=null;
		try {
			//1.注册驱动
			DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
			//2. 建立连接 参数一: 协议 + 访问的数据库 , 参数二: 用户名 , 参数三: 密码。
			Connection conn=DriverManager.getConnection(url, user, password);
			//3. 创建statement , 跟数据库打交道,一定需要这个对象
			Statement st=conn.createStatement();
			//4.得到数据
			String sql="select*from t_stu";
			data=st.executeQuery(sql);
			//遍历数组
			while(data.next()){
				int id=data.getInt("id");
				String name=data.getString("name");
				int age=data.getInt("age");
				System.out.println("id是:"+id+"   姓名是:"+name+"    年纪是:"+age);
			}
			data.close();
			st.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

}

 

 

###JDBC 工具类构建 ###

  1. 资源释放工作的整合
  1. 驱动防二次注册
DriverManager.registerDriver(new com.mysql.jdbc.Driver());

Driver 这个类里面有静态代码块,一上来就执行了,所以等同于我们注册了两次驱动。 其实没这个必要的。
//静态代码块 ---> 类加载了,就执行。 java.sql.DriverManager.registerDriver(new Driver());


	最后形成以下代码即可。

	Class.forName("com.mysql.jdbc.Driver");
  1. 使用properties配置文件

    1. 在src底下声明一个文件 xxx.properties ,里面的内容吐下:

      driverClass=com.mysql.jdbc.Driver url=jdbc:mysql://localhost/student name=root password=root

    2. 在工具类里面,使用静态代码块,读取属性

static{
		try {
			//1. 创建一个属性配置对象
			Properties properties = new Properties();
			InputStream is = new FileInputStream("jdbc.properties"); //对应文件位于工程根目录
			 
			//使用类加载器,去读取src底下的资源文件。 后面在servlet  //对应文件位于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();
		}
	}

​优化版:

package com.aming.test;

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

import com.aming.util.jdbcUtil;

public class jdbcTest_2 {
	
	public static void main(String[] args) {
		Connection conn  = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			//建立连接
			conn=jdbcUtil.getConn();
			//创建statement , 跟数据库打交道,一定需要这个对象
			st = conn.createStatement();
			//sql语句
			String sql="select*from t_stu";
			//获取数据
			rs=st.executeQuery(sql);
			//遍历获得数据
			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);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			jdbcUtil.release(conn, st, rs);
		}
	}

}
package com.aming.util;

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;

public class jdbcUtil {
	private static String driverClass=null;
	private static String url=null;
	private static String user=null;
	private static String password=null;
	
	static{
			try{
			//1. 创建一个属性配置对象
			Properties properties=new Properties();
//			InputStream is = new FileInputStream("jdbc.properties");  读取的是项目根目录下的jdbc.properties
			//使用类加载器,去读取src底下的资源文件。 后面在servlet
			InputStream is = jdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
			
			//导入输入流。
			properties.load(is);
			
			//获取配置数据
			driverClass =properties.getProperty("DriverClass");
			url =properties.getProperty("url");
			user =properties.getProperty("user");
			password =properties.getProperty("password");
			
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	/*
	 *注册驱动 
	 *建立连接
	 *@return Connection conn
	 */
	public static Connection getConn(){
		Connection conn=null;
		try {
			//注册驱动
			Class.forName(driverClass);
			//建立链接    参数一: 协议 + 访问的数据库 , 参数二: 用户名 , 参数三: 密码。
			conn=DriverManager.getConnection(url, user, password);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}
	public static void release(Connection conn, Statement st, ResultSet rs) {
		closeResultSet(rs);
		closeStatement(st);
		closeConnection(conn);
	}
	
	private static void closeConnection(Connection conn){
		try {
			if(conn!=null){
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			conn=null;
		}
	}
	private static void closeStatement(Statement st){
		try {
			if(st!=null){
				st.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			st=null;
		}
	}
	private static void closeResultSet(ResultSet rs){
		try {
			if(rs!=null){
				rs.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			rs=null;
		}
	}
}
DriverClass=com.mysql.cj.jdbc.Driver
url=jdbc\:mysql\://localhost/student?characterEncoding\=utf8&useSSL\=false
user=admin
password=admin

###数据库的CRUD sql###

  • insert

    INSERT INTO t_stu (NAME , age) VALUES ('wangqiang',28)

INSERT INTO t_stu VALUES (NULL,'wangqiang2',28)



	// 1. 获取连接对象
		conn = JDBCUtil.getConn();
		// 2. 根据连接对象,得到statement
		st = conn.createStatement();
		
		//3. 执行添加
		String sql = "insert into t_stu values(null , 'aobama' , 59)";
		//影响的行数, ,如果大于0 表明操作成功。 否则失败
		int result = st.executeUpdate(sql);
		
		if(result >0 ){
			System.out.println("添加成功");
		}else{
			System.out.println("添加失败");
		}
  • delete

    DELETE FROM t_stu WHERE id = 6

// 1. 获取连接对象
		conn = JDBCUtil.getConn();
		// 2. 根据连接对象,得到statement
		st = conn.createStatement();
		
		//3. 执行添加
		String sql = "delete from t_stu where name='aobama'";
		//影响的行数, ,如果大于0 表明操作成功。 否则失败
		int result = st.executeUpdate(sql);
		
		if(result >0 ){
			System.out.println("删除成功");
		}else{
			System.out.println("删除失败");
		}
  • query

    SELECT * FROM t_stu

// 1. 获取连接对象
		conn = JDBCUtil.getConn();
		// 2. 根据连接对象,得到statement
		st = conn.createStatement();

		// 3. 执行sql语句,返回ResultSet
		String sql = "select * from t_stu";
		rs = st.executeQuery(sql);

		// 4. 遍历结果集
		while (rs.next()) {
			String name = rs.getString("name");
			int age = rs.getInt("age");

			System.out.println(name + "   " + age);
		}
  • update

    UPDATE t_stu SET age = 38 WHERE id = 1;

// 1. 获取连接对象
		conn = JDBCUtil.getConn();
		// 2. 根据连接对象,得到statement
		st = conn.createStatement();
		
		//3. 执行添加
		String sql = "update t_stu set age = 26 where name ='qyq'";
		//影响的行数, ,如果大于0 表明操作成功。 否则失败
		int result = st.executeUpdate(sql);
		
		if(result >0 ){
			System.out.println("更新成功");
		}else{
			System.out.println("更新失败");
		}

###使用单元测试,测试代码###

  1. 定义一个类, TestXXX , 里面定义方法 testXXX.

  2. 添加junit的支持。

    右键工程 --- add Library --- Junit --- Junit4

  3. 在方法的上面加上注解 , 其实就是一个标记。

    @Test public void testQuery() { ... }

  4. 光标选中方法名字,然后右键执行单元测试。 或者是打开outline视图, 然后选择方法右键执行。

package com.aming.Main;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.PreparedStatement;

import org.junit.Test;

import com.aming.util.jdbcUtil;

public class jdbcInsert {
	
//下面进行数据库的增删改查,其都用单元测试来完成
	
//查询	
@Test
public void QueryTest(){
	Connection conn=null;
	PreparedStatement ps=null;
	ResultSet rs=null;
	try {
	//获取连接 
	conn= jdbcUtil.getConn();
	//sql语句
	String sql="select*from user where username=? and password=?";
	//获取Statement对象
	ps=conn.prepareStatement(sql);
	//赋值  
	ps.setString(1, "admin");
	ps.setString(2, "admin");
	//执行
	rs=ps.executeQuery();
	//解析数据
	if(rs.next()){
		System.out.println("登陆成功");
	 }else{
		System.out.println("登陆失败");
	 } 
	} catch (SQLException e) {
		e.printStackTrace();
	}finally{
		jdbcUtil.release(conn, ps, rs);
		
	}
	
}
//添加
@Test
public void InsertTest(){
	Connection conn=null;
	PreparedStatement ps=null;
	try {
	//获取连接 
	conn= jdbcUtil.getConn();
	//sql语句
	String sql="insert into user values(null,?,?,?)";
	//获取Statement对象
	ps=conn.prepareStatement(sql);
	//赋值  
	ps.setString(1, "赵玉池");
	ps.setString(2, "asdasd");
	ps.setString(3, "75156");
	//执行
	int rs=ps.executeUpdate();
	//解析数据
	if(rs>0){
		System.out.println("添加成功        添加了"+rs+"条数据");
	 }else{
		System.out.println("添加失败");
	 } 
	} catch (SQLException e) {
		e.printStackTrace();
	}finally{
		jdbcUtil.release(conn, ps);
		
	}
	
}
//修改
@Test
public void UpdateTest(){
	Connection conn=null;
	PreparedStatement ps=null;
	try {
	//获取连接 
	conn= jdbcUtil.getConn();
	//sql语句
	String sql="update user set password='110110' where username=?";
	//获取Statement对象
	ps=conn.prepareStatement(sql);
	//赋值  
	ps.setString(1, "赵玉池");
	//执行
	int rs=ps.executeUpdate();
	//解析数据
	if(rs>0){
		System.out.println("修改成功        修改了"+rs+"条数据");
	 }else{
		System.out.println("修改失败");
	 } 
	} catch (SQLException e) {
		e.printStackTrace();
	}finally{
		jdbcUtil.release(conn, ps);
		
	}
	
}


//删除
@Test
public void DeleteTest(){
	Connection conn=null;
	PreparedStatement ps=null;
	try {
	//获取连接 
	conn= jdbcUtil.getConn();
	//sql语句
	String sql="delete  from user where username=?";
	//获取Statement对象
	ps=conn.prepareStatement(sql);
	//赋值  
	ps.setString(1, "赵玉池");
	//执行
	int rs=ps.executeUpdate();
	//解析数据
	if(rs>0){
		System.out.println("删除成功        删除了"+rs+"条数据");
	 }else{
		System.out.println("删除失败");
	 } 
	} catch (SQLException e) {
		e.printStackTrace();
	}finally{
		jdbcUtil.release(conn, ps);
		
	}
	
}

}

###Dao模式###

Data Access Object 数据访问对象

  1. 新建一个dao的接口, 里面声明数据库访问规则
/**
	 * 定义操作数据库的方法
	 */
	public interface UserDao {
	
		/**
		 * 查询所有
		 */
		void findAll();
	}
  1. 新建一个dao的实现类,具体实现早前定义的规则
public class UserDaoImpl implements UserDao{

	@Override
	public void findAll() {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			//1. 获取连接对象
			conn = JDBCUtil.getConn();
			//2. 创建statement对象
			st = conn.createStatement();
			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.release(conn, st, rs);
		}
	}

}
  1. 直接使用实现

    @Test public void testFindAll(){ UserDao dao = new UserDaoImpl(); dao.findAll(); }

##Statement安全问题###

  1. Statement执行 ,其实是拼接sql语句的。 先拼接sql语句,然后在一起执行。
String sql = "select * from t_user where username='"+ username  +"' and password='"+ password +"'";

	UserDao dao = new UserDaoImpl();
	dao.login("admin", "100234khsdf88' or '1=1");

	SELECT * FROM t_user WHERE username='admin' AND PASSWORD='100234khsdf88' or '1=1' 

	前面先拼接sql语句, 如果变量里面带有了 数据库的关键字,那么一并认为是关键字。 不认为是普通的字符串。 
	rs = st.executeQuery(sql);

PrepareStatement

该对象就是替换前面的statement对象。

  1. 相比较以前的statement, 预先处理给定的sql语句,对其执行语法检查。 在sql语句里面使用 ? 占位符来替代后续要传递进来的变量。 后面进来的变量值,将会被看成是字符串,不会产生任何的关键字。
String sql = "insert into t_user values(null , ? , ?)";
		 ps = conn.prepareStatement(sql);
		 
		 //给占位符赋值 从左到右数过来,1 代表第一个问号, 永远你是1开始。
		 ps.setString(1, userName);
		 ps.setString(2, password);

 

##总结###:

  1. JDBC入门

  2. 抽取工具类 ###

  3. Statement CRUD ###

    演练crud

  4. Dao模式 ###

    声明与实现分开

  5. PrepareStament CRUD ###

    预处理sql语句,解决上面statement出现的问题

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值