目录
JDBC
JDBC的本质
JDBC的本身就是一个普通的Java类(数据库厂商提供驱动jar包),能够实现sun公司提供的一套接口规范:
java.sql.Driver
java.sql.Connection
java.sql.Statement
JDBC七大步骤
七大步骤
- 1)导包驱动包
- 2)注册驱动–加载驱动类
- 3)获取数据库的连接对象java.sql.Connection
- 4)准备sql语句
- 5)通过Connection连接对象获取数据库的执行对象
- 6)执行sql语句
- 7)释放资源
//七大步骤
// 1)导包
//2)注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//3)获取数据库的连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/库名","root","自己mysql密码") ;
//4)准备sql语句
String sql = "update 表名 set 字段名称 = 值 where 字段名称 = 值" ;
//5)通知数据库的连接对象获取执行对象Statement
Statement stmt = conn.createStatement() ;
//6)执行sql语句
int count = stmt.executeUpdate(sql) ;
//7)释放资源
stmt.close() ;
conn.close();
示例
public class JdbcDemo {
public static void main(String[] args) throws Exception {
//Jdbc的操作:java连接数据库
//1)导入驱动jar包
//2)注册驱动---加载驱动类
Class.forName("com.mysql.jdbc.Driver") ; //mysql5.5或者5.1的jar包:都是这个全限定名称
//mysql8.0jar包: com.mysql.cj.jdbc.Driver
//3)获取数据库连接对象
//DriverManager驱动管理类--->
//public static Connection getConnection(String url, 连接库地址 (统一资源定位符)
// String user, mysql的用户名 root用户
// String password) 登录MySQL的密码
// throws SQLException
//url--->组成: 协议名称 ://域名:端口号/具体的路径
/*
* mysql的驱动jar包如果是8.0以后:url的后面 编码格式 是否启用证书登录 服务器时区 是否公钥模式
* jdbc:mysql://localhost:3306/ee_2211_02?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
* */
// jdbc:mysql://localhost:3306/库名
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/ee_2211_02",
"root",
"123456"![请添加图片描述](https://img-blog.csdnimg.cn/2096cdbe70e247d49b49a6d854c15fde.png)
);
//4)准备sql语句
String sql = "insert into account (name,balance) values('高圆圆',1000)" ;
//5)通过数据库连接对象Connection获取数据库的执行对象
//执行静态sql语句
//Statement createStatement()throws SQLException创建一个Statement对象,用于将SQL语句发送到数据库
Statement stmt = conn.createStatement();
//6)执行sql语句
//Statement--->
//int executeUpdate(String sql)throws SQLException 通用的更新操作
int count = stmt.executeUpdate(sql);
System.out.println("影响了"+count+"行");
//7)释放资源
stmt.close();
conn.close();
}
}
JDBC7大操作步骤里面涉及的API
1)导包---导入msyql驱动包
2)注册驱动--->
Class.forName("com.mysql.jdbc.Driver") ; //为了向后兼容 ---在加载类
本身注册驱动需要用到java.sql.DriverManager:驱动管理类(管理诸如JDBC的服务)
提供静态功能:
1)注册驱动public static void registerDriver(Driver driver) throws SQLException
参数为:java.sql.Drvier---->需要接口的实现类---驱动jar包里面com.mysql.jdbc.Drvier
如果上面的写法使用 DriverManager.registerDriver(new com.mysql.jdbc.Driver());这种方式,会多注册一遍
com.mysql.jdbc.Driver的原码里面
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static { //静态代码块
try {
DriverManager.registerDriver(new Driver()); //注册驱动了
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
获取数据库的连接对象,返回值 java.sql.Connection
2)public static Connection getConnection(String url,
String user,
String password)
throws SQLException
url: 协议://域名:端口/库名 (统一资源定位符号)
jdbc:mysql://localhost:3306/库名
user:mysql的用户名: root用户
password:密码
java.sql.Connection:与特定数据库连接会话 接口
Statement createStatement() throws SQLException; 获取执行对象
返回返回的数据库执行对象--->里面创建具体子实现类对象
public class StatementImpl implements Statement
java.sql.Statement:用于执行静态SQL语句并返回其生成的结果的对象。
静态sql语句:
弊端
1)硬编码
2)存在sql字符串拼接
String sql = "update account set balance = balance + 500 where id =1 " ;
两种通用操作
针对DDL语句(针对表/库相关的操作),DML语句的insert ,update,delete 更新操作
public int executeUpdate(String sql)
针对DQL语句:数据库查询语句 ,返回表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。
ResultSet executeQuery(String sql) throws SQLException
java.sql.ResultSet 据库结果集的数据表
boolean next():是否下一个结果集
/*JDBC操作DDL语句--->创建一个学生表
* id,name,gender,age,address
*/
public class JDBCDemo2 {
public static void main(String[] args) {
Connection conn = null ;
Statement stmt = null ;
try {
//1)导包/注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//2)准备sql
String sql = "create table student(" +
" id int primary key auto_increment," +
" name varchar(10), " +
" age int ," +
" gender varchar(3), " +
" address varchar(50) " +
") ;" ;
//3)获取连接对象
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/ee_2211_02",
"root",
"123456"
) ;
//4)获取执行对象
stmt = conn.createStatement() ;
//5)执行
int count = stmt.executeUpdate(sql);
System.out.println(count);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
提供这样一个工具类,构造方法私有,目的就是为了让外界不能new对象
封装哪些?
- 1)每一次书写7大不步骤,都需要去获取数据库的连接对象,需要优化
- 2)每一次都要释放资源的代码,也需要优化
public class JdbcUtils {
//成员变量声明三个变量
private static String url = null ;
private static String user = null ;
private static String password = null ;
private static String driverClass = null ;
//模拟 驱动jar包---Driver驱动类---提供静态代码块
static{
try {
//想办法获取这些参数---->提供配置文件 后缀名.properties---->放在src下面
//1)读取配置文件内容
InputStream inputStream = JdbcUtils.class.getClassLoader()
.getResourceAsStream("jdbc.properties");
//2)创建一个属性集合列表Properties
Properties prop = new Properties() ;
//System.out.println(prop) ;//测试 ---肯定空列表
//3)将1)获取资源文件的输入流对象---加载到属性集合列表中
prop.load(inputStream);
// System.out.println(prop) ; //测试--->有属性列表内容
//4)通过key获取value
driverClass = prop.getProperty("driverClass");
url = prop.getProperty("url") ;
user = prop.getProperty("user") ;
password = prop.getProperty("password") ;
//5)加载驱动类
Class.forName(driverClass) ;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private JdbcUtils(){}
/**
* 这个方法,获取数据库的连接对象
* @return
*/
public static Connection getConnection(){
try {
//需要驱动管理DriverManager获取连接对象
Connection connection = DriverManager.getConnection(url, user, password);//获取这三个参数的内容
return connection ;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null ;
}
/**
* 释放资源,针对DQL语句操作释放的相关资源对象
* @param rs
* @param stmt
* @param conn
*/
public static void close(ResultSet rs,Statement stmt,Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
/**
* 释放资源,针对DDL语句,DML语句
* @param stmt
* @param conn
*/
public static void close(Statement stmt,Connection conn){
close(null,stmt,conn);
}
public static void main(String[] args) {
Connection connection = JdbcUtils.getConnection();
System.out.println(connection);
}
}
测试刚才工具类的功能:
public class JdbcUtilsTest {
public static void main(String[] args) {
Connection conn = null ;
Statement stmt = null ;
try {
//导包/注册驱动
//直接获取连接对象
conn = JdbcUtils.getConnection();
//准备sql语句
String sql = "insert into student(name,age,gender,address) values" +
"( '张三',20,'女','西安市'),( '张三丰',35,'男','咸阳市'), ( '李四',30,'男','西安市');" ;
//获取执行对象
stmt = conn.createStatement();
//执行
int count = stmt.executeUpdate(sql);
System.out.println("影响了"+count+"行") ;
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.close(stmt,conn);
}
}
}
DQL语句操作
public class StatementExecuteDQL {
public static void main(String[] args) throws Exception {
//1)直接获取连接对象
Connection conn = JdbcUtils.getConnection();
//2)准备sql语句
String sql = "select * from student" ;
//3)获取执行对象
Statement stmt = conn.createStatement();
//4)执行sql
ResultSet rs = stmt.executeQuery(sql);
System.out.println("学生的信息如下:");
//第一次获取
//ResultSet--->boolean next() :判断结果集中是否下一条数据
/* if(rs.next()){
//true
//通过列的索引值获取 xxx getXXX(int columneIndex)
int id = rs.getInt(1);//第一例
String name = rs.getString(2);//第二列
int age = rs.getInt(3);//第三列
String gender = rs.getString(4);//第四列
String address = rs.getString(5);//第五列
System.out.println(id+"\t"+name+"\t"+gender+"\t"+address);
}
//第二次获取
if(rs.next()){
//true
//通过列的名称获取 xxx getXXX(String columneLaber)
int id = rs.getInt("id");//第一例的名称
String name = rs.getString("name");//第二列名称
int age = rs.getInt("age");//第三列名称
String gender = rs.getString("gender");//第四列名称
String address = rs.getString("address");//第五列名称
System.out.println(id+"\t"+name+"\t"+gender+"\t"+address);
}
//第三次获取
if(rs.next()){
//true
//通过列的名称获取 xxx getXXX(String columneLaber)
int id = rs.getInt("id");//第一例的名称
String name = rs.getString("name");//第二列名称
int age = rs.getInt("age");//第三列名称
String gender = rs.getString("gender");//第四列名称
String address = rs.getString("address");//第五列名称
System.out.println(id+"\t"+name+"\t"+gender+"\t"+address);
}*/
while(rs.next()){
//通过列的名称获取 xxx getXXX(String columneLaber)
int id = rs.getInt("id");//第一例的名称
String name = rs.getString("name");//第二列名称
int age = rs.getInt("age");//第三列名称
String gender = rs.getString("gender");//第四列名称
String address = rs.getString("address");//第五列名称
System.out.println(id+" "+name+" "+gender+" "+address);
}
//释放
JdbcUtils.close(rs,stmt,conn);
}
}
需求:
- 有一个学生类,学生编号,学生姓名,学生年龄,学生性别,学生住址属性,
- 查询student表,将每一条数据封装到Student对象中,最终将Student对象添加List集合中,
- 最终遍历List,获取学生信息数据!
分析:
- 1)定义一个学生类,学生编号,学生姓名,学生年龄,学生性别,学生住址属性私有化
- 2)定义一个功能---->返回List
- 2.1)创建一个ArrayList
- 2.2)JDBC操作—获取连接对象,准备sql,获取执行对象,查询
- 2.3)查询结果—>ResultSet结果集
- 2.4)不断的去封装学生对象,将学生对象,添加集合中
- 2.5)完成遍历
public class Student {
/**
* 学生编号,学生姓名,学生年龄,学生性别,学生住址属性私有化
*/
private int id ; //编号
private String name ; //姓名
private int age ; //年龄
private String gender ; //性别
private String address ; //地址
public Student() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", address='" + address + '\'' +
'}';
}
}
public class Test1 {
public static void main(String[] args) throws Exception {
//调用一个功能
List<Student> list = getAllStudent() ;
System.out.println("学生信息如下:");
if(list!=null){
for(Student s:list){
System.out.println(s.getId()+"---"+s.getName()+"---"+s.getAge()+"---"+s.getGender()+"---"+s.getAddress());
}
}
}
//定义通过查询所有学数据,将每一条数据封装学生对象中,最终添加集合中
public static List<Student> getAllStudent() throws Exception {
//创建List集合
List<Student> list = new ArrayList<>() ;
//JDBC操作
//获取数据库的连接对象
Connection conn = JdbcUtils.getConnection();
//准备sql
String sql = "select * from student" ;
//通过连接对象获取执行对象
Statement stmt = conn.createStatement();
//执行sql语句
ResultSet rs = stmt.executeQuery(sql);
//声明学生类型的变量
Student s = null ;
//遍历结果集
while(rs.next()){
//封装学生数据
s = new Student() ;
//编号
// int id = rs.getInt("id") ;
// s.setId(id) ;
s.setId(rs.getInt("id") );
//姓名
s.setName(rs.getString("name"));
//年龄
s.setAge(rs.getInt("age"));
//性别
s.setGender(rs.getString("gender"));
//住址
s.setAddress(rs.getString("address"));
//将每一个学生对象添加到list集合中
list.add(s) ;
}
return list ;
}
}
单元测试
包的命名:公司域名反写
com.pojo/entity/domain---->实体类--->描述事物的属性和行为..
com.service ---->业务服务层 ----->针对业务的接口
com.service.impl----->针对业务的接口实现-------------------->以后开发中----大量的if.else...
com.dao ----->DAO Data Access Object--->数据访问对象 ------>数据访问接口
XxxDao
com.dao.impl
数据访问接口的实现------>JDBC代码
com.test----->单元测试的
单元测试的步骤
1)导入jar包 junit核心包 以及依赖包
2)针对某个类进行---- 单元测试---测试功能
书写方法,上面标记是单元测试方法 @Test---->执行单元测试之前,可以完成初始化操作 @Before标记方法
执行单元测试方法执行,释放资源 @After标记的方法中
com.pojo
public class Student {
/**
* 学生编号,学生姓名,学生年龄,学生性别,学生住址属性私有化
*/
private int id ; //编号
private String name ; //姓名
private int age ; //年龄
private String gender ; //性别
private String address ; //地址
public Student() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", address='" + address + '\'' +
'}';
}
}
public class JdbcUtils {
//成员变量声明三个变量
private static String url = null ;
private static String user = null ;
private static String password = null ;
private static String driverClass = null ;
//模拟 驱动jar包---Driver驱动类---提供静态代码块
static{
try {
//想办法获取这些参数---->提供配置文件 后缀名.properties---->放在src下面
//1)读取配置文件内容
InputStream inputStream = JdbcUtils.class.getClassLoader()
.getResourceAsStream("jdbc.properties");
//2)创建一个属性集合列表Properties
Properties prop = new Properties() ;
//System.out.println(prop) ;//测试 ---肯定空列表
//3)将1)获取资源文件的输入流对象---加载到属性集合列表中
prop.load(inputStream);
// System.out.println(prop) ; //测试--->有属性列表内容
//4)通过key获取value
driverClass = prop.getProperty("driverClass");
url = prop.getProperty("url") ;
user = prop.getProperty("user") ;
password = prop.getProperty("password") ;
//5)加载驱动类
Class.forName(driverClass) ;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private JdbcUtils(){}
/**
* 这个方法,获取数据库的连接对象
* @return
*/
public static Connection getConnection(){
try {
//需要驱动管理DriverManager获取连接对象
Connection connection = DriverManager.getConnection(url, user, password);//获取这三个参数的内容
return connection ;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null ;
}
/**
* 释放资源,针对DQL语句操作释放的相关资源对象
* @param rs
* @param stmt
* @param conn
*/
public static void close(ResultSet rs,Statement stmt,Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
/**
* 释放资源,针对DDL语句,DML语句
* @param stmt
* @param conn
*/
public static void close(Statement stmt,Connection conn){
close(null,stmt,conn);
}
public static void main(String[] args) {
Connection connection = JdbcUtils.getConnection();
System.out.println(connection);
}
}
针对学生的数据访问接口DAO
com.dao
public interface StudentDao {
/**
* 添加学生实体
* @param student 学生对象
*/
void add(Student student) throws SQLException;
/**
* 通过学生数据修改学生数据
* @param student 学生对象
* @return 影响的行数
*/
int updateStudent(Student student) throws SQLException;
/**
* 根据学生编号删除学生
* @param id 学生id
*/
void deleteStudentById(int id) throws SQLException;
/**
* 查询所有学生的功能
* @return 学生列表
*/
List<Student> findAllStudent() throws SQLException;
/**
* 通过学生id获取学生实体
* @param id 学生编号
* @return 返回学生实体
*/
Student findStudentById(int id) throws SQLException;
/**
* 通过学生的姓名模糊查询学列表
* @return 返回学生列表
*/
List<Student> findStudentByNmae(String name) throws SQLException;
}
针对学生数据访问接口的实现
com.dao.impl
public class StudentDaoImpl implements StudentDao {
/**
* 添加学生实体
* @param student 学生对象
*/
@Override
public void add(Student student) throws SQLException {
//获取数据库连接对象
Connection conn = JdbcUtils.getConnection();
//sql
String sql = "insert into student(name,age,gender,address) values('"+student.getName()+"','"
+student.getAge()+"','"+student.getGender()+"','"+student.getAddress()+"')" ;
//获取执行对象
Statement stmt = conn.createStatement() ;
//执行更新
int count = stmt.executeUpdate(sql);
System.out.println(count) ;
JdbcUtils.close(stmt,conn);
}
/**
* 通过学生数据修改学生数据
* @param student 学生对象
* @return 影响的行数
*/
@Override
public int updateStudent(Student student) throws SQLException {
//获取数据库连接对象
Connection conn = JdbcUtils.getConnection();
//sql
String sql = "update student set name ='"+student.getName()+"' ,address ='"+
student.getAddress()+"' where id = '"+student.getId()+"'";
System.out.println(sql);
//获取执行对象
Statement stmt = conn.createStatement() ;
//执行更新
int count = stmt.executeUpdate(sql);
System.out.println(count) ;
JdbcUtils.close(stmt,conn);
return count;
}
/**
* 根据学生编号删除学生
* @param id 学生id
*/
@Override
public void deleteStudentById(int id) throws SQLException {
//获取数据库连接对象
Connection conn = JdbcUtils.getConnection();
//sql
String sql = "delete from student where id = '"+id+"'" ;
System.out.println(sql);
//获取执行对象
Statement stmt = conn.createStatement() ;
//执行更新
int count = stmt.executeUpdate(sql);
System.out.println(count) ;
JdbcUtils.close(stmt,conn);
}
/**
* 查询所有学生的功能
* @return 学生列表
*/
@Override
public List<Student> findAllStudent() throws SQLException {
List<Student> list = new ArrayList<>() ;
Connection conn = JdbcUtils.getConnection();
//sql
String sql = "select * from student" ;
Statement stmt = conn.createStatement() ;
//查询结果集
ResultSet rs = stmt.executeQuery(sql) ;
//声明学生变量
Student s = null ;
while(rs.next()){
s = new Student() ;
s.setId(rs.getInt(1)) ;
s.setName(rs.getString(2));
s.setAge(rs.getInt(3));
s.setGender(rs.getString(4));
s.setAddress(rs.getString(5));
//添加集合中
list.add(s) ;
}
return list;
}
/**
* 通过学生id获取学生实体
* @param id 学生编号
* @return 返回学生实体
*/
@Override
public Student findStudentById(int id) throws SQLException {
Connection conn = JdbcUtils.getConnection();
//sql
String sql = "select * from student where id = '"+id+"'" ; //id唯一
//获取执行对象
Statement stmt = conn.createStatement() ;
ResultSet rs = stmt.executeQuery(sql);
Student s = null ;
if(rs.next()){
//封装学生对象
s = new Student() ;
s.setId(rs.getInt("id"));
s.setName(rs.getString("name"));
s.setAge(rs.getInt("age"));
s.setGender(rs.getString("gender"));
s.setAddress(rs.getString("address"));
}
JdbcUtils.close(rs,stmt,conn);
return s;
}
@Override
public List<Student> findStudentByNmae(String name) throws SQLException {
//创建List集合
List<Student> list = new ArrayList<>() ;
//获取数据库连接对象
Connection conn = JdbcUtils.getConnection() ;
String sql = "select * from student where name like '%"+name+"%'" ;
System.out.println(sql) ;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql) ;
//声明学生变量
Student s = null ;
while(rs.next()){
//封装学数据
s = new Student() ;
s.setId(rs.getInt("id"));
s.setName(rs.getString("name"));
s.setAge(rs.getInt("age"));
s.setGender(rs.getString("gender"));
s.setAddress(rs.getString("address"));
list.add(s) ;
}
JdbcUtils.close(rs,stmt,conn);
return list;
}
}
单元测试
com.test
public class StudentTest {
private StudentDao sd ;
@Before
public void init(){
sd = new StudentDaoImpl() ;
}
/**
* 测试添加功能
*/
@Test
public void testAddStudent() throws SQLException {
//封装学生对象
Student student = new Student() ;
student.setName("张佳宁") ;
student.setAge(32) ;
student.setGender("女") ;
student.setAddress("西安市");
sd.add(student);
}
/**
* 测试修改学生
* @throws SQLException
*/
@Test
public void testUpdateStudent() throws SQLException {
//封装学生对象
Student student = new Student() ;
student.setId(3);
student.setName("赵又廷") ;
student.setAge(36) ;
student.setGender("男") ;
student.setAddress("北京市");
sd.updateStudent(student);
}
/**
* 单元测试删除根据id删除学生
* @throws SQLException
*/
@Test
public void testDelStudent() throws SQLException {
sd.deleteStudentById(4);
}
/**
* 单元测试查询所有学生数据
* @throws SQLException
*/
@Test
public void testFindAll() throws SQLException {
List<Student> students = sd.findAllStudent();
if(students!=null){
for(Student s:students){
System.out.println(s) ;
}
}
}
/**
* 单元测试通过指定的编号查询指定学生
* @throws SQLException
*/
@Test
public void testFindStudentById() throws SQLException {
Student student = sd.findStudentById(1);
if(student!=null){
System.out.println(student) ;
}
}
/**
* 单元测试测试模糊查询
* @throws SQLException
*/
@Test
public void testFindStudentByName() throws SQLException {
List<Student> list = sd.findStudentByNmae("张");
if(list!=null){
for (Student student : list) {
System.out.println(student);
}
}
}
}
jdbc.properties
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ee_2211_02
user=root
password=123456
封装JDBC工具类的步骤 —JdbcUtils
1)准备配置文件 jdbc.properties
url=jdbc:mysql://localhost:3306/库名
driverClass=com.mysql.jdbc.Driver
user=root
password=123456
2) 当前类中提供静态代码块
static{
1)读取配置文件
InputStream inputStream = 前类名.class.getClassLoader().getResourceAsStream("jdbc.properties") ;
2)创建属性集合列表
Properties prop = new Properties() ;
//3)加载字节输入流对象到属性集合列表中
prop.load(inputStream) ;
//4)通过key获取value
//public String getProperty(String key)
获取四个key----给成员变量进行赋值
5)加载驱动
Class.forName(驱动类的全限定名称获取到);
}
3)静态方法----获取Connection
Connection conn = DriverManager.getConnection(三个参数直接传进去) ;
4)静态方法--->释放资源 针对DML语句 释放Statment以及Connection
针对DQL语句:释放ResultSet Statement,Connection
如何获取src下面的配置文件.properties内容
InputStream inputStrema = 前类名.class.getClassLoader().getResourceAsStream("jdbc.properties") ;
// 2)创建属性集合列表
Properties prop = new Properties() ;
//3)加载字节输入流对象到属性集合列表中
prop.load(inputStream) ;
//4)通过key获取value
//public String getProperty(String key)
通过 JDBC 员工表---->通过接口方式—使用单元测试—添加员
工类—给员工表插入数据(日期的处理)
package com.pojo;
//Employee中有员工编号,姓名,员工年龄,员工性别,员工工资,员工出生日期
public class Employee {
private int id ;//编号
private String name ;//姓名
private int age ; //年龄
private String gender ; //性别
private int salary ;//工资
private Date birthday ;// 出生日期
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Employee() {
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", salary=" + salary +
", birthday=" + birthday +
'}';
}
}
public class Dept { //部门类
//一个部门有多个员工
private List<Employee> list ;
}
package com.dao;
public interface EmployeeDao {
/**
* 添加员工数据
* @param employee 员工实体
*/
void add(Employee employee) throws SQLException;
}
针对员工数据访问接口实现
package com.dao.impl;
public class EmployeeDaoImpl implements EmployeeDao {
/**
* 添加员工数据
* @param employee 员工实体
*/
@Override
public void add(Employee employee) throws SQLException {
//获取连接对象
Connection conn = JdbcUtils.getConnection();
//sql
String sql = "insert into employee(name,age,gender,salary,birthday) values('"+employee.getName()+"',"+employee.getAge()+",'"+employee.getGender()+"',"+employee.getSalary()+",'"+employee.getBirthday()+"')" ;
System.out.println(sql) ;
//获取执行对象
Statement stmt = conn.createStatement() ;
//执行
int count = stmt.executeUpdate(sql);
System.out.println(count);
//释放资源
JdbcUtils.close(stmt,conn);
}
}
package com.utils;
public class JdbcUtils {
//成员变量声明三个变量
private static String url = null ;
private static String user = null ;
private static String password = null ;
private static String driverClass = null ;
//模拟 驱动jar包---Driver驱动类---提供静态代码块
static{
try {
//想办法获取这些参数---->提供配置文件 后缀名.properties---->放在src下面
//1)读取配置文件内容
InputStream inputStream = JdbcUtils.class.getClassLoader()
.getResourceAsStream("jdbc.properties");
//2)创建一个属性集合列表Properties
Properties prop = new Properties() ;
//System.out.println(prop) ;//测试 ---肯定空列表
//3)将1)获取资源文件的输入流对象---加载到属性集合列表中
prop.load(inputStream);
// System.out.println(prop) ; //测试--->有属性列表内容
//4)通过key获取value
driverClass = prop.getProperty("driverClass");
url = prop.getProperty("url") ;
user = prop.getProperty("user") ;
password = prop.getProperty("password") ;
//5)加载驱动类
Class.forName(driverClass) ;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private JdbcUtils(){}
/**
* 这个方法,获取数据库的连接对象
* @return
*/
public static Connection getConnection(){
try {
//需要驱动管理DriverManager获取连接对象
Connection connection = DriverManager.getConnection(url, user, password);//获取这三个参数的内容
return connection ;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null ;
}
/**
* 释放资源,针对DQL语句操作释放的相关资源对象
* @param rs
* @param stmt
* @param conn
*/
public static void close(ResultSet rs,Statement stmt,Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
/**
* 释放资源,针对DDL语句,DML语句
* @param stmt
* @param conn
*/
public static void close(Statement stmt,Connection conn){
close(null,stmt,conn);
}
public static void main(String[] args) {
Connection connection = JdbcUtils.getConnection();
System.out.println(connection);
}
}
package com.test;
public class EmployeeTest {
private EmployeeDao employeeDao = null ;
@Before
public void init(){
employeeDao = new EmployeeDaoImpl() ;
}
//测试添加员工
@Test
public void addEmployee() throws SQLException, ParseException {
//封装员工数据
Employee emp = new Employee() ;
emp.setName("张珊珊") ;
emp.setAge(44) ;
emp.setGender("女") ;
emp.setSalary(10000) ;
String dataStr = "2022-11-30" ;
//将日期文本---解析为java.util.Date
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;
Date date = sdf.parse(dataStr);
//数据库中支持java.sql.Date
//public Date(long date)
//创建支持sql的Date对象
java.sql.Date date2 = new java.sql.Date(date.getTime()) ;
//emp.setBirthday(new Date());//java.util.Date格式 和数据库中Date类型不一致
emp.setBirthday(date2);
employeeDao.add(emp);
}
}
reparedStatement预编译
PreparedStatement原生的写法
- 1)注册驱动
- 2)获取数据库的连接对象
- 3)准备sql-------->参数化sql语句, 这些参数不能在sql写死,都是? 占位符号
- 4)通过数据库连接对象 获取预编译对象,同时将sql发送给数据库,(参数什么类型,第几个参数)都会存储在预编译对象中
- 5)给参数赋值
- 6)执行预编译的sql
- 7)释放资源
public class PreparedStatementDemo {
public static void main(String[] args) throws SQLException {
//1)注册驱动
// 2)获取数据库的连接对象
Connection conn = JdbcUtils.getConnection();
//3)准备sql-------->参数化sql语句, 这些参数不能在sql写死,都是? 占位符号
//给员工表插入数据
String sql = "insert into employee(name,age,gender,salary,birthday) values(?,?,?,?,?)" ;
//4)通过数据库连接对象 获取预编译对象,同时将sql发送给数据库,(参数什么类型,第几个参数)都会存储在预编译对象中
//Connection--->方法 PreparedStatement prepareStatement(String sql) throws SQLException
System.out.println(sql) ;
//interface PreparedStatement extends Statement{}
PreparedStatement stmt = conn.prepareStatement(sql) ;
//5)给参数赋值
//PreparedStatement
//void setXX(int parameterIndex,XX实际值)throws SQLException
//参数1:参数化sql里面第几个占位符号 第一个?--->1
stmt.setString(1,"盲僧") ;
stmt.setInt(2,20) ;
stmt.setString(3,"男") ;
stmt.setInt(4,8000) ;
stmt.setDate(5,new java.sql.Date(new Date().getTime()));
//不断进行参数赋值
//6)通过预编译对象进行参数的赋值的操作
//int executeUpdate() throws SQLException 通用的更新操作
//ResultSet executeQuery() throws SQLException 通用的查询操作
int count = stmt.executeUpdate();
System.out.println(count);
//7)释放资源
JdbcUtils.close(stmt,conn);
}
}
之前通过sql指令的方式控制事务 (事务:让同时执行多个sql语句要么一块成功,要么一块失败!)
- 1)开启事务 :start transaction ;
- 2)执行多个sql语句/或者多张表的sql–添加/删除/修改
- 3)如果有问题,回滚事务 rollback;
- 4)没有问题,提交事务 最终 commit ;
JDBC方式控制事务
java.sql.Connection:
void setAutoCommit(boolean autoCommit) throws SQLException 设置提交模式
参数为false,表示禁用自动提交;为true,默认就是自动提交
void rollback() throws SQLException 事务回滚,撤销之前的所有更新操作; (前提必须处于手动提交)
void commit() throws SQLException 提交事务,将数据永久保存!
public class JdbcDemo {
public static void main(String[] args) {
Connection conn = null ;
PreparedStatement ps1 = null ;
PreparedStatement ps2 = null ;
try {
//操作账户表---完成转账操作
//jdbc方式 不控制事务 ---执行多个sql语句期间出问题了,会造成数据紊乱!
//jdbc方式 控制事务
//获取连接对象
conn = JdbcUtils.getConnection();
//1)将自动提交设置手动提交模式----开启事务
/**
* void setAutoCommit(boolean autoCommit) throws SQLException 设置提交模式
* 参数为false,表示禁用自动提交;为true,默认就是自动提交
*/
conn.setAutoCommit(false) ;
//准备多个sql---->参数化的sql语句
String sql1 = "update account set balance = balance - ? where id = ?" ;
String sql2 = "update account set balance = balance +? where id = ?" ;
//通过执行对象获取预编译对象
ps1 = conn.prepareStatement(sql1);
ps2 = conn.prepareStatement(sql2);
//参数赋值
ps1.setInt(1,500) ;
ps1.setInt(2,2);
ps2.setInt(1,500) ;
ps2.setInt(2,4);
//分别执行将参数给预编译sql进行操作
int count1 = ps1.executeUpdate();
System.out.println(count1);
// int i = 10 / 0 ; //除数不能为0 (这块明显给了异常,开发中中间业务逻辑存在漏洞,造成程序异常)
int count2 = ps2.executeUpdate();
System.out.println(count2);
//提交事务
conn.commit();
} catch (SQLException throwables) {
//void rollback() throws SQLException 事务回滚,撤销之前的所有更新操作; (前提必须处于手动提交)
//如果中间出问题了,执行catch语句
try {
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
throwables.printStackTrace(); //将异常信息处理--打印在控制台上
} finally {
JdbcUtils.close(ps1,conn) ;
JdbcUtils.close(ps2,conn) ;
}
}
}
测试数据库连接池 Druid 获取连接对象的过程!
public class DruidTest {
public static void main(String[] args) throws Exception {
//1)导包核心连接池的jar包 druid.jar
//2)准备了druid.properties配置文件
//3)创建属性集合列表
Properties prop = new Properties() ;
//4)读取src下面的连接池的配置文件
InputStream inputStream = DruidTest.class.getClassLoader().getResourceAsStream("druid.properties");
//5)将字节输入流内容加载到属性集合列表中
prop.load(inputStream);
//6)从连接池获取连接对象
//com.alibaba.druid.pool.DruidDataSourceFactory
//提供了静态方法public static DataSource createDataSource(Properties properties)
//创建数据源DataSource数据源接口对象---->本质----DruidDataSource实现类
DataSource ds = DruidDataSourceFactory.createDataSource(prop);
for(int x = 1;x<=11;x++){
Connection conn = ds.getConnection();
if(x == 3){
conn.close();// 将连接对象归还连接池中
}
System.out.println(conn);
}
}
}
#德鲁伊的加载驱动的名称driverClassName
driverClassName=com.mysql.jdbc.Driver
#连接的库的地址
url=jdbc:mysql://localhost:3306/ee_2211_02
#用户名
username=root
#密码
password=123456
#连接池启用之后初始化的连接数量5个
initialSize=5
#连接池中最大激活数量10个
maxActive=10
#最大等待时间 3000毫秒(3秒),当连接池如果中的连接数数量超过了最大就激活数量,等待3秒中连接,如果超过3秒,拒绝连接
对象进入连接池
maxWait=3000
Java中的注解
Java注解----称为"Java标注",被解析应用到程序中;
所有的注解都有继承自 java.lang.annotation Annotation公共接口
注解本质就是一个接口—里面的方法名---->称为注解的"属性",而且注解中有且仅有一个value属性 (value()),
jdk提供内置注解---->标记 当前一些使用访问
jdk提供注解
-
@Override:标记当前这个方法是否重写方法(父类或者接口)
-
@SuppressWarnings: 抑制警告 :项目部署上线的,所有的类不能出现黄色警告线
-
@Deprecated:标记这个方法已经过时
-
@FunctionalInteface:标记接口用的,是否为函数式接口(接口中有且仅有一个抽象方法)
-
@Annotation 注解的本质就是interface——本身就存在元注解
- RetentionPolicy value(); value属性返回值枚举RetentionPolicy
- 三个级别(三个阶段)
- SOURCE, 源代码代码编译阶段
- CLASS, 当前注解中类相关的加载阶段
- RUNTIME 运行阶段
-
@Target :使用的自定义或者jdk提供注解它的使用方法 ——标记指定的注解使用的范围
- ElementType[] value(); value属性的返回值枚举类型的数组
- ElementType:说明@Target使用的范围 (这四个经常用)
- TYPE, 标记注解使用类上或者接口上
- FIELD, 标记注解使用在成员变量上
- METHOD, 标记这个注解可以在方法上用
- PARAMETER 标记你这个注解可以在形式参数上用
-
@Documented :解析的时候,针对类或接口上使用这个注解,保留文档注释!
自定义注解 以及注解中定义方法(属性—>返回值类型只有5中,String,基本类型,枚举,注解类型,以上类的数组)
注解中的属性名(就是接口中的成员方法名)的返回值类型可以是哪些数据类型?
5种类型
- 基本数据类型
- 字符串类型
- 枚举类型
- 注解类型
- 以上类型是数组格式
前端部分
HTML部分
查看链接:之前的HTML总结,更加详细
JS部分
Javascript的历史
js使用方式
方式1,内部方式
head标签体中 写script标签,书写js代码
方式2,外部方式
前端人员, 在当前页码导入外部.js文件
script标签体 里面src属性=“外部.js文件”
<script>
//常用的函数: window.alert("提示框")
alert("hello,javascript") ; //window可以不写
//window里面确认提示
var flag = confirm("您忍心删除吗?") ;
//prompt带有一个消息和文本输入框
window.prompt("请输入动态密令:") ;
//向浏览器输出内容
document.write("hello,javaScript") ;
//浏览器中控制台打印内容
console.log("hello,javascript") ;
</script>
效果如下:
js中变量以及数据类型
javasript:弱类型语言(语法结构不严谨)
js中定义任何变量以及创建对象 使用var (var可以省略不写)
数据类型:
1)无论整数还是小数都是number 数值类型 --提升为 js内置对象 Number对象
2)boolan类型--- 提升内置对象 Boolean对象
3)无论是字符还是字符串 都是string类型 -- 提升js内置对象 String对象
4)对象类型 object 提升 Object---代表所有js对象的模板
5)未定义类型undefined--没有值
查看js中的变量的数据类型 typeof(变量名)
<script>
a = 10
a = 20
var b = 3.14 ;
var c = true ;
var d = 'A';
var e = "hello" ;
var f = new Object();
var g ;
document.write("a的值是:"+a+",a的数据类型是:"+typeof(a)+"<br/>") ;
document.write("b的值是:"+b+",b的数据类型是:"+typeof(b)+"<br/>") ;
document.write("c的值是:"+c+",c的数据类型是:"+typeof(c)+"<br/>") ;
document.write("d的值是:"+d+",d的数据类型是:"+typeof(d)+"<br/>") ;
document.write("e的值是:"+e+",e的数据类型是:"+typeof(e)+"<br/>") ;
document.write("f的值是:"+f+",f的数据类型是:"+typeof(f)+"<br/>") ;
document.write("g的值是:"+g+",g的数据类型是:"+typeof(g)+"<br/>") ;
</script>
效果如下:
js的运算符_流程控制语句
运算符
- 算术 +,-,*,/,%
- 比较 :==,!=,<,<=,>,>=
- 逻辑:&&,|| 前端中使用 (提高执行效率:短路效果)
- 三元:(表达式)?执行成立的结果:否则不成立的结果;
- 赋值运算符: = ,+=,-=,*=,%/…
js流程控制语句
顺序结构语句:代码由上而下依次加载
选择结构语句 :、
1. if语句
if
if...else
if ...else if...else...
2. switch(表达式或变量){
case "可以变量/也可以是常量":
语句1;
break ;
...
default :
语句n;
break ;
}
3. for-in语句:针对数组以及对象的属性进行遍历--类似于Java中的增强for
for(var 变量名 in 数组对象或者对象名){
使用变量名
}
/* var num = "10" ;
if(num ==10){ //string:数值字符串和number进行比较==,将string-->number进行比较
alert("成立") ;
} */
<script>
//var a = 3 ;
//var b = false ; //true---1 成立
//false--0 不成立
//document.write((a+b)+"<br/>") ;
var x = 3 ;
var y = 4 ;
document.write((x+y)+"<br/>") ;
document.write((x-y)+"<br/>") ;
document.write((x*y)+"<br/>") ;
document.write((x/y)+"<br/>") ;
document.write((x%y)+"<br/>") ;
document.write("<hr/>") ;
document.write((x>=y)+"<br/>") ;
document.write((x==y)+"<br/>") ;
document.write((x!=y)+"<br/>") ;
document.write("<hr/>") ;
var m = 4 ;
var n = 5 ;
document.write("m:"+m+",n:"+n+"<br/>") ;
document.write(((++m==4) && (--n==4))+"<br/>") ;
document.write("m:"+m+",n:"+n+"<br/>") ;
document.write("<hr/>") ;
var age = 19 ;
document.write((age>18)?"成年人":"未成年人") ;
document.write("<hr/>") ;
var num = "10" ;
//alert(typeof(num)) ;
//js提供类型转换--strig---number
var num = parseInt(num) ;
//alert(typeof(num)) ;
switch(num){
case 10:
document.write("10匹配成功") ;
break ;
case 11:
document.write("11匹配成功") ;
break ;
default:
document.write("上面都不匹配") ;
break ;
}
</script>