三层架构是将整个业务应用划分为表现层,业务逻辑层,数据访问层。
表现层:主要接收用户的请求,以及数据的返回,为客户端提供应用程序的访问。
业务逻辑层:主要负责对数据库的操作,就是从数据访问层获取数据进行一系列操作,该操作是引用数据访问层对数据进行相关操作的增删改查等按照不同顺序执行的一个复杂操作。表现层与数据访问层之间的桥梁。
数据访问层:只有看数据层中包不包含逻辑处理,主要是访问数据库中的文件,它的各个函数主要完成各个对数据文件的操作,不管其他操作。与数据库打交道,主要实现对数据库数据的增删改查和保存。
还有一个不属于三层中任意一层的一层,实体层。作用:1,实现面向对象思想中的封装;2,贯穿3层,在三层之间传递数据,连接三层;3,初学者可以认为,每一个数据表对于一个实体,数据表中的字段对应实体类中的属性。但实际上不是,因为我们需要的实体在数据表对于的实体中并不存在,并且我们完全可以把数据放入同一个实体中;4,三层每一层之间的数据传递是靠变量或实体作为参数传递,实现了功能的实现。
public class User {
Integer product_id;
String name;
Integer quantity_in_stock;
Double unit_price;
public Integer getProduct_id() {
return product_id;
}
public String getName() {
return name;
}
public Integer getQuantity_in_stock() {
return quantity_in_stock;
}
public Double getUnit_price() {
return unit_price;
}
public void setProduct_id(Integer product_id) {
this.product_id = product_id;
}
public void setName(String name) {
this.name = name;
}
public void setQuantity_in_stock(Integer quantity_in_stock) {
this.quantity_in_stock = quantity_in_stock;
}
public void setUnit_price(Double unit_price) {
this.unit_price = unit_price;
}
public User() {
}
public User(Integer product_id, String name, Integer quantity_in_stock, Double unit_price) {
this.product_id = product_id;
this.name = name;
this.quantity_in_stock = quantity_in_stock;
this.unit_price = unit_price;
}
}
实体层中声明了数据表中的每个属性极其每个属性的get和set方法,并声明了改数据表的无参和有参的构造方法。
表现层可以说就是我们的界面,客户把需求告诉表现层,表现层在把需求传递给业务逻辑层,然后表现层再把业务逻辑层返回的数据呈现给客户。
数据访问层,首先在数据访问层在创建一个baseDao类,其中定义了数据访问层中最基础的方法。
下面这是写在resource文件中的用于连接数据库的基础信息。在进行数据库连接时引用resource文件中的信息就行了。
ur.driver="com.mysql.cj.jdbc.Driver"
ur.url="jdbc:mysql://localhost:3306/mysql"
ur.useName="用户名"
ur.psw="密码"
public class BaseDao {
static String driver;
static String url;
static String useName;
static String psw;
static {
try {
Properties properties = new Properties();
InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("resource");
properties.load(is);
driver = properties.getProperty("ur.driver");
url = properties.getProperty("ur.url");
useName = properties.getProperty("ur.useName");
psw = properties.getProperty("ur.psw");
} catch (IOException e) {
System.out.println("文件配置错误");
e.printStackTrace();
}
}
//上面代码开头有个static{ }代码块,又叫静态代码块,是独立于成员函数的代码块,不需要程序主动调
//用,在加载类的时候系统会自动执行static代码块,因此它可以做一些类成员变量的初始化工作。所有的
//static代码块只在jvm加载类的时候执行一次。
public Connection getConnection() {
try {
Class.forName(driver);
Connection connection = DriverManager.getConnection(url, useName, psw);
return connection;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
//DriverManager是用于管理数据库驱动的程序的类,功能包括:
//1,注册数据库驱动的类,在使用JDBC连接数据库之前,必须先注册适用于所有数据的驱动程序。
//2,创建数据库的连接,DriverManager运行我们创建到数据的连接,这是执行sql的第一步。
//3,管理数据库连接池,连接池是一组被预先创建的数据库连接,可以在需要时被重复使用,提高性能。
public int execute(String sql, Object... params) {
Connection connection = this.getConnection();
try {
PreparedStatement stata = connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
stata.setObject(i + 1, params[i]);
}
int hang = stata.executeUpdate();
return hang;
} catch (SQLException e) {
System.out.println("sql执行错误");
e.printStackTrace();
}
return 0;
}
//preparedStatement是预处理用的,用于批量处理。preparedStatement对象包含了sql语句,且这个 //语句大部分时候已经被预编译过了,执行时只需DBMS运行sql语句,而不必先编译。
//stata.setObject(1,name)作用是用name代替sql语句中的第一个?
public void closeAll(Connection connection, PreparedStatement state, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (state != null) {
try {
state.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
}
现在连接和关闭数据库的基础方法写好了。接下来要定义用于操作数据库的方法接口了。
public interface UserDao {
boolean addUser(User user);
User getUser(String name);
}
该接口类中只定义了增加和查找用户的接口方法。
最后是写这些接口方法的实现,impl包
public class UserDaoImpl extends BaseDao implements UserDao {
@Override
public boolean addUser(User user) {
String sql="using sql_store; insert into products value(0,?,?,?);";
//Connection connection=this.getConnection();
if(this.execute(sql,user.getProduct_id(),user.getName(),user.getQuantity_in_stock())>0){
return true;
}
return false;
}
@Override
public User getUser(String name) {
Connection connection=this.getConnection();
String sql="select * from products where name=?;";
try {
PreparedStatement stata=connection.prepareStatement(sql);
stata.setObject(1,name);
ResultSet rs=stata.executeQuery();
//stata.executeQuery执行查询,获取结果。stata.executeUpdate用于增删改查。
//ResultSet对象可以实现遍历功能,rs.next该方法在没有下一行时会返回false。
if(rs.next()){
User user=new User();
user.setProduct_id(rs.getInt("product_id"));
user.setQuantity_in_stock(rs.getInt("quantity_in_stock"));
user.setUnit_price(rs.getDouble("unit_price"));
return user;
}
}catch (SQLException e){
e.printStackTrace();
}
return null;
}
}
实现类既继承了baseDao中的连接和关闭数据库的方法也接收了数据库的接口。
业务逻辑层,接下来我们说一个比较复杂的操作:登陆系统。在登陆系统中我们需要先在数据库中查找有无相应信息,无相应信息就增加一条新信息。这个过程既用到了查找方法也用到了增加用户的方法。
public class UserService {
UserDao userDao = new UserDaoImpl();
public boolean register(User user) {
User temp = userDao.getUser(user.getName());
if (temp == null) {
boolean result = userDao.addUser(user);
return result;
} else
return false;
}
}
这个登陆系统就属于业务逻辑层,它可以是将数据访问层的几个简单方法进行一定的排序构造成一个复杂方法来实现比较复杂的功能。