理论 :
标准做法:定义一个接口,然后再一个或多个类去实现,疑问来了:为什么我们要维护两份同构代码,而不直接使用一个类呢? 为什么非要用一个接口呢 直接用两个实现类不可以吗
业务层中为什么一定要用接口,不用行不行?回答:不是必须要使用接口,但强烈建议使用接口。
1 为了基于SPringBoot 框架下 还可以再扩展 如果只用类 则无从下口
2 两个同事一块工作 定义一个接口 就相当于一个占位符 让他去写就行了 保证工作并行
3 适配器 或者说是一个简单的工厂类 如果没有定义接口 那么面对众多的实现类 无法统一操作
4 规范!! 想让人符合 但有不可能看着别人写代码 就先出一套接口 让别人看着办
5 java没有多继承 但可以实现多接口 说是面向对象 实际上最好还是要面向接口编程
‘
定义接口和实现类
接口的名字一般都是 xxxService 实现类则时 XXXServicelmpl
实现接口的时候不需要任何注解 实现XXXServicelmpl (实现类)则需要添加注解 @Service 并指明名称 如 @Service(“companyService”)
在实现类中,通过注解@Autowired,注入数据仓库层Repository接口;
当实现的接口的实现类中 ,涉及数据库数据的删除或修改时,方法上一定要添加注解@Transactional,否则会执行不成功
实践:
1 创建接口 并定义接口内的方法
1)在java内的项目包下 新建 service包(一般接口都放在其中) 然后再其中新建XXXService接口
2)定义要实现的方法 和方法 的返回值(如果遇到修改和删除 还要添加注解 @Transactional 否则会执行不成功)
/**
- 公司业务层接口
- repository 是为业务层接口服务 而这个公司业务层 接口 直接面向控制层 下面写的这些接口(方法)都是控制层要用的
- 不用添加任何注解 写完了 在实现类中 实现接口 需要加注解 加上别名 这个别名是控制层要用的
- 写接口其实就是写个方法 实际上实现要自己去实现类去实现
*/
public interface CompanyService {
// 定义一个保存接口 其实接口当当与一个方法 并没有实现
void save(Company company);
// 根据uuid删除修改记录 删除一定要加 transactioal
@Transactional
void dalete(String uuid);
// 修改
@Transactional
void update(Company company);
// 查询全部数据
List findAll();
// 执行原生SQL语句查询
List findByNativeSQL(String companyname);
}
2创建实现类
1) java里的项目包下 的 新创建的service 包内 新建 impl 包(实现类全部再impl包内)
2)新建实现类 XXXServiceImpl 并且继承 刚定义好的接口 (此时会报错 让你实现接口内定义好的方法 直接Alt+Enter 进行导入即可)
3) 声明实现类 @Autowried(xxxxService) 其中xxxxService为别名 控制层要用到的
4)@Autowired
private CompanyRepo companyRepo;
引进 数据仓库层 通过定义的变量类型 引进之后 就可以通过其中的变量名实现其中增删改查的方法
因为 数据仓库层 已经配好了 对应的数据表 所以直接用即可
5)@Override
public void save(Company company) {
companyRepo.save(company);
// 因为引入的数据仓库层里面
}
注解 @Override 这个是引入自带的 代表重写方法 备注一般写在方法内部
遇到删改 还是要注解一下
@Transactional
具体实现如下
/**
- 公司业务层实现类
- 1 在实现类中 实现接口 需要加注解 加上别名 这个别名是控制层要用的 @Service(“companyService”)
- 2 引入数据仓库接口
@Autowiredprivate CompanyRepo companyRepo; 依赖注入 控制反转- 3 把方法实现 借用数据仓库里继承的Jpa 方法 和自己写的原生sql方法
- 注: 凡是有注解的 注释一定写道 方法里面
@Override
public List findByNativeSQL(String companyname) {
// 调用非封装 而是直接在repository 定义的原生SQL方法
return companyRepo.findByNativeSQL(companyname);
}
*
*/
@Service(“companyService”)
// 指明这是一个实现类 并且实现类的别称叫companyService
public class CompanyServiceImpl implements CompanyService {
@Autowired
private CompanyRepo companyRepo;
// 引进 数据仓库层 引进之后 就可以通过其实现其中增删改查的方法
// 数据仓库层 已经配好了 对应的数据表 所以直接用即可
@Override
public void save(Company company) {
companyRepo.save(company);
// 因为引入的数据仓库层里面
}
@Override
public void dalete(String uuid) {
companyRepo.deleteById(uuid);
}
@Transactional
// 稳妥起见 还是加上他
@Override
public void update(Company company) {
companyRepo.save(company);
// 语句跟 save 是一样的 原因是 程序会自动判断 如果主键为空 代表没有这条记录 则插入 如果不为空 则为更新
}
@Override
public List<Company> findAll() {
return companyRepo.findAll();
}
@Override
public List<Company> findByNativeSQL(String companyname) {
return companyRepo.findByNativeSQL(companyname);
// 调用非封装 而是直接在repository 定义的原生SQL方法
}
}