引言
在前面分析了项目结构和数据库以及功能:嗖嗖移动业务大厅——功能及数据库分析-优快云博客,这里作模块代码设计。
dao层模式回顾:JDBC-Dao层模式_java tscustomerinsightplatforminfodao.insertlist(l-优快云博客
编写系统常量类
在数据库的某些表中,有些数字表示特定的意思,例如tb_card表中status字段1表示禁用,0表示可用,在数据库操作中如果直接写上数字0或1不利于代码阅读,写一个系统常量类可以很好的提供代码可读性。新建constant包,里面存放系统需要的常量:
public class SystemConstant {
/**
* 卡冻结状态
*/
public static final Integer CARD_STATUS_FREEZE = 1;
/**
* 卡正常状态
*/
public static final Integer CARD_STATUS_NORMAL = 0;
public static final double TALK_PRICE = 0.2; //超出的通话: 0.2元/分
public static final double SMS_PRICE = 0.1; //超出的短信:0.1元/条
public static final double FLOW_PRICE = 0.1; //超出的上网流量:0.1元/MB
}
编写工具包
工具包包通常指的是一个包含多种实用工具类和方法的包,这些工具类和方法能够简化开发过程,提高代码的效率和可读性。这里在项目目录下创建一个util包,里面存放jdbc工具包和Date工具包。
其中jdbc包里面只需提供连接对象和关闭方法即可,对数据库的操作使用commons-dbutil提供的QueryRunner();
public class JdbcUtil {
static Properties props = new Properties();
static {
try{
props.load(JdbcUtil.class.getClassLoader().getResourceAsStream("db.properties"));
Class.forName(props.getProperty("driverClass"));
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static Connection getConnect() throws SQLException {
String jdbcUrl = props.getProperty("jdbcUrl");
String username = props.getProperty("username");
String password = props.getProperty("password");
return DriverManager.getConnection(jdbcUrl, username, password);
}
public static void close(Connection conn,Statement stmt,ResultSet rs){
try{
if(rs != null) rs.close();
if(stmt != null) stmt.close();
if(conn != null) conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void close(Connection conn){
close(conn,null,null);
}
}
还需要一个Date包用于处理日期:
public class DateUtil {
public static String formatDate(Date date,String pattern ){
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(date);
}
/**
* 获取当前系统日期的本月的第一天的日期
* @return
*/
public static Date getCurrentFirstDay(){
//得到当前系统日期
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH,1);
return calendar.getTime();
}
}
编写实体类
在构建数据库交互的面向对象编程架构时,都要遵循一个原则,就是每一张数据库表都要设计一个对应的实体类。通过实体类中的属性和方法,我们能够轻松实现对数据的封装、传输和高效处理。
因此,在项目目录结构下,创建一个名为entity的包,用于专门存放表对应的实体类。同时,在前面数据库分析时,发现所有数据库都有一个名为id的字段,因此,我们可以写一个所有实体类的父实体类,用于存放id,其他类只需继承即可。
父类:BaseEnentity
public abstract class BaseEnentity {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "BaseEnentity{" +
"id='" + id + '\'' +
'}';
}
public BaseEnentity(Integer id) {
this.id = id;
}
public BaseEnentity(){}
}
接下来仅展示一个表tb_mobole_card对应的实体类的编写:
/**
* 用户手机卡
*/
public class MoboleCard extends BaseEnentity{
private String cardNumber;
private String username;
private String password;
private Integer serPackage;
private BigDecimal money;
private Integer status;
public MoboleCard(String cardNumber, String username, String password, Integer serPackage, BigDecimal money, Integer status) {
this.cardNumber = cardNumber;
this.username = username;
this.password = password;
this.serPackage = serPackage;
this.money = money;
this.status = status;
}
public MoboleCard() {
}
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getSerPackage() {
return serPackage;
}
public void setSerPackage(Integer serPackage) {
this.serPackage = serPackage;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public BigDecimal getMoney() {
return money;
}
public void setMoney(BigDecimal money) {
this.money = money;
}
@Override
public String toString() {
return "MoboleCard{" +
"cardNumber='" + cardNumber + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
", serPackage=" + serPackage +
", money=" + money +
", status=" + status +
'}';
}
}
编写业务类
每张数据库表均承载着特定的业务功能,因此,为每一张表设计一个相应的业务类。这种做法不仅有助于清晰地划分数据库操作与业务逻辑之间的界限,还极大地提升了代码的可维护性和可读性,利于后续的软件开发与维护工作。
同样,这些业务也有大量的相似的地方,因此也可以创建一个父类接口,让其他接口去继承,可以减少工作量:
import java.util.List;
/**
* 业务父接口
*/
public interface IService<T>{
/**
* 查询所有
* @return
*/
List<T> queryAll();
/**
* 添加记录
* @param t
*/
void add(T t);
/**
* 根据主键删除
* @param t
*/
void delete(T t);
/**
* 根据主键更新
* @param t
*/
void update(T t);
T queryById(Integer id);
}
这里同样那moboleCard接口做例子:
public interface MoboleCardService extends IService<MoboleCard>{
void login(String cardNumber, String password)throws CardNumberOrPasswordException,CardFreezeException;
MoboleCard queryByCardNummber(String cardNumber);
void charge(String cardnumber,int mon);
void deleteByCard(String cardNumber);
void changeType(String cardNumber, int choose);
}
还要写这个接口的实现类,将需要的业务进行补充:
public class MoboleCardServiceImpl implements MoboleCardService {
@Override
public void login(String cardNumber, String password) throws CardNumberOrPasswordException, CardFreezeException {
//调用dao层方法,调用数据库。
MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
MoboleCard moboleCard = moboleCardDao.queryByCardNumber(cardNumber);
if (Objects.isNull(moboleCard)) {
throw new CardNumberOrPasswordException("卡号或密码错误!");
} else {
//比较密码
if (!moboleCard.getPassword().equals(password)) {
throw new CardNumberOrPasswordException("卡号或密码错误!");
}
if (moboleCard.getStatus() == CARD_STATUS_FREEZE) {
throw new CardFreezeException("该卡已冻结!");
}
}
}
@Override
public List<MoboleCard> queryAll() {
return Collections.emptyList();
}
@Override
public void add(MoboleCard moboleCard) {
MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
moboleCardDao.insert(moboleCard);
}
@Override
public void delete(MoboleCard moboleCard) {
}
@Override
public void update(MoboleCard moboleCard) {
MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
moboleCardDao.update(moboleCard);
}
@Override
public MoboleCard queryById(Integer id) {
return null;
}
public MoboleCard queryByCardNummber(String cardNumber) {
MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
return moboleCardDao.queryByCardNumber(cardNumber);
}
@Override
public void charge(String cardnumber,int mon) {
MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
moboleCardDao.add(cardnumber,mon);
}
@Override
public void deleteByCard(String cardNumber) {
MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
moboleCardDao.deleteByNumber(cardNumber);
}
@Override
public void changeType(String cardNumber, int choose) {
MoboleCardDao mcd = new MoboleCardDaoImpl();
mcd.changeByType(cardNumber,choose);
}
}
编写数据库操作层
同样的,数据库操作也有大量类似的方法,因此写一个父接口:
public interface BaseDao<T> {
List<T> selectAll();
T selectById(Integer id);
void insert(T t);
void delete(Integer id);
void update(T t);
}
其他接口去继承:
public interface MoboleCardDao extends BaseDao<MoboleCard>{
/**
* 根据用户查询手机卡的信息
* @param cardNumber 卡号
* @return MoboleCard 对象
*/
MoboleCard queryByCardNumber(String cardNumber);
/**
* 话费充值
* @param cardnumber
* @param mon
*/
void add(String cardnumber, int mon);
void deleteByNumber(String cardNumber);
void changeByType(String cardNumber, int choose);
}
还要补上实现类:
public class MoboleCardDaoImpl implements MoboleCardDao {
@Override
public MoboleCard queryByCardNumber(String cardNumber) {
QueryRunner queryRunner = new QueryRunner();
Connection conn = null;
try {
conn = JdbcUtil.getConnect();
String sql = "select id,card_number cardNumber,username,password,ser_package serPackage,money,status from tb_mobole_card where card_number = ?";
//要求字段名和属性名一致
MoboleCard moboleCard = queryRunner.query(conn,sql,new BeanHandler<>(MoboleCard.class),cardNumber);
return moboleCard;
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
JdbcUtil.close(conn);
}
}
/**
* 话费充值
* @param cardnumber
* @param mon
*/
@Override
public void add(String cardnumber, int mon) {
String sql = "update tb_mobole_card set money = money + ? where card_number = ?";
BigDecimal money = new BigDecimal(mon);
Connection conn = null;
QueryRunner queryRunner = new QueryRunner();
try{
conn = JdbcUtil.getConnect();
queryRunner.update(conn,sql,money,cardnumber);
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
JdbcUtil.close(conn);
}
}
@Override
public void deleteByNumber(String cardNumber) {
String sql = "delete from tb_mobole_card where card_number = ?";
Connection conn = null;
QueryRunner queryRunner = new QueryRunner();
try{
conn = JdbcUtil.getConnect();
queryRunner.update(conn,sql,cardNumber);
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
JdbcUtil.close(conn);
}
}
@Override
public void changeByType(String cardNumber, int choose) {
Connection conn = null;
String sql = "update tb_mobole_card set ser_package = ? where card_number = ?";
QueryRunner queryRunner = new QueryRunner();
try{
conn = JdbcUtil.getConnect();
queryRunner.update(conn,sql,choose,cardNumber);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JdbcUtil.close(conn);
}
}
@Override
public List<MoboleCard> selectAll() {
return Collections.emptyList();
}
@Override
public MoboleCard selectById(Integer id) {
return null;
}
@Override
public void insert(MoboleCard moboleCard) {
String sql = "insert into tb_mobole_card(card_number,username,password,ser_package,money,status) values(?,?,?,?,?,?)";
Connection conn = null;
QueryRunner queryRunner = new QueryRunner();
try{
conn = JdbcUtil.getConnect();
queryRunner.update(conn,sql,moboleCard.getCardNumber(),moboleCard.getUsername(),
moboleCard.getPassword(),moboleCard.getSerPackage(),
moboleCard.getMoney(),moboleCard.getStatus());
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JdbcUtil.close(conn);
}
}
@Override
public void delete(Integer id) {
}
@Override
public void update(MoboleCard moboleCard) {
QueryRunner queryRunner = new QueryRunner();
Connection conn = null;
try {
conn = JdbcUtil.getConnect();
String sql = "update tb_mobole_card set card_number = ? , username = ?,password=?,ser_package=?,money=?,status=? where id = ?";
queryRunner.update(conn,sql,moboleCard.getCardNumber(),moboleCard.getUsername(),moboleCard.getPassword(),
moboleCard.getSerPackage(),moboleCard.getMoney(),moboleCard.getStatus(),moboleCard.getId());
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
JdbcUtil.close(conn);
}
}
}