JavaWeb入门 day02----JDBC

1.JDBC

1.什么是JDBC?

JDBC(Java Database Connectivity) Java连接数据库,可以使用Java语言连接数据库实现增删改查操作

2.JDBC核心思想

Java中定义访问数据库的接口,可以为多种关系型数据库提供统一的访问方式。由数据库厂商提供驱动实现类(Driver 数据库驱动)

3.环境搭建

1.在项目下新建lib文件,用于存放jar文件
2.将mysql驱动mysql-connector-java-5.1.7-bin.jar复制到项目的lib文件夹中
3.然后右键jar文件->Bulid Path->Add to Bulid Path

4.开发步骤
4.1连接数据库

	try {
		//1.注册驱动
		Class.forName("com.mysql.jdbc.Driver");
			//2.获得连接
		String url="jdbc:mysql://localhost:3306/testJdbc";
		String user="root";
		String password="123456";
		try {
			Connection connection=DriverManager.getConnection(url, user, password);
			if(connection!=null) {
				System.out.println("连接到数据库了-------------");
			}else {
				System.out.println("连接失败--------------------------");
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

//1.注册驱动
Class.forName(“com.mysql.jdbc.Driver”);
//2.获得连接
String url=“jdbc:mysql://localhost:3306/testJdbc”;
String user=“root”;
String password=“123456”;
Connection connection=DriverManager.getConnection(url, user, password);

注:url:连接地址 jdbc:mysql: 协议 localhost:本机 3306:端口 testJdbc:数据库的名字
user:用户名
password:密码
(根据具体自己的情况)
只要有上面两个步骤,并且connection对象不为null,那么就证明连接数据库成功了!!!

4.2操作数据库(增删改)

try {
			//1.注册驱动
			Class.forName("com.mysql.jdbc.Driver");
			
			//2.获得连接
			String url="jdbc:mysql://localhost:3306/testJdbc";
			String user="root";
			String password="123456";
			try {
				Connection connection=DriverManager.getConnection(url, user, password);
				if(connection!=null) {
					System.out.println("连接到数据库了-------------");
				}else {
					System.out.println("连接失败--------------------------");
				}
				
				//3.获得执行SQL语句的对象
				Statement statement=connection.createStatement();
				
				//4.编写SQL语句,执行SQL语句
				String sql="insert into Student(name,sex,age)values('小明','男',20)";//要用单引号
				int result=statement.executeUpdate(sql); 
				System.out.println(result);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		

//3.通过Connection对象获得Statement对象,用于对数据库进行访问
Statement statement=connection.createStatement();
//4.编写SQL语句,执行SQL语句
String sql=“insert into Student(name,sex,age)values(‘小明’,‘男’,20)”;//要用单引号
int result=statement.executeUpdate(sql);//1 说明对数据库的操作成功,受影响行数为1行

4.3处理结果,释放资源

try {
			//1.注册驱动
			Class.forName("com.mysql.jdbc.Driver");
			
			//2.获得连接
			String url="jdbc:mysql://localhost:3306/testJdbc";
			String user="root";
			String password="123456";
			try {
				Connection connection=DriverManager.getConnection(url, user, password);
				if(connection!=null) {
					System.out.println("连接到数据库了-------------");
				}else {
					System.out.println("连接失败--------------------------");
				}
				
				//3.获得执行SQL语句的对象
				Statement statement=connection.createStatement();
				
				//4.编写SQL语句,执行SQL语句
				String sql="insert into Student(name,sex,age)values('小红','女',20)";//要用单引号
				int result=statement.executeUpdate(sql);
//				System.out.println(result);
				
				//5.处理接收结果
				if(result==1) {
					System.out.println("对数据库的操作成功");
				}else {
					System.out.println("对数据库的操作失败");
				}
				
				//6.释放资源
				statement.close();
				connection.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

//5.处理接收结果
if(result==1) {
System.out.println(“对数据库的操作成功”);
}else {
System.out.println(“对数据库的操作失败”);
}
//6.释放资源 先开后关
statement.close();
connection.close();

注:以上六个步骤就是连接数据库、访问数据库,关闭数据库的核心。。。。(增删改,都是这个步骤,唯一不同的就是SQL语句)

案例(查询操作)

package com.le.JDBC;

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

public class QueryJDBC {

	public static void main(String[] args) throws Exception {
		//创建一个集合来存储多个Student对象
		List <Student> list=new ArrayList<Student>();
		
		try {
			//1.注册驱动类
			Class.forName("com.mysql.jdbc.Driver");
			
			//2.获取连接
			Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/testJdbc", "root", "123456");
			
			//3.创建Statement对象,用来发送SQL语句
			Statement statement=connection.createStatement();
			
			//4.执行SQL语句,并返回结果
			String sql="select * from Student";
			ResultSet resultSet=statement.executeQuery(sql);
			
			//5.处理结果集
			while(resultSet.next()) {//判断下一行是否有数据
				/**
				 * 也可以选择resultSet.getInt(1);编号从1开始,不过更提倡列名的方式
				 */
				int id=resultSet.getInt("id");
				String name=resultSet.getString("name");
				String sex=resultSet.getString("sex");
				int age=resultSet.getInt("age");
				
				//创建一个Student对象来存储数据
				Student stu=new Student(id,name,sex,age);
				list.add(stu);
				
			}
			
			for(Object o:list) {
				System.out.println(o);
			}
			//6.释放资源
			resultSet.close();
			statement.close();
			connection.close();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

登录案例:

package com.le.JDBC;

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

public class TestLogin {
	

	public static void main(String[] args) throws Exception {
		Scanner sc=new Scanner(System.in);
		//1.注册驱动类
		Class.forName("com.mysql.jdbc.Driver");
		
		System.out.println("请输入用户名");
		String username=sc.nextLine();
		System.out.println("请输入密码:");
		String password=sc.nextLine();
		
		//2.获取连接
		Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc", "root", "123456");
		
//		if(connection!=null) {
//			System.out.println("连接成功");
//		}else {
//			System.out.println("连接失败");
//		}
		
		//3.获取Statement对象,用来发送SQL语句
		Statement statement = connection.createStatement();
		
		//4.执行SQL语句,并获取返回结果
		String sql="select username,password from user where username='"+username+"' and password='"+password+"'";
		
		
		ResultSet resultSet=statement.executeQuery(sql);
	
		
		//5.处理结果集
		if(resultSet.next()) {
			System.out.println("登录成功");
//			System.out.println(resultSet.getString("username"));
		}else {
			System.out.println("登录失败");
		}
		
		//6.释放资源
		resultSet.close();
		statement.close();
		connection.close();

	}

}

上面这个登录的例子可以不用看。。。
注:这个 String sql=“select username,password from user where username=’”+username+"’ and password=’"+password+"’";可能会有SQL注入异常,所以PrepareStatement非常有必要。。。
PrepareStatement继承了Statement接口

PreparedStatement的作用:
1、预编译SQL语句,效率高
2.安全,避免SQL注入
3.可以动态的填充数据,执行多个同构的SQL语句

参数标记 ?
//1.预编译SQL语句
PreparedStatement pstmt=connection.prepareStatement(“select * from user where username=? and password=?”);

package com.le.JDBC;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class TestLogin2 {
	

	public static void main(String[] args) throws Exception {
		Scanner sc=new Scanner(System.in);
		//1.注册驱动类
		Class.forName("com.mysql.jdbc.Driver");
		
		System.out.println("请输入用户名");
		String username=sc.nextLine();
		System.out.println("请输入密码:");
		String password=sc.nextLine();
		
		//2.获取连接
		Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc", "root", "123456");
		
//		if(connection!=null) {
//			System.out.println("连接成功");
//		}else {
//			System.out.println("连接失败");
//		}
		
		//3.获取PreparedStatement对象,预编译SQL语句,动态绑定?,并为其赋值
		PreparedStatement pstmt=connection.prepareStatement("select * from user where username=? and password=?");
		
		pstmt.setString(1, username);
		pstmt.setString(2, password);
		System.out.println(pstmt);
		//4.并获取返回结果
		
		
		ResultSet resultSet=pstmt.executeQuery();
	
		
		//5.处理结果集
		if(resultSet.next()) {
			System.out.println("登录成功");
//			System.out.println(resultSet.getString("username"));
		}else {
			System.out.println("登录失败");
		}
		
		//6.释放资源
		resultSet.close();
		pstmt.close();
		connection.close();

	}

}

//3.获取PreparedStatement对象,预编译SQL语句,动态绑定?,并为其赋值
PreparedStatement pstmt=connection.prepareStatement(“select * from user where username=? and password=?”);
pstmt.setString(1, username);
pstmt.setString(2, password);
注:只有这两句不一样,其他的都一样。。。。

2.封装工具类
(重用性)------------------------------------------------------------------------------------------

jdbc的六个核心步骤:
1.加载驱动
2.获取连接对象
3.准备PreparedStatement对象,SQL 语句,.为占位符进行赋值
4.执行SQL语句,接收结果集,
5.处理结果集
6.关闭资源

注:上面1、2、6都是反复重复操作,所以可以将其封装成方法,调用即可。。。。

建议代码方式:
获取连接的方法 public static Connection getConnection(){};
释放资源的方法 public static void closeAll(Connection connection,Statement preparedStatement,ResultSet resultSet){};

package com.le.JDBC;

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

public class DbUtils {
	
	static {
		//1.注册驱动
				try {
					Class.forName("com.mysql.jdbc.Driver");//为了让其自始自终只加载一次,把它放在静态代码块中
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	}
	
	//获取连接的方法
	public static Connection getConnection() throws Exception {
		
		
		//2.获取连接
		Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc", "root", "123456");
		
		return connection;
	}
	
	
	//释放资源的方法
	public static void closeAll(Connection connection,Statement preparedStatement,ResultSet resultSet) throws Exception {
		if(resultSet!=null) {
			resultSet.close();
		}
		if(preparedStatement!=null) {
			preparedStatement.close();
		}
		if(connection!=null) {
			connection.close();
		}
	}

}

跨平台性:--------------------------------------------------------------------------------------------
在这里插入图片描述
在src下新建db.properties文件。。。

package com.le.jdbc1;

import java.io.IOException;
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 DbUtils {
	
	public static final Properties PROPERTIES=new Properties();//存储文件的map
	
	static {
		InputStream inputStream=DbUtils.class.getResourceAsStream("/db.properties");
	
		try {
			PROPERTIES.load(inputStream);
			Class.forName(PROPERTIES.getProperty("driver"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//获取连接
	public static Connection getConnection() {
		Connection connection=null;
		try {
			connection = DriverManager.getConnection(PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"),PROPERTIES.getProperty("password"));
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return connection;
	}
	
	//释放资源
	public static void closeAll(Connection connection ,Statement statement,ResultSet resultSet) {
		if(resultSet!=null) {
			try {
				resultSet.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(statement!=null) {
			try {
				statement.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(connection!=null) {
			try {
				connection.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

在这里插入图片描述
注:这是上面代码块重要的部分

下面的代码块为测试类

package com.le.jdbc1;

import java.sql.Connection;

public class TestDbUtils {

	public static void main(String[] args) {
		
		Connection connection = DbUtils.getConnection();
		
		if(connection!=null) {
			System.out.println("连接数据库成功");
		}else {
			System.out.println("连接失败");
		}
	}

}

3.DAO数据访问对象(Data Acess Object)

DAO实现了业务逻辑和数据库访问相分离。
1,对同一张表的所有操作封装在xxxDaoImpl对象中
2.根据增删改查的不同功能实现具体的方法

package person;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class PersonDaoImpl {
	
	//添加
	public int insert(Person person) {
		//1.获取连接
		Connection connection=DBUtils.getConnection();
		int result=0;
		
		PreparedStatement pstmt=null;
		try {
			//2.准备PreparedStatement对象
			 pstmt=connection.prepareStatement("Insert into person(name,age,bornDate,email,address)values(?,?,?,?,?)");
			
			//3.给占位符进行赋值
			pstmt.setString(1, person.getName());
			pstmt.setInt(2, person.getAge());
			pstmt.setObject(3,person.getBornDate());
			pstmt.setString(4, person.getEmail());
			pstmt.setString(5, person.getAddress());
			
			//4.执行SQL语句,并返回值
			 result=pstmt.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtils.closeAll(connection,pstmt, null);
		}
		
		
		
		return result;
	}
	
	//更新
	public int update(Person person) {
		//1.获取连接
		Connection connection=DBUtils.getConnection();
		int result=0;
		PreparedStatement pstmt=null;
		try {
			//2.准备PreparedStatement对象
			 pstmt=connection.prepareStatement("update person set name=?,age=?,bornDate=?,email=?,address=? where id=?");
		
			//3.给占位符进行赋值
			pstmt.setString(1, person.getName());
			pstmt.setInt(2, person.getAge());
			pstmt.setObject(3,person.getBornDate());
			pstmt.setString(4, person.getEmail());
			pstmt.setString(5, person.getAddress());
			pstmt.setInt(6, person.getId());
			
			//4.执行SQL语句,并返回结果
			result=pstmt.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtils.closeAll(connection, pstmt, null);
		}			
		return result;
	}
	
	//删除
	public int delete(int id) {
		
		//1.获取连接
		Connection connection = DBUtils.getConnection();
		
		PreparedStatement pstmt=null;
		int result=0;
		
		try {
			//2.准备PreparedStatement对象
			pstmt=connection.prepareStatement("delete from person where id=?");
			
			//3.给占位符进行赋值
			pstmt.setInt(1, id);
			
			//4.执行SQL语句,并返回结果值
			result=pstmt.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtils.closeAll(connection, pstmt, null);
		}
		
		return result;
	}
	
	//查询
	public Person select(int id) {
		
		//1.获取连接
		Connection connection=DBUtils.getConnection();
		
		PreparedStatement pstmt=null;
		ResultSet resultSet=null;
		Person person=null;
		
		try {
			//2.准备PreparedStatement对象
			pstmt=connection.prepareStatement("select * from person where id=?");
			
			//3.给占位符进行赋值
			pstmt.setInt(1, id);
			
			//4.执行SQL语句,并返回结果值
			resultSet=pstmt.executeQuery();
			
			if(resultSet.next()) {
				String name=resultSet.getString("name");
				int age=resultSet.getInt("age");
				Date bornDate=resultSet.getDate("bornDate");
				String email=resultSet.getString("email");
				String address=resultSet.getString("address");
				
				person=new Person(name, age, bornDate, email, address);

				
				
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtils.closeAll(connection, pstmt, resultSet);
		}
		
		return person;
	}
	
	//查询所有
	public List<Person> selectAll(){
		//1.获取连接
				Connection connection=DBUtils.getConnection();
				
				List<Person> list=new ArrayList<Person>();
				PreparedStatement pstmt=null;
				ResultSet resultSet=null;
				Person person=null;
				
				try {
					//2.准备PreparedStatement对象
					pstmt=connection.prepareStatement("select * from person  ");
					
					
					
					//4.执行SQL语句,并返回结果值
					resultSet=pstmt.executeQuery();
					
					while(resultSet.next()) {
						int id=resultSet.getInt("id");
						String name=resultSet.getString("name");
						int age=resultSet.getInt("age");
						Date bornDate=resultSet.getDate("bornDate");
						String email=resultSet.getString("email");
						String address=resultSet.getString("address");
						
						person=new Person(id,name, age, bornDate, email, address);
						list.add(person);
						
					}
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally {
					DBUtils.closeAll(connection, pstmt, resultSet);
				}
				
				return list;
		
	}

}

4.Date工具类

数据库中存储的数据类型为java.sql.Date。而Java应用层存储日期类型为java.util.Date,所以当我们用Java应用层的程序 插入 (比如上段代码中的插入方法) 带有日期的数据到数据库时,需要进行转换。

1.java.util.Date
Java语言常规应用层面的日期类型,可以通过字符串创建对应的时间对象,无法直接通过JDBC插入到数据库
2.java.sql.Date
不可以通过字符串创建对应的时间对象,只能通过毫秒值创建对象(1970年至今的毫秒值),可以通过JDBC插入到数据库

package person;

import java.text.ParseException;
import java.text.SimpleDateFormat;


public class DateUtils {
	
	private static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM");
	
	//1.字符串转换为util.Date
	public static java.util.Date toUtilDate(String str){
//		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM");
		java.util.Date utilDate=null;
		try {
			 utilDate = sdf.parse(str);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return utilDate;
		
	}
	
	//2.util.Date转换为sql.Date
	
	public static java.sql.Date toSqlDate(java.util.Date date ){
		long times=date.getTime();
		java.sql.Date sqlDate=new java.sql.Date(times);
		return sqlDate;
		
	}
	
	//3.util.Date转换为字符串的形式
	public static String toStingDate(java.util.Date date) {
//		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM");
		String stringDate=sdf.format(date);
		return stringDate;
		
	}

}

在上一个知识点中插入日期到数据库中的步骤就是:
1、日期是一个String类型 1999-01-01
2.在插入方法中,转换为util.Date
Person person=new Person("张",23,DateUtils.toUtilDate("1999-01-01"),"2678@qq.com","山东");
3.在PreparedStatement 中设置把util.Date转换成sql.Date
pstmt.setDate(3,DateUtils.toSqlDate(person.getBornDate()));

5.Service业务逻辑层

业务逻辑层是完成业务的,它是调用数据库访问层中的一个或多个方法。

package person;

public class PersonServiceImpl {
	
	//注册
	public void register(Person person) {
		PersonDaoImpl personDao=new PersonDaoImpl();
			//1.查询是否存在注册账户
		Person person2 = personDao.select(person.getName());
	
		if(person2==null) {
			//2.不存在就新增
			personDao.insert(person);
			System.out.println("注册成功");
		}else {//3,存在就返回
			System.out.println("注册失败");
		}
		
		
	}

}

6实现转账的案例

7.三层架构

1.表示层:
命名XXXView
职责:收集用户的数据和需求,展示数据(概括来说就是与用户打交道,让用户输入数据之类的操作)

2.业务逻辑层
命名:XXXServiceImpl
职责:数据加工处理,调用数据库访问层中的方法完成业务的实现,控制事务(一个业务的实现可能要调用数据库访问层中一个或多个方法)

3.数据库访问层
命名:XXXDaoImpl
职责:向业务层提供数据,将业务层加工后的数据同步到数据库中(总的来说,就是对数据库中表的操作,增删改查)

可以分别给这三层定义接口,为什么呢?比如当你定义了数据库访问层的接口,然后再让XXXDaoImpl 实现该接口,这样如果你再定义XXXDaoImpl2,实现该接口,就避免了你定义的方法不一致,需要在XXXServiceImpl做大量修改。好处就是你直接可以在XXXServiceImpl中
DaoInterface accountDao=new AccountDaoImpl();
直接改成
DaoInterface accountDao=new AccountDaoImpl2();
不需要做其他的操作。

注:其他层定义接口,用处都是一样,避免大量代码的更改。。。

三层架构项目的搭建
utils包存放工具类
entity包存放实体类
dao包存放dao接口,在dao包下的impl包存放的是dao接口实现类
service包存放service接口,在service包下的impl包存放的是service接口实现类
view包存放的是显示的,(main方法)

注:dao、service、view就是三层架构。。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值