今日内容
- Mybatis的逆向工程
- 销售合同
- 合同管理
- 货物管理
- 七牛云存储
第一章 Mybatis逆向工程
1. 介绍
Mybatis是目前非常流行的持久层框架,其逆向工程更是大大缩减了我们的开发时间。
所谓mybatis逆向工程,就是Mybatis会根据我们设计好的数据表,自动生成domain(实体)、mapper(接口)以及mapper.xml(映射)
而且会在文件中给我们生成单表增删改查的方法和sql
官网地址:https://mybatis.org/generator/
2. 插件使用
2.1 创建一个maven工程,引入依赖
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
2.2 加入配置文件
generatorConfig.xml
<generatorConfiguration>
<!-- classPathEntry:数据库的 JDBC驱动的jar 包地址 -->
<classPathEntry location="lib/mysql-connector-java-5.1.47.jar"/>
<!--生成java代码-->
<context id="context" targetRuntime="MyBatis3">
<!-- 配置生成pojo的序列化的插件-->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<!-- 配置生成toString的序列化的插件 -->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<commentGenerator>
<!-- 是否去除自动生成的(english)注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/saas-export"
userId="root"
password="root"/>
<!--
默认为false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer
为true时,把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal
-->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- 指定生成的实体类的存放位置 -->
<javaModelGenerator targetPackage="com.itheima.domain.cargo" targetProject="./src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 指定生成的Dao映射文件的存放位置 -->
<sqlMapGenerator targetPackage="com.itheima.dao.cargo" targetProject="./src/main/resources">
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!--指定生成的Dao接口的存放位置-->
<javaClientGenerator targetPackage="com.itheima.dao.cargo" targetProject="./src/main/java" type="XMLMAPPER">
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<!-- 指定数据库表 -->
<table tableName="co_factory" domainObjectName="Factory" mapperName="FactoryDao"
enableCountByExample="false" enableDeleteByExample="false"
enableSelectByExample="true" enableUpdateByExample="false"/>
</context>
</generatorConfiguration>
2.3 运行插件,生成文件
3. 生成的文件的使用
3.1 单表crud
package com.itheima.dao.cargo;
import com.itheima.domain.cargo.Factory;
import com.itheima.domain.cargo.FactoryExample;
import java.util.List;
public interface FactoryDao {
//保存
int insert(Factory record);
//保存(动态SQL)
int insertSelective(Factory record);
//修改
int updateByPrimaryKey(Factory record);
//修改(动态SQL)
int updateByPrimaryKeySelective(Factory record);
//根据主键删除
int deleteByPrimaryKey(String id);
//根据主键查询
Factory selectByPrimaryKey(String id);
//条件查询
List<Factory> selectByExample(FactoryExample example);
}
3.2 条件查询
factory表数据
加入mybatis的环境
测试
package com.itheima.test;
import com.itheima.dao.cargo.FactoryDao;
import com.itheima.domain.cargo.Factory;
import com.itheima.domain.cargo.FactoryExample;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @description:
* @author: mryhl
* @date: Created in 2020/10/15 11:47
* @version: 1.1
*/
public class MybatisTest {
/**
* @description 查询所有
* @author mryhl
* @date 2020/10/15 11:51
* @return void
*/
public void testFindAll() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sessionFactory.openSession();
FactoryDao mapper = sqlSession.getMapper(FactoryDao.class);
FactoryExample factoryExample = new FactoryExample();
List<Factory> factories = mapper.selectByExample(factoryExample);
for (Factory factory : factories) {
System.out.println(factory);
}
sqlSession.close();
}
/**
* @description 按条件查询
* @author mryhl
* @date 2020/10/15 11:51
* @return void
*/
public void testSort() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sessionFactory.openSession();
FactoryDao mapper = sqlSession.getMapper(FactoryDao.class);
// 创建FactoryExample对象
FactoryExample factoryExample = new FactoryExample();
FactoryExample.Criteria criteria = factoryExample.createCriteria();
// 查询条件
criteria.andCtypeEqualTo("货物").andAddressEqualTo("长沙");
// 调用查询条件
List<Factory> factories = mapper.selectByExample(factoryExample);
// 遍历查询结果
for (Factory factory : factories) {
System.out.println(factory);
}
sqlSession.close();
}
/**
* @description 排序去重
* @author mryhl
* @date 2020/10/15 11:51
* @return void
*/
public void testFindByExample() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sessionFactory.openSession();
FactoryDao mapper = sqlSession.getMapper(FactoryDao.class);
// 创建FactoryExample对象
FactoryExample factoryExample = new FactoryExample();
FactoryExample.Criteria criteria = factoryExample.createCriteria();
// 查询条件
criteria.andCtypeEqualTo("货物").andAddressEqualTo("长沙");
// 排序的方法
factoryExample.setOrderByClause("id desc");
// 去重的方法
factoryExample.setDistinct(true);
// 调用查询条件
List<Factory> factories = mapper.selectByExample(factoryExample);
// 遍历查询结果
for (Factory factory : factories) {
System.out.println(factory);
}
sqlSession.close();
}
}
支持的条件操作:
第二章 购销合同功能
1. 需求分析
1.1 需求说明
购销合同:买卖双方签订的合同,维系国内的出口公司和海外客户之间联系
购销合同由三部分组成:合同主体信息、合同中所有货物信息、合同中所有附件信息
1.2 数据模型分析
实体关系
数据库表:
- 购销合同表 : co_contract
- 购销合同货物表: co_contract_product
- 购销合同附件表:co_ext_cproduct
实体关系影响
合同、货物、附件三个实体之间是有关系的, 当前中一个变动会影响到其它两个, 主要影响到的属性为数量和金额
合同变化 | 新增 | 删除 | 修改 |
---|---|---|---|
货物 | 无 | 删除合同下所有货物 | 无 |
附件 | 无 | 删除合同下所有附件 | 无 |
货物变化 | 新增 | 删除 | 修改 |
合同 | 变更总金额和货物的数量 | 变更总金额和货物的数量和附件的数量 | 变更总金额 |
附件 | 无 | 删除货物下的所有附件 | 无 |
附件变化 | 新增 | 删除 | 修改 |
合同 | 变更总金额和附件的数量 | 变更总金额和附件的数量 | 变更总金额 |
货物 | 无 | 无 | 无 |
2. 环境搭建
2.1 添加模块, 配置依赖
2.2 复制配置文件
2.3 复制启动类
2.4 添加准备好的类和文件
2.5 Service实现类代码的补全
以FactoryServiceImpl实现类演示其使用方式, 其它的实现类中均以写好对应的实现
package com.itheima.service.cargo.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.dao.cargo.FactoryDao;
import com.itheima.domain.cargo.Factory;
import com.itheima.domain.cargo.FactoryExample;
import com.itheima.service.cargo.FactoryService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
public class FactoryServiceImpl implements FactoryService {
//一定注意Dao的所有引入都是用@Autowired
private FactoryDao factoryDao;
public void save(Factory factory) {
factoryDao.insertSelective(factory);
}
public void update(Factory factory) {
factoryDao.updateByPrimaryKeySelective(factory);
}
public void delete(String id) {
factoryDao.deleteByPrimaryKey(id);
}
public Factory findById(String id) {
return factoryDao.selectByPrimaryKey(id);
}
public List<Factory> findAll(FactoryExample example) {
return factoryDao.selectByExample(example);
}
public PageInfo findByPage(int pageNum, int pageSize, FactoryExample example) {
PageHelper.startPage(pageNum, pageSize);
List<Factory> factories = factoryDao.selectByExample(example);
return new PageInfo(factories, 10);
}
}
第三章 合同管理
1. 需求说明
完成对合同的增删改查操作。注意, 在创建合同的时候添加创建人id\创建部门id\创建时间, 后面会用到。
2. 合同基本功能实现
在export_manager_web
模块的com.itheima.web.controller.cargo
下创建ContractController
package com.itheima.web.controller.cargo;
import cn.hutool.core.lang.UUID;
import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import com.itheima.domain.cargo.Contract;
import com.itheima.domain.cargo.ContractExample;
import com.itheima.service.cargo.ContractService;
import com.itheima.web.controller.BaseController;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Date;
"/cargo/contract") (
public class ContractController extends BaseController {
private ContractService contractService;
/**
* 生成列表
*/
"/list", name = "合同列表查询") (value =
public String list(
@RequestParam(defaultValue = "1", name = "page") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
ContractExample contractExample = new ContractExample();
//1 封装条件
ContractExample.Criteria criteria = contractExample.createCriteria();
criteria.andCompanyIdEqualTo(getCompanyId());
//2 排序
contractExample.setOrderByClause("create_time desc");
PageInfo pageInfo = contractService.findByPage(pageNum, pageSize,contractExample);
request.setAttribute("page", pageInfo);
return "/cargo/contract/contract-list";
}
/**
* 跳转新增页面
*/
"/toAdd", name = "跳转合同新增页面") (value =
public String toAdd() {
return "/cargo/contract/contract-add";
}
/**
* 新增,修改功能
*/
"/edit", name = "合同新增,修改") (value =
public String edit(Contract contract) {
if (StringUtils.isEmpty(contract.getId())) {
//1. 设置主键
contract.setId(UUID.randomUUID().toString());
//2. 设置企业信息
contract.setCompanyId(getCompanyId());
contract.setCompanyName(getCompanyName());
//3.创建人id\创建部门id\创建时间
contract.setCreateBy(getUser().getId());
contract.setCreateDept(getUser().getDeptId());
contract.setCreateTime(new Date());
//4. 设置当前合同的状态
contract.setState(0);//草稿
contractService.save(contract);
} else {
contractService.update(contract);
}
//重定向到list方法
return "redirect:/cargo/contract/list.do";
}
/**
* 跳转到修改
*/
"/toUpdate", name = "跳转合同编辑页面") (value =
public String toUpdate(String id) {
//1. 根据id查询当前合同信息
Contract contract = contractService.findById(id);
request.setAttribute("contract", contract);
//3. 转发到修改页面
return "/cargo/contract/contract-update";
}
/**
* 删除功能
*/
"/delete", name = "合同删除") (value =
public String delete(String id) {
//调用service删除
contractService.delete(id);
//重定向到list方法
return "redirect:/cargo/contract/list.do";
}
}
3. 删除合同的调整
因为合同 货物 附件之间是有关系的, 所以在删除合同的时候,还要删除合同下面的货物和附件信息
修改ContractServiceImpl代码
public void delete(String id) {
//=========================================查询===========================================//
//1. 查询当前合同下的所有附件
ExtCproductExample extCproductExample = new ExtCproductExample();
extCproductExample.createCriteria().andContractIdEqualTo(id);
List<ExtCproduct> extCproductList = extCproductDao.selectByExample(extCproductExample);
//2. 查询当前合同下的所有货物
ContractProductExample contractProductExample = new ContractProductExample();
contractProductExample.createCriteria().andContractIdEqualTo(id);
List<ContractProduct> contractProductList = contractProductDao.selectByExample(contractProductExample);
//========================================附件删除========================================//
for (ExtCproduct extCproduct : extCproductList) {
extCproductDao.deleteByPrimaryKey(extCproduct.getId());
}
//========================================货物删除========================================//
for (ContractProduct contractProduct : contractProductList) {
contractProductDao.deleteByPrimaryKey(contractProduct.getId());
}
//========================================合同删除========================================//
contractDao.deleteByPrimaryKey(id);
}
4. 提交/取消合同
提交和撤销合同的本质是改变合同的状态:
- 提交: 0—> 1 草稿—>已上报
- 撤销: 1–>0 已上报—>草稿
4.1 ContractController
/**
* 提交合同
*/
"/submit", name = "提交合同") (value =
public String submit(String id) {
Contract contract = new Contract();
contract.setId(id);
contract.setState(1);
contractService.update(contract);
//重定向到list方法
return "redirect:/cargo/contract/list.do";
}
/**
* 撤销提交
*/
"/cancel", name = "撤销提交") (value =
public String cancel(String id) {
Contract contract = new Contract();
contract.setId(id);
contract.setState(0);
contractService.update(contract);
//重定向到list方法
return "redirect:/cargo/contract/list.do";
}
第四章 货物管理
1. 货物列表
在export_manager_web
模块的com.itheima.web.controller.cargo
下创建ContractProductController
package com.itheima.web.controller.cargo;
import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import com.itheima.domain.cargo.ContractProductExample;
import com.itheima.domain.cargo.Factory;
import com.itheima.domain.cargo.FactoryExample;
import com.itheima.service.cargo.ContractProductService;
import com.itheima.service.cargo.FactoryService;
import com.itheima.web.controller.BaseController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
"/cargo/contractProduct") (
public class ContractProductController extends BaseController {
private ContractProductService contractProductService;
private FactoryService factoryService;
"/list", name = "货物列表查询") (value =
public String list(
@RequestParam(defaultValue = "1", name = "page") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
String contractId) {
ContractProductExample contractProductExample = new ContractProductExample();
//1 查询当前合同下的所有货物
ContractProductExample.Criteria criteria = contractProductExample.createCriteria();
criteria.andCompanyIdEqualTo(getCompanyId());//企业id
criteria.andContractIdEqualTo(contractId);//合同id
PageInfo pageInfo = contractProductService.findByPage(pageNum, pageSize, contractProductExample);
request.setAttribute("page", pageInfo);
//2 查询所有生产货物的厂家列表
FactoryExample factoryExample = new FactoryExample();
factoryExample.createCriteria().andCtypeEqualTo("货物");
List<Factory> factoryList = factoryService.findAll(factoryExample);
request.setAttribute("factoryList", factoryList);
//3. 回传合同id
request.setAttribute("contractId", contractId);
return "/cargo/product/product-list";
}
}
2. 新增货物
2.1 ContractProductController
/**
* 新增,修改功能
*/
"/edit", name = "货物新增,修改") (value =
public String edit(ContractProduct contractProduct) {
if (StringUtils.isEmpty(contractProduct.getId())) {
//1. 设置主键
contractProduct.setId(UUID.randomUUID().toString());
//2. 设置企业信息
contractProduct.setCompanyId(getCompanyId());
contractProduct.setCompanyName(getCompanyName());
contractProductService.save(contractProduct);
} else {
contractProductService.update(contractProduct);
}
//重定向到list方法
return "redirect:/cargo/contractProduct/list.do?contractId=" + contractProduct.getContractId();
}
2.2 ContractProductServiceImpl
public void save(ContractProduct contractProduct) {
// 根据id查询合同信息
Contract contract = contractDao.selectByPrimaryKey(contractProduct.getContractId());
// 设置商品的金额
double amount = contractProduct.getPrice() * contractProduct.getCnumber();
contractProduct.setAmount(amount);
contractProductDao.insertSelective(contractProduct);
// 保存合同的信息
// 商品种类数
contract.setProNum(contract.getProNum() + 1);
// 合同总金额
contract.setTotalAmount(contract.getTotalAmount() + amount);
contractDao.updateByPrimaryKeySelective(contract);
}
3. 修改货物
3.1 跳转修改页面
修改ContractProductController添加代码
"/toUpdate", name = "跳转货物编辑页面") (value =
public String toUpdate(String id) {
//1. 根据id查询当前货物信息
ContractProduct contractProduct = contractProductService.findById(id);
request.setAttribute("contractProduct", contractProduct);
//2. 查询所有生产货物的厂家列表
FactoryExample factoryExample = new FactoryExample();
factoryExample.createCriteria().andCtypeEqualTo("货物");
List<Factory> factoryList = factoryService.findAll(factoryExample);
request.setAttribute("factoryList", factoryList);
//3. 转发到修改页面
return "/cargo/product/product-update";
}
3.2 修改货物
修改ContractProductServiceImpl添加代码
public void update(ContractProduct contractProduct) {
// 根据id查询合同信息
Contract contract = contractDao.selectByPrimaryKey(contractProduct.getContractId());
ContractProduct contractProduct1 = contractProductDao.selectByPrimaryKey(contractProduct.getId());
// 设置商品的金额
double amount = contractProduct.getPrice() * contractProduct.getCnumber();
contractProduct.setAmount(amount);
contractProductDao.updateByPrimaryKeySelective(contractProduct);
// 判断原来的数据库中保存的值,因为有错误的测试插入,可能存在空值
if (contractProduct1.getAmount()==null){
contractProduct1.setAmount(0.0);
}
contract.setTotalAmount(contract.getTotalAmount() + amount - contractProduct1.getAmount());
contractDao.updateByPrimaryKeySelective(contract);
}
4. 删除货物
4.1 ContractProductController
"/delete", name = "货物删除") (value =
public String delete(String id, String contractId) {
//调用service删除
contractProductService.delete(id);//货物id
//重定向到list方法
return "redirect:/cargo/contractProduct/list.do?contractId=" + contractId;
}
4.2 ContractProductServiceImpl
public void delete(String id) {
// 查询商品信息
ContractProduct contractProduct = contractProductDao.selectByPrimaryKey(id);
// 查询附件
ExtCproductExample extCproductExample = new ExtCproductExample();
extCproductExample.createCriteria().andContractProductIdEqualTo(id);
List<ExtCproduct> extCproducts = extCproductDao.selectByExample(extCproductExample);
// 查询合同
Contract contract = contractDao.selectByPrimaryKey(contractProduct.getContractId());
// 执行删除附件
double amount = 0.0;
for (ExtCproduct extCproduct : extCproducts) {
amount += extCproduct.getAmount();
extCproductDao.deleteByPrimaryKey(extCproduct.getId());
}
// 删除货物
contractProductDao.deleteByPrimaryKey(id);
// 修改合同 商品种类数
contract.setProNum(contract.getProNum() - 1);
// 附件种类数
contract.setExtNum(contract.getProNum() - extCproducts.size());
// 金额
contract.setTotalAmount(contract.getTotalAmount() - contractProduct.getAmount() - amount );
contractDao.updateByPrimaryKeySelective(contract);
}
第五章 七牛云存储
添加货物和附件时需要上传图片,图片我们上传到一个第三方的托管服务器,本项目我们使用七牛云存储
1. 账户申请
1.1 注册账户
申请免费注册今日注册页面,填写必要信息
1.2 激活账号
通过邮箱验证的方式进行激活
1.3 实名认证
实名认证需要准备好身份证正反面照片和支付宝账号
2. 使用案例
2.1 创建空间
操作步骤:
- 点击云产品的对象存储, 进入新建空间的页面
- 创建一个空间, 名字自定义 ,其它按照图上来
- 域名暂时不用绑定, 七牛云会默认分派一个(有效期30天)
2.2 查找秘钥
操作步骤:
- 点击小头像, 选择秘钥管理, 进入秘钥管理页面
- 点击显示, 就可以查看到秘钥, 然后将其记录下来, 备用
**数据资料**
空间名称:saas-tj4
对外域名:http://qi8eho848.hn-bkt.clouddn.com/
AK:B6NvfR2Gp_8mA8LyVW1AwKsJ4ISpdsORS85ZH2Z-
SK:vS5YNOikZjhINGmO7ZDOG1hZR-7i-NLRbSIL71tB
2.3 开发文档
https://developer.qiniu.com/kodo/sdk/1239/java
3. 文件上传案例
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
/**
* @description:
* @author: mryhl
* @date: Created in 2020/10/15 19:50
* @version: 1.1
*/
public class QiniuDemo {
public static void main(String[] args) {
//指定region2 华南地区
Configuration cfg = new Configuration(Region.region2());
UploadManager uploadManager = new UploadManager(cfg);
//填写自己的信息
String accessKey = "6RDghSCTOnkzq***************tWsB4VbIEtlK";
String secretKey = "nRJqQDTVIxxu7***************hm_Rya3zFnWg";
String bucket = "saas-export-yhl";
//准备一张图片
String localFilePath = "C:/Users/mryhl/Pictures/Camera Roll/12.jpg";
String key = null;
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
try {
Response response = uploadManager.put(localFilePath, key, upToken);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
ex2.printStackTrace();
}
}
}
}