一:表示层(UI,Main)
1:收集用户输入数据
2:调用业务逻辑层
3:展示数据或展示操作结果
二:业务层(service)
1:开启事务
2:调用DAO层
3:处理数据
4:提交或回滚
三:数据访问层(DAO)
1:查询相关业务逻辑的数据
2:根据相关业务逻辑修改数据
三层架构项目搭建(按开发步骤)
1:utils 存放工具类
2:entity 存放实体类
3:dao存放DAO接口类 impl存放DAO接口实现类
4:service 存放service接口 impl存放service接口实现类
5:view 存放程序启动类
实例演示:对数据库中的person表进行增删改查操作
第一步:创建项目并在src文件下创建db.properties文件
db.properties文件内容如下:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf8
username=root
password=1234
第二步:编写utils工具类
1:DbUtils:连接数据库,事务控制,释放资源
package com.person.utils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
* 连接数据库
* 事务控制
* 释放资源
*/
public class DbUtils {
private static final Properties PROPERTIES = new Properties();
private static final ThreadLocal<Connection> THREAD_LOCAL = new ThreadLocal<>();
static {
InputStream is = DbUtils.class.getResourceAsStream("/db.properties");
try {
PROPERTIES.load(is);
Class.forName(PROPERTIES.getProperty("driver"));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
Connection connection = THREAD_LOCAL.get();
try {
if (connection == null){
connection = DriverManager.getConnection(PROPERTIES.getProperty("url"),PROPERTIES.getProperty("username"),PROPERTIES.getProperty("password"));
THREAD_LOCAL.set(connection);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return connection;
}
//开启事务
public static void begin(){
Connection connection = null;
try {
connection = getConnection();
connection.setAutoCommit(false);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
//提交事务
public static void commit(){
Connection connection = null;
try {
connection = getConnection();
connection.commit();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
//回滚事务
public static void rollback(){
Connection connection = null;
try {
connection = getConnection();
connection.rollback();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
public static void closeAll(Connection connection, Statement statement,ResultSet resultSet){
try {
if (resultSet!=null){
resultSet.close();
}
if (statement!=null){
statement.close();
}
if (connection!=null){
connection.close();
THREAD_LOCAL.remove();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
2:DaoUtils:对数据库的增删改查方法的复用
package com.person.utils;
import com.person.advanced.RowMapper;
import com.person.entity.Person;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
/**
* 复用增删改查方法
*/
public class DaoUtils<T> {
/**
* 公共处理增删改的方法
* sql 执行的sql语句
* args 参数列表
* return 受影响的行数
*/
public int commonsUpdate(String sql,Object... args){
Connection connection = null;
PreparedStatement preparedStatement = null;
connection = DbUtils.getConnection();
try {
preparedStatement = connection.prepareStatement(sql);
for (int i = 0;i<args.length;i++){
preparedStatement.setObject(i+1,args[i]);
}
int result = preparedStatement.executeUpdate();
return result;
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DbUtils.closeAll(null,preparedStatement,null);
}
return 0;
}
/**
* 公共的查询方法(可查询任意一张表,可查询单个对象,也可查询整张表)
* sql 执行的sql语句
* args 参数列表
* return 集合
*/
public List<T> commonSelect(String sql, RowMapper<T> rowMapper , Object... args){
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<T> list = new ArrayList<>();
connection = DbUtils.getConnection();
try {
preparedStatement = connection.prepareStatement(sql);
if (args!=null){
for (int i = 0;i<args.length;i++){
preparedStatement.setObject(i+1,args[i]);
}
}
resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
//id name age borndate email address
//如何根据查询结果完成ORM封装,如何进行对象的创建且赋值
T t = rowMapper.getRow(resultSet);//回调-->调用者提供的一个封装方法ORM
list.add(t);
}
return list;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
}
3:DateUtils:日期转换工具类,字符串,util.date,sql.date之间的相互转换
package com.person.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class DateUtils {
private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
//字符串转Util.Date
public static java.util.Date strToUtil(String str){
try {
return SIMPLE_DATE_FORMAT.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
//Util.Date转Sql.Date
public static java.sql.Date utilToSql(java.util.Date date){
return new java.sql.Date(date.getTime());
}
//Util.Date转字符串
public static String utilToStr(java.util.Date date){
return SIMPLE_DATE_FORMAT.format(date);
}
}
第三步:创建entity存放实体类
package com.person.entity;
import java.util.Date;
/**
* @author shkstart
* @create 2021-03-24 11:00
*/
public class Person {
private int id;
private String name;
private int age;
private Date bornDate;
private String email;
private String address;
public Person() {
}
public Person(int id, String name, int age, Date bornDate, String email, String address) {
this.id = id;
this.name = name;
this.age = age;
this.bornDate = bornDate;
this.email = email;
this.address = address;
}
public Person(String name, int age, Date bornDate, String email, String address) {
this.name = name;
this.age = age;
this.bornDate = bornDate;
this.email = email;
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", bornDate=" + bornDate +
", email='" + email + '\'' +
", address='" + address + '\'' +
'}';
}
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 Date getBornDate() {
return bornDate;
}
public void setBornDate(Date bornDate) {
this.bornDate = bornDate;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
第四步:创建Dao接口,及Dao.impl接口实现类
1:Dao接口
package com.person.dao;
import com.person.entity.Person;
import java.util.List;
public interface PersonDao {
public int insert(Person person);
public int update(Person person);
public int delete(int id);
public Person select(int id);
public List<Person> selectAll();
}
2:Dao.utils接口实现类
package com.person.dao.impl;
import com.person.advanced.impl.PersonRowMapper;
import com.person.dao.PersonDao;
import com.person.entity.Person;
import com.person.utils.DaoUtils;
import com.person.utils.DateUtils;
import com.person.utils.DbUtils;
import com.sun.scenario.effect.impl.prism.PrReflectionPeer;
import javax.naming.Name;
import java.sql.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class PersonDaoImpl implements PersonDao {
private DaoUtils<Person> daoUtils = new DaoUtils();
@Override
public int insert(Person person) {
String sql = "insert into person(name,age,borndate,email,address) values(?,?,?,?,?);";
Object[] args ={person.getName(),person.getAge(),DateUtils.utilToSql(person.getBornDate()),person.getEmail(),person.getAddress()};
return daoUtils.commonsUpdate(sql,args);
}
@Override
public int update(Person person) {
String sql = "update person set name=?,age=?,borndate=?,email=?,address=? where id = ?";
Object[] args ={person.getName(),person.getAge(),DateUtils.utilToSql(person.getBornDate()),person.getEmail(),person.getAddress(),person.getId()};
return daoUtils.commonsUpdate(sql,args);
}
@Override
public int delete(int id) {
String sql = "delete from person where id = ?";
return daoUtils.commonsUpdate(sql,id);
}
@Override
public Person select(int id) {
String sql = "select * from person where id = ?";
List<Person> list = daoUtils.commonSelect(sql,new PersonRowMapper(),id);
if (!list.isEmpty()){
return list.get(0);
}
return null;
}
@Override
public List<Person> selectAll() {
String sql = "select * from person;";
List<Person> list = daoUtils.commonSelect(sql,new PersonRowMapper(),null);
//将集合中每个object元素强转为person 再存放在list
return list;
}
}
第五步:创建service接口及server.impl接口实现类
由于DAO数据访问层把加工后的数据同步到了数据库,且增删改查不涉及对数据的加工处理,故可以不写,但是如果写一个转账操作的话必须要写service
第六步:对数据进行泛型,以便于适用于其他相似的数据操作
1:在包com.oerson.advanced内创建RowMapper接口约束封装对象
package com.person.advanced;
import java.sql.ResultSet;
/**
* 约束封装对象的ORM
*/
public interface RowMapper<T> {
public T getRow(ResultSet resultSet);
}
2:在包com.oerson.advanced.impl内创建PersonRowMapper类实现RowMapper接口
package com.person.advanced.impl;
import com.person.advanced.RowMapper;
import com.person.entity.Person;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
public class PersonRowMapper implements RowMapper<Person> {
@Override
public Person getRow(ResultSet resultSet) {
Person person = null;
try {
int pid = resultSet.getInt("id");
String name = resultSet.getString("name");
int age = resultSet.getInt("age");
Date borndate = resultSet.getDate("borndate");
String email = resultSet.getString("email");
String address = resultSet.getString("address");
person = new Person(pid, name, age, borndate, email, address);
return person;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
第六步:view存放程序启动类(main)
拿查询全部举例:
package com.person.view;
import com.person.dao.PersonDao;
import com.person.dao.impl.PersonDaoImpl;
import com.person.entity.Person;
import com.person.utils.DaoUtils;
import com.person.utils.DateUtils;
import java.util.List;
/**
* @author shkstart
* @create 2021-03-24 11:07
*/
public class TestPerson {
public static void main(String[] args) {
PersonDao personDao= new PersonDaoImpl();
List<Person> list = personDao.selectAll();
System.out.println(list);
}
}