一、JDBC编程六步骤(重点)
整个项目只需做一次
- 项目中新增一个lib目录
- 在lib目录中添加mysql对应版本的jar包
- 将jar包作为仓库添加到当前项目中
每个类中需要做的操作
1. Class.forName();注册驱动
- mysql5:com.mysql.jdbc.Driver
- mysql8:com.mysql.cj.jdbc.Driver
2. Connection conn = DriverManager.getConnection(url, user, pass);//使用DriverManager对象的getConnection()方法获取数据库的连接对象
1. url代表连接的是哪台主机的哪个端口的哪个数据库
2. user以哪个用户来访问
3. pass是user的密码
3. String sql = "insert/update/delete or select"; //创建SQL语句
4. Statement stmt = conn.createStatement(); //使用sql语句作为参数放在conn的createStatement()方法中创建Statement对象
5. 执行sql语句,
- stmt.executeUpdate(sql);执行增删改的dml语句,返回的结果为受影响的行数int值
- stmt.executeQuery(sql);执行查询操作dql语句,返回的是结果集对象ResultSet
6. 关闭资源
1. 关闭ResultSet(如果有的话)
2. 关闭Statement对象
3. 关闭Connection对象
二、JDBC代码块
* Created by .
*/
public class TestJDBC {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 注册驱动,mysql5与mysql8的区别
Class.forName("com.mysql.jdbc.Driver");
// 使用DriverManager的静态方法getConnection(url, username, password)创建一个连接对象,
// 使用该连接对象就可以用java来访问数据库
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/school?serverTimezone=UTC&characterEncoding=UTF-8",
"school", "123456");
// 编写sql语句
String sql = "select * from tb_group";
// 使用Connnection对象的createStatement()方法创建一个Statement对象
stmt = conn.createStatement();
// 使用Statement对象的executeQuery(sql)将sql语句作为参数放入执行方法中进行sql语句的执行
// 如果sql语句是查询,则返回的是结果集ResultSet
// 如果sql预计是增删改,则返回的是受影响的行数int值
rs = stmt.executeQuery(sql);
// 对于结果集进行遍历,next()方法可以实现游标的下移
while (rs.next()){
// 通过结果集对象的getXXX()方法来获取结果集中每一行的数据
// getXxx(index),int类型的索引,下标从1开始,代码简单
// getXxx(columnLable), 字符串类型的类别,可读性更高
System.out.println(rs.getInt(1) + "\t" + rs.getString(2)
+ "\t" + rs.getString(3));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
// 资源的管理
// 先开的后关,后开的先关
try {
if(rs != null){
rs.close();
rs = null;
}
if(stmt != null){
stmt.close();
stmt = null;
}
if(conn != null){
conn.close();
conn = null;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
三、DBUtil将代码块分层
包的层次划分:
**
dao:数据访问对象,跟数据库相关的操作都可以放在此包下。 dao.impl:dao的实现类,完成对dao接口的所有方法的实现。 entity:实体类所在的包,包中的类要与数据库中的表对应,包括属性名和字段名。 util:工具包,里面放置各种工具。 test:对应各个类进行测试。
util.DButil
package util;
import java.sql.*;
public class DButil {
private static Connection conn = null;
//将注册驱动放入静态代码中以提高连接的速度
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接的对象
public static Connection getConnection(){
try {
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/school?useSSL=true&serverTimezone=UTC&characterEncoding=UTF-8",
"school",
"123456"
);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
//关闭连接资源
public static void closeConnection(ResultSet rs,Statement stmt,Connection conn) throws SQLException {
if(rs!=null){
rs.close();
rs=null;
}
if(stmt!=null){
stmt.close();
stmt=null;
}
if(conn!=null){
conn.close();
conn=null;
}
}
}
entity.Student
package entity;
public class Student {
private int sno;
private String sname;
private String ssex;
private String sbirthday;
private int cls;
public Student(int sno, String sname, String ssex, String sbirthday, int cls) {
this.sno = sno;
this.sname = sname;
this.ssex = ssex;
this.sbirthday = sbirthday;
this.cls = cls;
}
public Student() {
}
public int getSno() {
return sno;
}
public void setSno(int sno) {
this.sno = sno;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSsex() {
return ssex;
}
public void setSsex(String ssex) {
this.ssex = ssex;
}
public String getSbirthday() {
return sbirthday;
}
public void setSbirthday(String sbirthday) {
this.sbirthday = sbirthday;
}
public int getCls() {
return cls;
}
public void setCls(int cls) {
this.cls = cls;
}
@Override
public String toString() {
return "student{" +
"sno=" + sno +
", sname='" + sname + '\'' +
", ssex='" + ssex + '\'' +
", sbirthday='" + sbirthday + '\'' +
", cls=" + cls +
'}';
}
}
**
dao.IStudentDao
package dao;
import entity.Student;
import java.sql.SQLException;
import java.util.List;
public interface IStudentDao {
//分页查询,满足所有规则的student对象所组成的List集合
List<Student> getStudentByPage(int cp,int ps);
//查询所有的student对象封装到一个list集合中
List<Student> getAllStudents() throws SQLException;
//根据Sno得到一个student对象
Student getStudentBySno(int sno) throws SQLException;
//向数据库中添加一个新的student对象
int addStudent(Student student) throws SQLException;
//在数据库中修改某条记录
int updateStudent(Student student) throws SQLException;
//根据sno删除某条记录
void delStudent(int sno) throws SQLException;
}
**
dao.impl.StudentDaoImpl
package dao.impl;
import dao.IStudentDao;
import entity.Student;
import util.DButil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class StudentDaoImpl implements IStudentDao {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
@Override
public List<Student> getStudentByPage(int cp, int ps) {
List<Student> list = null;
conn = DButil.getConnection();
int si = (cp-1)*ps;
String sql = String.format("select * from student limit %d,%d",si,cp);
//创建statement对象
try {
stmt = conn.createStatement();
//执行sql语句
rs = stmt.executeQuery(sql);
if(rs!=null){
list = new ArrayList<>();
Student student = null;
while (rs.next()){
//获取student对象
student = new Student(rs.getInt(1),rs.getString(2),rs.getString(3),
rs.getString(4),rs.getInt(5));
//将student对象放入集合中
list.add(student);
}
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
DButil.closeConnection(rs,stmt,conn);
} catch (SQLException e) {
e.printStackTrace();
}
}
return list;
}
@Override
public List<Student> getAllStudents() throws SQLException {
List<Student> list = null;
//创建连接对象
conn = DButil.getConnection();
//创建sql语句
String sql = " select * from student";
try {
//创建Statement对象
stmt = conn.createStatement();
//执行sql语句
rs = stmt.executeQuery(sql);
if(rs!=null){
list = new ArrayList<>();
Student student = null;
while (rs.next()){
student = new Student(rs.getInt(1),
rs.getString(2),rs.getString(3),
rs.getString(4),rs.getInt(5)
);
list.add(student);
}
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DButil.closeConnection(rs,stmt,conn);
}
return list;
}
@Override
public Student getStudentBySno(int sno) throws SQLException {
Student student = null;
conn = DButil.getConnection();
String sql = String.format(" select * from student where sno = %d",sno);
//创建statement对象
try {
stmt = conn.createStatement();
//执行sql语句
rs = stmt.executeQuery(sql);
while (rs.next()){
student = new Student(rs.getInt(1),rs.getString(2),rs.getString(3),
rs.getString(4), rs.getInt(5)
);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DButil.closeConnection(rs,stmt,conn);
}
return student;
}
@Override
public int addStudent(Student student) throws SQLException {
int i = 0;
conn = DButil.getConnection();
String sql = String.format("insert into student (sno,sname,ssex,sbirthday,cls) " ,
"values (%d,%s,%s,%s,%d)",
student.getSno(),student.getSname(),student.getSsex(),
student.getSbirthday(),student.getCls()
);
try {
stmt = conn.createStatement();
i = stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}finally {
DButil.closeConnection(rs,stmt,conn);
}
return i;
}
@Override
public int updateStudent(Student student) throws SQLException {
int i = 0;
conn = DButil.getConnection();
String sql = String.format("update student set sname = '%s',ssex= '%s',sbirthday ='%s',cls = %d, where sno = %d",
student.getSname(),student.getSsex(),student.getSbirthday(),student.getCls(),
student.getSno()
);
try {
stmt = conn.createStatement();
i = stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}finally {
DButil.closeConnection(rs,stmt,conn);
}
return i;
}
@Override
public void delStudent(int sno) throws SQLException {
conn = DButil.getConnection();
String sql = String.format("delete from student where sno = %d",sno);
try {
stmt = conn.createStatement();
stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}finally {
DButil.closeConnection(rs,stmt,conn);
}
}
}
**
test.TestStudentDaoImpl
package test;
import dao.IStudentDao;
import dao.impl.StudentDaoImpl;
import entity.Student;
import org.junit.Test;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class StudentDaoImplTest {
IStudentDao iStudentDao = new StudentDaoImpl();
List<Student> list = new ArrayList<>();
Student student = new Student();
@Test
public void getStudentByPage(){
list = iStudentDao.getStudentByPage(1,5);
for (Student student1 : list) {
System.out.println(student1);
}
}
@Test
public void getAllStudent() throws SQLException {
list = iStudentDao.getAllStudents();
for (Student student2 : list) {
System.out.println(student2);
}
}
@Test
public void getStudentBySno() throws SQLException {
student = iStudentDao.getStudentBySno(101);
System.out.println(student);
}
@Test
public void addStudent() throws SQLException {
student = new Student(122,"王莉","女","1999-08-17",95033);
iStudentDao.addStudent(student);
list = iStudentDao.getAllStudents();
for (Student student1 : list) {
System.out.println(student1);
}
}
@Test
public void updateStudent() throws SQLException {
int sno = 110;
student = new Student(sno,"刘晓明","男","2008-02-09",95034);
iStudentDao.updateStudent(student);
list = iStudentDao.getAllStudents();
for (Student student1 : list) {
System.out.println(student1);
}
}
@Test
public void delStudent() throws SQLException {
iStudentDao.delStudent(108);
list = iStudentDao.getAllStudents();
for (Student student1 : list) {
System.out.println(student1);
}
}
}
四、druid连接池进行分层
准备工作:需在项目中引入以上三个jar包,每个项目只做一次。
db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/school?useSSL=true&serverTimezone=UTC&characterEncoding=UTF-8
user=school
pass=123456
util.Env
package util;
import java.io.IOException;
import java.util.Properties;
/**
* Env单例模式用来动态获取不同数据库连接字符串
*/
public class Env extends Properties {
private static Env instance = null;
private Env(){
try {
// Property的load方法用来加载指定的properties属性文件
load(getClass().getResourceAsStream("/db.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 单例设计模式在该类的外界通过该方法可以得到当前类的实例对象
* @return 当前类的实例对象
*/
public static Env getInstance(){
//如果当前实例为空,则去调用当前类的私有构造器构造该对象
if(instance==null){
instance = new Env();
}
//返回该对象
return instance;
}
}
util.DBPoolUtil
package util;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.Properties;
/**
* 数据库连接池数据源工具类,用来动态获取数据源
*/
public class DBPoolUtil {
private static DruidDataSource dataSource = null;
static {
Properties p = new Properties();
try {
//加载Properties文件
p.load(DBPoolUtil.class.getResourceAsStream("/db.properties"));
//借助Properties对象创建一个dataSource对象
dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(p);
//分别设置dataSource连接的4个字符串
dataSource.setUrl(Env.getInstance().getProperty("url"));
dataSource.setDriverClassName(Env.getInstance().getProperty("driver"));
dataSource.setUsername(Env.getInstance().getProperty("user"));
dataSource.setPassword(Env.getInstance().getProperty("pass"));
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 工具方法,用来动态获取DataSource对象
* @return 整个dataSource数据源对象
*/
public static DataSource getDataSource(){
return dataSource;
}
}
entity.Student
package entity;
import java.util.Date;
public class Student {
private String sno;
private String sname;
private String ssex;
private String sbirthday;
private int cls;
public Student(String sno, String sname, String ssex, String sbirthday, int cls) {
this.sno = sno;
this.sname = sname;
this.ssex = ssex;
this.sbirthday = sbirthday;
this.cls = cls;
}
public Student() {
}
public String getSno() {
return sno;
}
public void setSno(String sno) {
this.sno = sno;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSsex() {
return ssex;
}
public void setSsex(String ssex) {
this.ssex = ssex;
}
public String getSbirthday() {
return sbirthday;
}
public void setSbirthday(String sbirthday) {
this.sbirthday = sbirthday;
}
public int getCls() {
return cls;
}
public void setCls(int cls) {
this.cls = cls;
}
@Override
public String toString() {
return "Student{" +
"sno='" + sno + '\'' +
", sname='" + sname + '\'' +
", ssex='" + ssex + '\'' +
", sbirthday=" + sbirthday +
", cls=" + cls +
'}';
}
}
dao.IStudentDao
package dao;
import entity.Student;
import java.util.List;
public interface IStudentDao {
/**
* 得到所有的Student集合
* @return 所有的Student集合
*/
List<Student> getAllStudent();
/**
* 分页查询得到对应页数的Student对象集合
* @param cp 当前第几页
* @param ps 每页最大条目数
* @return 所有Student对象的集合
*/
List<Student> getStudentByPage(int cp,int ps);
/**
* 通过sno得到该sno所对应的Student对象
* @param sno 编号
* @return sno 对应的对象
*/
Student getStudentBySno(int sno);
/**
* 持久化Student的s对象到持久化介质中
* @param s 要持久化的s对象
* @return 受影响的行数
*/
int saveStudent(Student s);
/**
* 修改持久化介质中的s的sno所对应s数据,用该s对象的所有属性值去替换持久化介质中该sno对应的持久化数据
* @param s 要持久化数据的新值
* @return 受影响的行数
*/
int updateStudent(Student s);
/**
* 删除持久化介质中sno所对应的数据
* @param sno 要删除对象sno的主键
* @return 受影响的行数
*/
int deleterStudent(int sno);
/**
* 获取当前表中的总记录数
* @return 数据库中该表的条目数
*/
long getCount();
}
dao.impl.IStudentDaoImpl
package dao.impl;
import dao.IStudentDao;
import entity.Student;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import util.DBPoolUtil;
import java.sql.SQLException;
import java.util.List;
import java.util.logging.Handler;
public class IStudentDaoImpl implements IStudentDao {
// 使用数据库的连接池对象创建一个QueryRunner对象,使用QueryRunner对象可以完成所有的crud操作
private QueryRunner qr = new QueryRunner(DBPoolUtil.getDataSource());
@Override
public List<Student> getAllStudent() {
try {
return qr.query(" select * from student",new BeanListHandler<Student>(Student.class));
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public List<Student> getStudentByPage(int cp, int ps)
{
int si = (cp - 1) * ps;
try {
return qr.query("select * from student limit ?,?",new BeanListHandler<Student>(Student.class),si,ps);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public Student getStudentBySno(int sno) {
try {
return qr.query(" select * from student where sno=?",new BeanHandler<Student>(Student.class),sno);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public int saveStudent(Student s) {
try {
return qr.update("insert into student values(?,?,?,?,?)",s.getSno(),s.getSname(),s.getSsex(),s.getSbirthday(),s.getCls());
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
@Override
public int updateStudent(Student s) {
try {
qr.update(" update student set sname=?,ssex=?,sbirthday=?,cls=? where sno=?",s.getSname(),s.getSsex(),s.getSbirthday(),
s.getCls(),s.getSno());
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
@Override
public int deleterStudent(int sno) {
try {
qr.update("delete from student where sno=?",sno);
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
@Override
public long getCount() {
try {
return qr.query("select count(1) from student",new ScalarHandler<>());
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
}
test.TestStudent
package test;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import dao.IStudentDao;
import dao.impl.IStudentDaoImpl;
import entity.Student;
import javax.xml.crypto.Data;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
public class TestStudentDao {
public static void main(String[] args) {
IStudentDao isd = new IStudentDaoImpl();
/**
* 得到所有的Student集合
* @return 所有的Student集合
*/
List<Student> list = isd.getAllStudent();
for (Student s : list) {
System.out.println(s);
}
System.out.println("=====================");
/**
* 分页查询得到对应页数的Student对象集合
* @param cp 当前第几页
* @param ps 每页最大条目数
* @return 所有Student对象的集合
*/
List<Student> list1 = isd.getStudentByPage(2,2);
for (Student s1 : list1) {
System.out.println(s1);
}
System.out.println("============================");
/**
* 通过sno得到该sno所对应的Student对象
* @param sno 编号
* @return sno 对应的对象
*/
System.out.println(isd.getStudentBySno(436));
/**
* 持久化Student的s对象到持久化介质中
* @param s 要持久化的s对象
* @return 受影响的行数
*/
Student ss = new Student();
Scanner input = new Scanner(System.in);
System.out.println("请输入sno:");
String sno = input.next();
ss.setSno(sno);
System.out.println("请输入sname:");
String sname = input.next();
ss.setSname(sname);
System.out.println("请输入ssex:");
String ssex = input.next();
ss.setSsex(ssex);
System.out.println("请输入sbirthday:");
String sbirthday = input.next();
ss.setSbirthday(sbirthday);
System.out.println("请输入cls:");
int cls = input.nextInt();
ss.setCls(cls);
/**
* 修改持久化介质中的s的sno所对应s数据,用该s对象的所有属性值去替换持久化介质中该sno对应的持久化数据
* @param s 要持久化数据的新值
* @return 受影响的行数
*/
System.out.println(isd.updateStudent(ss));
/**
* 删除持久化介质中sno所对应的数据
* @param sno 要删除对象sno的主键
* @return 受影响的行数
*/
System.out.println(isd.deleterStudent(101));
/**
* 获取当前表中的总记录数
* @return 数据库中该表的条目数
*/
System.out.println(isd.getCount());
}
}
service.IStudentService
package service;
import entity.Student;
import java.util.List;
public interface IStudentService {
/**
* 得到所有的Student集合
*
* @return 所有的Student集合
*/
List<Student> getAllStudent();
/**
* 分页查询得到对应页数的Student对象集合
*
* @param cp 当前第几页
* @param ps 每页最大条目数
* @return 所有Student对象的集合
*/
List<Student> getStudentByPage(int cp, int ps);
/**
* 通过sno得到该sno所对应的Student对象
*
* @param sno 编号
* @return sno 对应的对象
*/
Student getStudentBySno(int sno);
/**
* 持久化Student的s对象到持久化介质中
*
* @param s 要持久化的s对象
* @return
*/
boolean saveStudent(Student s);
/**
* 修改持久化介质中的s的sno所对应s数据,用该s对象的所有属性值去替换持久化介质中该sno对应的持久化数据
*
* @param s 要持久化数据的新值
* @return
*/
boolean updateStudent(Student s);
/**
* 删除持久化介质中sno所对应的数据
*
* @param sno 要删除对象sno的主键
* @return
*/
boolean deleterStudent(int sno);
/**
* 获取当前表中的总记录数
*
* @return
*/
long getCount();
}
service.impl.StudentServiceImpl
package service.Impl;
import dao.IStudentDao;
import dao.impl.IStudentDaoImpl;
import entity.Student;
import service.IStudentService;
import java.util.List;
public class StudentServiceImpl implements IStudentService {
private IStudentDao isd = new IStudentDaoImpl();
@Override
public List<Student> getAllStudent() {
return isd.getAllStudent();
}
@Override
public List<Student> getStudentByPage(int cp, int ps) {
return isd.getStudentByPage(cp, ps);
}
@Override
public Student getStudentBySno(int sno) {
return isd.getStudentBySno(sno);
}
@Override
public boolean saveStudent(Student s) {
return isd.saveStudent(s)>0;
}
@Override
public boolean updateStudent(Student s) {
return isd.updateStudent(s)>0;
}
@Override
public boolean deleterStudent(int sno) {
return isd.deleterStudent(sno)>0;
}
@Override
public long getCount() {
return isd.getCount();
}
}
五、QueryRunner()方法的使用
主要是针对数据库连接池的使用,一方面解决了数据库访问过多时造成数据库承受的压力,另一方面也简化了数据查询。
QueryRunner方法()
QueryRunner中一共有6种方法:
•execute(执行SQL语句)
•batch(批量处理语句)
•insert(执行INSERT语句)
•insertBatch(批量处理INSERT语句)
•query(SQL中 SELECT 语句)
•update(SQL中 INSERT, UPDATE, 或 DELETE 语句)(最为常用)
•ArrayHandler:把结果集中的第一行数据转成对象数组。
•ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。
•BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
•BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
•MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
•MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
• ColumnListHandler:将结果集中某一列的数据存放到List中。
•KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List),再把这些map再存到一个map里,其key为指定的列。
ScalarHandler:将结果集第一行的某一列放到某个对象中。

601

被折叠的 条评论
为什么被折叠?



