java 占位符_Java修行第038天--JDBC下半部分--核心封装BaseDao

今天接继续学习JDBC,其中今天最关键的就是如何封装BaseDao

先串一下分层的具体步骤 : ----BaseDao具体实现在下面

1.新建Java项目,并添加数据库的驱动包

2.新建常用的包

com.sxt.commons :工具类

com.sxt.dao :数据访问接口

com.sxt.dao.impl:数据访问接口的实现类

com.sxt.pojo:实体类

com.sxt.service:服务层,业务逻辑接口

com.sxt.service.impl:业务逻辑实现类

com.sxt.test:测试类

3.在com.sxt.pojo包下添加实体类,封装与数据表相关的数据(实体类的类名与表名相同,属性名称与表的字段相同)

public class Student {

private String scode;//学号

private String sname;//名称

private int age;

private float score;

..省略getter和setter方法

}

4.编写DAO接口(表名+Dao)及其实现类(表名+DaoImpl)

a.StudentDao接口 ---没有方法体的方法,需要StudentDaoImpl实现类来来实现它

public interface StudentDao {

/**

* 新增学生

*/

public int addStudent(Student student);

/**

* 修改学生

*/

public int updateStudent(Student student);

/**

* 删除学生

*/

public int deleteStudent(String scode);

/**

* 查询所有学生

*/

public List<Student> findAll();

/**

* 根据学生编号查询学生详情

*/

public Student findByScode(String scode);

}

b.新建StudentDaoImpl

package com.sxt.dao.impl;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;

import com.sxt.commons.JdbcUtil;

import com.sxt.dao.StudentDao;

import com.sxt.pojo.Student;

