文章目录
- 一、JDBC概述
- 二、JDBC开发前的准备
- 三、JDBC编程六步
- 四、获取数据库对象Statement(不常用)
- 五、从配置文件中读取连接数据库信息
- 六、用户登录判断
- 七、用户登录改进版,解决上诉问题(重点)
- 八、获取预编译数据库对象PreparedStatement(常用)
- 九、Statement和PreparedStatement的对比
- 十、Statement的用途
- 十一、事务机制演示(JDBC是会自动提交的)
- 十二、自己写一个工具类来建立连接(重点)
- 十三、用工具类建立连接,模糊查询
- 十四、批处理,一次插入100条数据
- 十五、悲观锁和乐观锁的概念
- 十六、学生信息管理系统(MVC设计模式)
- 十七、数据库连接池
- 十八、JDBCTemplat(一般和连接池一起用,简化我们的操作)
一、JDBC概述
二、JDBC开发前的准备
1.对文本编辑器方式发开
2.idea开发
先去官网下载驱动jre包
三、JDBC编程六步
1.注册驱动
方法一:
Driver driver =new com.mysql.jdbc.Driver();//多态,父类型引用子类型对象
//Driver driver =new oracle.jdbc.driver.OracleDriver(); //oracle的驱动
DrivaerManager.registerDriver(driver);//向 DriverManager 注册给定驱动程序
java.sql下DriverManager类:管理一组 JDBC 驱动程序的基本服务。
DriverManager类下的方法registerDriver
作用:
向 DriverManager注册给定驱动程序。新加载的驱动程序类应该调用 registerDriver 方法让 DriverManager 知道自己。
接口 Driver:每个驱动程序类必须实现的接口。每个驱动程序都应该提供一个实现 Driver 接口的实现类
方法二(常用):
2.获取连接
Connection conn=DriverManager.getConnection("jdbc:mysql://locasthost:3306/mysqldb","root","333");
DriverManager类下的方法getConnection
作用:
试图建立到给定数据库 URL 的连接。DriverManager 试图从已注册的 JDBC 驱动程序集中选择一个适当的驱动程序。
接口 Connection:与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。
1.URL介绍
3.获取数据库操作对象
接口Connection 的方法:createStatement(不常用)
作用:
创建一个Statement对象来将 SQL 语句发送到数据库。
接口 PreparedStatement继承自Statemnent:(常用)详见下
登录改进
作用:
SQL 语句被预编译并存储在
PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。
4.执行SQL语句
接口 Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。
接口Statement下的方法:executeUpdate
作用:
执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句
返回的是影响数据库的记录条数
接口Statement下的方法:executeQuery
作用:
执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。
接口 ResultSet:表示数据库结果集的数据表,通常通过执行查询数据库的语句生成
5.处理查询结果集
遍历结果集
接口ResultSet下的next方法
作用:
将光标从当前位置向下移一行。如果新的当前行有效,则返回 true;如果不存在下一行,则返回 false
接口ResultSet下的getString方法
以 Java 编程语言中
String 的形式获取此
ResultSet 对象的当前行中指定列的值。
四、获取数据库对象Statement(不常用)
1.插入数据
2.删除和修改数据
3.查询数据
五、从配置文件中读取连接数据库信息
实际开发中不建议把连接数据库的信息写死到java程序中
资源包文件:
六、用户登录判断
Main方法中
获取到的用户名和密码去和数据库的验证
用集合获取用户输入的用户名和密码
存在安全隐患(SQL注入)
七、用户登录改进版,解决上诉问题(重点)
接口 PreparedStatement继承自Statemnent:
SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。
八、获取预编译数据库对象PreparedStatement(常用)
1.添加数据
2.修改数据
3.删除数据
4.查询数据
九、Statement和PreparedStatement的对比
十、Statement的用途
(例子:自己输入升序还是降序的时候)
用PreparedStatement就不行,传值的时候,给的是’desc’,不是字符串所以无法拼接
十一、事务机制演示(JDBC是会自动提交的)
十二、自己写一个工具类来建立连接(重点)
因为每次写连接太过于麻烦,所以我们自己写一个工具类
用关闭资源的时候,如果遇到没有要关闭的就赋值null
十三、用工具类建立连接,模糊查询
十四、批处理,一次插入100条数据
必须先关闭自动提交
尽量使用Statement
十五、悲观锁和乐观锁的概念
十六、学生信息管理系统(MVC设计模式)
dao层
service层
举例:学生信息管理系统
先从test写,重下往上写
stu_entity
package stu_entity;
import java.util.Date;
/*
学生的字段:学号,姓名,年龄,性别,入学日期,班级编号,分数
*/
public class Student {
private Integer sid;
private String sname;
private Integer sage;
private String sgender;
private String enterdate;
private Integer cid;
private Double score;
public Student(){
}
public Student(Integer sid, String sname, Integer sage, String sgender, String enterdate, Integer cid, Double score) {
this.sid = sid;
this.sname = sname;
this.sage = sage;
this.sgender = sgender;
this.enterdate = enterdate;
this.cid = cid;
this.score = score;
}
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getSage() {
return sage;
}
public void setSage(Integer sage) {
this.sage = sage;
}
public String getSgender() {
return sgender;
}
public void setSgender(String sgender) {
this.sgender = sgender;
}
public String getEnterdate() {
return enterdate;
}
public void setEnterdate(String enterdate) {
this.enterdate = enterdate;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", sage=" + sage +
", sgender='" + sgender + '\'' +
", enterdate=" + enterdate +
", cid=" + cid +
", score=" + score +
'}';
}
}
stu_util
package stu_util;
import java.sql.*;
public class DBUtil {
private DBUtil(){}
static {
try {
Class.forName("org.mariadb.jdbc.Driver");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
}
//连接对象
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:mariadb://localhost:3306/mysqldb","root","mariadb");
}
//关闭资源
public static void close(Connection conn, Statement stat, ResultSet rs){
if(conn!=null){
try{
conn.close();
}catch (SQLException e){
e.printStackTrace();
}
} if(stat!=null){
try{
stat.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if(rs!=null){
try{
rs.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
}
stu_test
package stu_test;
import stu_view.StudentSystem;
/*
系统入口类,执行类
*/
public class StudentSystemTest {
public static void main(String[] args) {
StudentSystem system = new StudentSystem();
//启动系统
system.start();
while (true) {
//展示菜单
system.menu();
//选择菜单
int index = system.selectMenu();
switch (index) {
case 1:
//查看所有
system.selectAll();
break;
case 2:
//添加学生
system.addStudent();
break;
case 3:
//删除学生
system.delStudent();
break;
case 4:
//修改学生
system.updateStudent();
break;
case 5:
//查找学生
system.searchStudent();
break;
case 6:
//退出系统
system.exit();
break;
}
}
}
}
stu_view
package stu_view;
import stu_entity.Student;
import stu_service.StudentService;
import stu_service.stu_serviceimpl.StudentServiceImpl;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
/*
视图层
控制台内容的显示
*/
public class StudentSystem {
//用于接收键盘录入
private Scanner sc=new Scanner(System.in);
//控制层对象
private StudentService service=new StudentServiceImpl();
//启动系统
public void start(){
System.out.println("----------系统启动成功--------");
System.out.println("-------欢迎访问商品管理系统--------");
}
//退出系统
public void exit(){
System.out.println("-------您已退出商品管理系统--------");
System.exit(0);
}
//显示菜单
public void menu(){
System.out.println("-------1.查看所有--------");
System.out.println("-------2.添加学生--------");
System.out.println("-------3.删除学生--------");
System.out.println("-------4.修改学生--------");
System.out.println("-------5.查找学生--------");
System.out.println("-------6.退出系统--------");
}
//选择菜单
public int selectMenu(){
System.out.println("输入你的选择");
return sc.nextInt();
}
//查询所有
public void selectAll(){
List<Student> stus= service.selectAll();
//在视图层展示
if(stus==null || stus.size()==0){
System.out.println("没有学生信息");
}else {
System.out.println("所有的学生信息");
for(Student student:stus){
System.out.println(student);
}
}
System.out.println();
}
//键盘录入接收学生的信息
public Student createStudetn(){
System.out.println("输入学号");
int sid=sc.nextInt();
System.out.println("输入姓名");
String sname=sc.next();
System.out.println("输入年龄");
int sage=sc.nextInt();
System.out.println("输入性别 男,女");
String sgender=sc.next();
System.out.println("入学日期(格式:YYYY-MM-dd)");
String enterdate=sc.next();
System.out.println("班级编号");
int cid=sc.nextInt();
System.out.println("输入分数");
double score=sc.nextDouble();
Student stu=new Student(sid,sname,sage,sgender,enterdate,cid,score);
return stu;
}
//添加学生
public void addStudent(){
Student stu=createStudetn();
int count=service.addStudent(stu);
System.out.println("--------"+(count >0? "添加成功":"添加失败")+"---------");
System.out.println();
}
//删除学生
public void delStudent() {
System.out.println("输入要删除学生的学号");
int sid=sc.nextInt();
Student stu =new Student();
stu.setSid(sid);
int count=service.delStudent(stu);
System.out.println("--------"+(count >0? "删除成功":"删除失败")+"---------");
System.out.println();
}
//修改学生信息
public void updateStudent() {
System.out.println("输入要修改的学生学号");
int sid=sc.nextInt();
System.out.println();
System.out.println("--------输入修改后的内容--------");
Student stu=createStudetn();
int count =service.updateStudent(sid,stu);
System.out.println("--------"+(count >0? "修改成功":"修改失败")+"---------");
System.out.println();
}
/*
查找学生
1.可以根据学号查
2.可以根据姓名查
*/
public void searchStudent() {
System.out.println("--------------");
System.out.println("----请选择----");
System.out.println("1.根据学号查找");
System.out.println("2.根据姓名查找");
int input=sc.nextInt();
if(input==1){
System.out.println("请输入查找的学号");
int sid=sc.nextInt();
List<Student> list=service.findBysid(sid);
if(list==null || list.size()==0){
System.out.println("没有学生信息");
}else {
System.out.println("学生的信息为:");
for(Student student:list){
System.out.println(student);
}
}
System.out.println();
} else if(input==2){
System.out.println("请输入查找的姓名");
String sname=sc.next();
List<Student> list=service.findByname(sname);
if(list==null || list.size()==0){
System.out.println("没有学生信息");
}else {
System.out.println("学生的信息为:");
for(Student student:list){
System.out.println(student);
}
}
System.out.println();
}else {
System.out.println("输入错误");
}
}
}
stu_servic
package stu_service;
import stu_entity.Student;
import java.util.List;
/*
学生系统业务逻辑层的接口
*/
public interface StudentService {
// 查询所有学生
public abstract List<Student> selectAll();
//添加一个学生
int addStudent(Student stu);
//删除学生
int delStudent(Student stu);
//修改学生信息
int updateStudent(int sid, Student stu);
//根据学号查找
List<Student> findBysid(int sid);
//根据姓名查找
List<Student> findByname(String sname);
}
stu_servicImple
package stu_service.stu_serviceimpl;
import stu_dao.StudentDao;
import stu_dao.stu_dapimpl.StudentDaoImpl;
import stu_entity.Student;
import stu_service.StudentService;
import java.util.List;
/*
学生系统业务逻辑层的具体的实现类,所有的对学生操作的业务逻辑都在此处理
和视图层打交道
*/
public class StudentServiceImpl implements StudentService {
//通过dao层去访问数据库,并得到返回的结果
private StudentDao dao =new StudentDaoImpl();
//查询所有学生的信息
@Override
public List<Student> selectAll() {
String sql="select * from student";
return dao.selectStudent(sql);
}
//添加一个学生
@Override
public int addStudent(Student stu) {
String sql ="insert into student values(?,?,?,?,?,?,?)";
return dao.add(sql,stu);
}
//删除学生
@Override
public int delStudent(Student stu) {
String sql="delete from student where sid=?";
return dao.del(sql,stu);
}
//修改学生信息
@Override
public int updateStudent(int sid, Student stu) {
String sql ="update student set sid=?,sname=?,sage=?,sgender=?,enterdate=?,cid=?,score=? where sid=?";
return dao.update(sql,sid,stu);
}
//根据学号查找
@Override
public List<Student> findBysid(int sid) {
String sql="select * from student where sid=?";
return dao.findBysid(sid,sql);
}
//根据姓名查找
@Override
public List<Student> findByname(String sname) {
String sql="select * from student where sname=?";
return dao.findByname(sname,sql);
}
}
stu_dao
package stu_dao;
import stu_entity.Student;
import java.util.List;
/*
访问数据库的接口
对数据库的基本的各种操作
*/
public interface StudentDao {
//根据sql语句查询所有的学生
public abstract List<Student> selectStudent(String sql);
//添加学生
int add(String sql, Student stu);
//删除学生
int del(String sql, Student stu);
//修改学生信息
int update(String sql, int sid, Student stu);
//按学号查找
List<Student> findBysid(int sid, String sql);
//按姓名查找
List<Student> findByname(String sname, String sql);
}
stu_daoImpl
package stu_dao.stu_dapimpl;
import stu_util.DBUtil;
import stu_dao.StudentDao;
import stu_entity.Student;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
/*
//通过JDBC去访问数据库了,和数据库打交道
*/
public class StudentDaoImpl implements StudentDao {
//查询全部学生信息
@Override
public List<Student> selectStudent(String sql) {
List<Student> list=new ArrayList<>();
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try{
conn=DBUtil.getConnection();
ps=conn.prepareStatement(sql);
rs=ps.executeQuery();
while(rs.next()){
int sid=rs.getInt("sid");
String sname=rs.getString("sname");
int sage=rs.getInt("sage");
String sgender=rs.getString("sgender");
String enterdate =rs.getString("enterdate");
int cid=rs.getInt("cid");
double score=rs.getDouble("score");
Student student=new Student(sid,sname,sage,sgender,enterdate,cid,score);
list.add(student);
}
}catch (Exception e){
e.printStackTrace();
}finally {
DBUtil.close(conn,ps,rs);
}
return list;
}
//添加学生
@Override
public int add(String sql, Student stu) {
Connection conn=null;
PreparedStatement ps=null;
int flag=0;
try{
conn=DBUtil.getConnection();
ps=conn.prepareStatement(sql);
ps.setInt(1,stu.getSid());
ps.setString(2,stu.getSname());
ps.setInt(3,stu.getSage());
ps.setString(4,stu.getSgender());
ps.setString(5,stu.getEnterdate());
ps.setInt(6,stu.getCid());
ps.setDouble(7,stu.getScore());
int count =ps.executeUpdate();
return flag=count;
}catch (Exception e){
e.printStackTrace();
}finally {
DBUtil.close(conn,ps,null);
}
return flag;
}
//删除学生
@Override
public int del(String sql, Student stu) {
Connection conn=null;
PreparedStatement ps=null;
int flag=0;
try{
conn=DBUtil.getConnection();
ps=conn.prepareStatement(sql);
ps.setInt(1,stu.getSid());
int count =ps.executeUpdate();
return flag=count;
}catch (Exception e){
e.printStackTrace();
}finally {
DBUtil.close(conn,ps,null);
}
return flag;
}
//修改学生信息
@Override
public int update(String sql, int sid, Student stu) {
Connection conn=null;
PreparedStatement ps=null;
int flag=0;
try{
conn=DBUtil.getConnection();
ps=conn.prepareStatement(sql);
ps.setInt(1,sid);
ps.setString(2,stu.getSname());
ps.setInt(3,stu.getSage());
ps.setString(4,stu.getSgender());
ps.setString(5,stu.getEnterdate());
ps.setInt(6,stu.getCid());
ps.setDouble(7,stu.getScore());
ps.setInt(8,stu.getSid());
int count =ps.executeUpdate();
return flag=count;
}catch (Exception e){
e.printStackTrace();
}finally {
DBUtil.close(conn,ps,null);
}
return flag;
}
//通过学号查找
@Override
public List<Student> findBysid(int sid, String sql) {
List<Student> list=new ArrayList<>();
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try{
conn=DBUtil.getConnection();
ps=conn.prepareStatement(sql);
ps.setInt(1,sid);
rs=ps.executeQuery();
while(rs.next()){
String sname=rs.getString("sname");
int sage=rs.getInt("sage");
String sgender=rs.getString("sgender");
String enterdate =rs.getString("enterdate");
int cid=rs.getInt("cid");
double score=rs.getDouble("score");
Student student=new Student(sid,sname,sage,sgender,enterdate,cid,score);
list.add(student);
}
}catch (Exception e){
e.printStackTrace();
}finally {
DBUtil.close(conn,ps,rs);
}
return list;
}
//通过姓名查找
@Override
public List<Student> findByname(String sname, String sql) {
List<Student> list=new ArrayList<>();
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try{
conn=DBUtil.getConnection();
ps=conn.prepareStatement(sql);
ps.setString(1,sname);
rs=ps.executeQuery();
while(rs.next()){
int sid=rs.getInt("sid");
int sage=rs.getInt("sage");
String sgender=rs.getString("sgender");
String enterdate =rs.getString("enterdate");
int cid=rs.getInt("cid");
double score=rs.getDouble("score");
Student student=new Student(sid,sname,sage,sgender,enterdate,cid,score);
list.add(student);
}
}catch (Exception e){
e.printStackTrace();
}finally {
DBUtil.close(conn,ps,rs);
}
return list;
}
}
十七、数据库连接池
要使用这些连接池需要去下载他们指定的jar包
1.C3P0连接技术
配置文件(下载自带的,我们只需要修改一下连接参数即可)
2.Druid(德鲁伊)
配置文件(下载自带的,我们只需要修改一下连接参数即可)
3.工具类使用Druid连接池技术
public class DBUtil {
//1.定义成员变量 DataSoure
private static DataSource ds;
static {
try {
//1.加载配置文件
Properties pro=new Properties();
pro.load(DBUtil.class.getClassLoader().getResourceAsStream("druid.properties"));
//2.获取DataSource
ds=DruidDataSourceFactory.createDataSource(pro);
}catch (Exception e){
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//释放资源
public static void close(Connection conn, Statement stat, ResultSet rs){
if(conn!=null){
try{
conn.close();//归还连接
}catch (SQLException e){
e.printStackTrace();
}
} if(stat!=null){
try{
stat.close();//归还连接
}catch (SQLException e){
e.printStackTrace();
}
}
if(rs!=null){
try{
rs.close();//归还连接
}catch (SQLException e){
e.printStackTrace();
}
}
}
//获取连接池方法,供jdbcTemplat使用
public static DataSource getDataSource(){
return ds;
}
}
十八、JDBCTemplat(一般和连接池一起用,简化我们的操作)
需要去下载JRE包
jdbcTemplate会帮你连接和归还资源,因为传入一个DateSource
我们只需要关注SQL语句和操作SQL语句就行了
1.执行DML语句举例:
2.执行DQL语句举例:
1.用Map集合接收,只能接收一条数据
2.用List集合接收,先将每一条语句封装到Map集合,再把Map集合放到List集合中
3.通过一个对象接收,然后把对象给List集合,注意,对象中定义的类型必须要是封装类型(比如:int 类型要写成 Integer)(用一个对象接收是我们常用的)
4.一般用来操作分组函数的