public class StudentDaoImpl implements StudentDao {

//新增语句

@Override

public int addStudent(Student student) {

int count = 0;

String sql="insert into student(scode,sname,age,score) values(?,?,?,?)";

Connection conn=null;

PreparedStatement psmt = null;

conn = JdbcUtil.getConnection();

try {

psmt = conn.prepareStatement(sql);

//为占位符绑定值

psmt.setString(1, student.getScode());

psmt.setString(2, student.getSname());

psmt.setInt(3, student.getAge());

psmt.setFloat(4, student.getScore());

//执行新增

count = psmt.executeUpdate();

} catch (SQLException e) {

e.printStackTrace();

}finally{

JdbcUtil.closeAll(conn, psmt, null);

}

return count;

}

//修改语句

@Override

public int updateStudent(Student student) {

int count = 0;

String sql="update student set sname=?,age=?,score=? where scode=?";

Connection conn=null;

PreparedStatement psmt = null;

conn = JdbcUtil.getConnection();

try {

psmt = conn.prepareStatement(sql);

//为占位符绑定值

psmt.setString(1, student.getSname());

psmt.setInt(2, student.getAge());

psmt.setFloat(3, student.getScore());

psmt.setString(4, student.getScode());

//执行新增

count = psmt.executeUpdate();

} catch (SQLException e) {

e.printStackTrace();

}finally{

JdbcUtil.closeAll(conn, psmt, null);

}

return count;

}

//删除语句

@Override

public int deleteStudent(String scode) {

int count = 0;

String sql="delete from student where scode=?";

Connection conn=null;

PreparedStatement psmt = null;

conn = JdbcUtil.getConnection();

try {

psmt = conn.prepareStatement(sql);

//为占位符绑定值

psmt.setString(1, scode);

//执行新增

count = psmt.executeUpdate();

} catch (SQLException e) {

e.printStackTrace();

}finally{

JdbcUtil.closeAll(conn, psmt, null);

}

return count;

}

//查询语句

@Override

public List<Student> findAll() {

List<Student> list = new ArrayList<>();

String sql="select * from student";

Connection conn=null;

PreparedStatement psmt = null;

ResultSet rs = null;

conn = JdbcUtil.getConnection();

try {

psmt = conn.prepareStatement(sql);

//执行查询

rs = psmt.executeQuery();

while(rs.next()){

//创建Student对象用于封装一条记录的数据

Student student = new Student();

student.setScode(rs.getString("scode"));

student.setSname(rs.getString("sname"));

student.setAge(rs.getInt("age"));

student.setScore(rs.getFloat("score"));

list.add(student);

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

JdbcUtil.closeAll(conn, psmt, rs);

}

return list;

}

//查询单条语句

@Override

public Student findByScode(String scode) {

String sql="select * from student where scode=?";

Connection conn=null;

PreparedStatement psmt = null;

ResultSet rs = null;

conn = JdbcUtil.getConnection();

Student student = null;

try {

psmt = conn.prepareStatement(sql);

psmt.setString(1, scode);

//执行查询

rs = psmt.executeQuery();

while(rs.next()){

//创建Student对象用于封装一条记录的数据

student = new Student();

student.setScode(rs.getString("scode"));

student.setSname(rs.getString("sname"));

student.setAge(rs.getInt("age"));

student.setScore(rs.getFloat("score"));

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

JdbcUtil.closeAll(conn, psmt, rs);

}

return student;

}

}

5.服务层(业务逻辑层),调用DAO完成业务逻辑。新建Service接口(表名+Service)及其Service接口的实现类(表名+ServiceImpl),

(13)通过 PreparedStatement 对象完成数据的查询

(13.1)查询返回单条结果集

(13.2)查询返回多条结果集

在条件是like时%号该如何定义

一定要注意%本来就是属于条件的一部分,应该将其和值放在一起,然后绑定到问号中

不要在语句中定义%?%,再往%里绑值.这样会导致结果出错

a4645cf4e532894842d1bcc8ceabae5f.png

(14)PreparedStatement 批处理操作

批处理:在与数据库的一次连接中,批量的执行条 SQL 语句

如何更加高效的一次性插入多条数据?

有两种方式:一种,把写好的插入数据的方法在循环中调用10次,另一种,新写一种方法,在建立一次Connection连接中完成十条数据的添加

第一种方法性能极其低下,需要创建十次连接,对象,关闭等操作.非常麻烦

添加批处理时会出现

40fe4819e808822a7db64ab937197b35.png

(15)JDBC中的事务处理

在JDBC中操作数据中数据库事务默认为自动提交,如果事务改为手动提交,我们需要使用

Connection对象中的setAutoCommit 方法来关闭事务自动提交。然后通过

Connection 对象中的 commit 方法rollback 方法进行事务的提交与回滚。

4 JDBC 进阶

(1)动态查询

动态查询:根据用户给定的条件来决定执行什么样的查询。

04f12bb53ada63774ee3846c3613928c.png

(2)应用程序分层

(2.1)应用程序分层是什么

应用程序通过创建不同的包来实现项目的分层,将项目中的代码根据功能做具体划分,并存放在不同的包下

(2.2)分层优点

1、分层结构将应用系统划分为若干层,每一层只解决问题的一部分,通过各层的协作提供整体解决方案。

2、分层结构具有良好的可扩展性,为应用系统的演化增长提供了一个灵活的支持,具有良好的可扩展性。

3、分层架构易于维护。

(2.3)三层结构

三层结构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层

(Business Logic Layer)、数据访问层(Data access layer)。

分层的目的是为了:"高内聚低 耦合"的思想

adbf446a484ce4d5bf2ce38b29a72688.png

(2.4)项目分层

在持久层里起名称时不要包含业务,这样持久层的复用性就会更高

d58ca5c3261c3d9d7b60609ff7c95840.png

添加项目分层时,有时会自动过滤创建的空包,比如:让com.sxt.Dao空包显示出来要点击

a02141809ef9092c533da957b3b073f5.png

3 封装通用的 BaseDao

c4ae039ff2d564932124605f4ea85ef2.png

封装工具包JDBCUtil: ----最上面的impl实现类中代码会有很多重复,下面就是改进方法

4ba49a4a53c8b290dd818fba634614ab.png

持久层(数据访问层)---StudentDao接口和StudentDaoImpl实现类

ab0d8fc034d644ef6cec753a433e0a30.png

StudentDaoImpl

03ea8e55e96597b882ce17f5bf40d66a.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值