模仿天猫实战【SSM版】——项目起步

 
 

前言:如今本身的学习彷佛遇到了瓶颈,感受学习了 SSM 以后有一些迷茫,不知道接下来该往哪里去努力了,我以为这是个很很差的状态,为了度过这段时期,我准备把天猫模仿下来(给本身找点事作)以后开始去巩固 Java 的基础知识,也准备好暑假去找实习。php

第一步:需求分析

首先要肯定要实现哪些功能,须要对需求进行完整的分析,才能在编写项目的时候有条不紊,咱们的目的很明确:就是模仿天猫前端 + 本身实现后端。而且尽最大努力去下降这个项目的复杂度(毕竟高深的东西不懂)。前端

前端需求分析

规定:全天猫没有店铺,就只有惟一一家叫作 Tmall 的商家,卖全部的东西。java

  • 1.数据的显示:

首页数据显示分析:mysql

首先是搜索栏下方的九个商品,须要从数据库中取出销量最高的几个产品,关于标红的关键字,是要知足必定条件的,好比:这一个星期内销量超过多少...git

 
 

接着是分类导航栏,首先是商品分类右边固定的两个连接【天猫超市】和【天猫国际】,还有紧跟着的八个超链,这个能够设计为一个单表,存储它显示的文字和连接过去的地址,而后是具体的 16 个分类以及轮播:github

 
 

下面的具体产品展现比较复杂,咱们能够本身作一下简化,好比就展现几个产品比较多的固定的几个分类就行了,其余的就直接舍弃:web

 
 
  • 总结: 总之就是须要显示各类数据库中的数据
  • 2.登陆/注册页

须要有一个登陆/注册页,可以完成用户的登陆和注册功能,并能提供基础的例如判断空值等功能。spring

  • 3.产品搜索页
 
 

左上角的图标咱们能够统一简化成 Tmall 的图片,商品图片,咱们能够整个大分类使用一张图,主要就是实现排序功能还有搜索功能sql

  • 4.产品展现页

天猫原生的产品展现页有些复杂,咱们能够本身简化一下,就不要选这么多东西,都是一口价,数据库

 
 

另外下方规格参数和评价都不能省略:

 
 
  • 5.购物车/购买页面

第二步:表结构设计

根据对于前端的分析,数据库有了一些眉目,为了简化项目的难度,因此咱们须要本身想点办法,先来构思一下大概须要一些什么样的表:

 
 

我大概就想出来须要用到这些表,咱们一个一个来建立它们:

表一:分类表

首先咱们须要一个表来存储咱们的分类信息,也就是【女装/内衣】、【男装/运动户外】在内的 16 个分类,为了高度一致,这 16 个分类不能多也不能少。

 
 

为了简化任务,能够观察出,【热门手机】、【特点手机】分栏下的东西都是【手机/数码/电脑办公】类别里的东西,因此咱们直接砍掉,右边的一些图片超链也给直接砍掉,咱们规定每一行显示的产品数目就能够了,这样就简单多了。

CREATE TABLE category (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', name varchar(255) NOT NULL COMMENT '分类的名字', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

表二:商品分类右边的超链表

即在【天猫国际】右边的 8 个超链,咱们单独新建一个表来存储超链显示的文字和连接的地址,这样就能够任意的修改其内容:

 
 

百度翻译【推荐连接】翻译为【Referral links】,那咱们也这么给咱们的表命名好了:

CREATE TABLE referal_link (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', text varchar(255) NOT NULL COMMENT '超链显示的文字', link varchar(255) NOT NULL COMMENT '超链的地址', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

表三:产品表

每一个分类下都要必定的产品,这些产品还有本身的一些属性,因此另外须要属性表,这个表另外建立,咱们先来观察一下一个产品表须要一些什么东西:

 
 
  • 用于展现的 5 张图片
  • 产品名称
  • 小标题(即名称下面一排标红的小字)
  • 价格(就一口价,没别的)
  • 销量(别月销量了,能简化就简化一下)
  • 累计评价(还须要设计一个评价表)
  • 库存
  • 属性(须要关联另外的属性表)
CREATE TABLE product (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', name varchar(255) NOT NULL COMMENT '产品的名称', sub_title varchar(255) DEFAULT NULL COMMENT '小标题', price float DEFAULT NULL COMMENT '价格', sale int(11) DEFAULT NULL COMMENT '销量', stock int(11) DEFAULT NULL COMMENT '库存', category_id int(11) DEFAULT NULL COMMENT '对应的分类id', PRIMARY KEY (id), CONSTRAINT fk_product_category FOREIGN KEY (category_id) REFERENCES category (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  • 注意: 其中产品图片,累计评价,属性都做为单独的表存在并让当前表的 id 做为外键

表四:属性表

 
 

去掉详细的规格参数划分,其实属性也就是一个名字而已(简化简化简化)。

CREATE TABLE property (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', name varchar(255) DEFAULT NULL COMMENT '属性名称', product_id int(11) NOT NULL COMMENT '对应的产品id', PRIMARY KEY (id), CONSTRAINT fk_property_product FOREIGN KEY (product_id) REFERENCES product(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  • 忽然想到的问题:
    每个产品的属性实际上是不少的,若是每个产品都对应不少属性的话,对于天猫这样的数据量来讲,应该会让数据库爆炸的吧...
  • 改进方法:
    将属性表关联到 category 表上,由于其实每个分类下的产品的属性差很少!

修改数据库

根据以上问题,修改一下数据库表之间的关系

 
 

并将属性表的外键修改成 category 的主键:

CREATE TABLE property (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', name varchar(255) DEFAULT NULL COMMENT '属性名称', category_id int(11) NOT NULL COMMENT '对应的分类id', PRIMARY KEY (id), CONSTRAINT fk_property_category FOREIGN KEY (category_id) REFERENCES category(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

表五:属性值表

其中就是保存了对应属性的值,而且应该有两个外键,一个指向 Property 表,而另外一个则指向 Product 表

CREATE TABLE property_value (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', product_id int(11) NOT NULL COMMENT '对应产品id', properti_id int(11) NOT NULL COMMENT '对应属性id', value varchar(255) DEFAULT NULL COMMENT '具体的属性值', PRIMARY KEY (id), CONSTRAINT fk_property_value_property FOREIGN KEY (properti_id) REFERENCES property (id), CONSTRAINT fk_property_value_product FOREIGN KEY (product_id) REFERENCES product (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

表六:产品图片表

这个表名义上是保存了产品的图片,其实只是保存了产品图片的位置即图片名称,咱们能够规定全部的产品图片都放在一个统一的文件夹下面,而后经过 id 来获取对应名称的图片

CREATE TABLE product_image (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', product_id int(11) DEFAULT NULL COMMENT '对应的产品id', PRIMARY KEY (id), CONSTRAINT fk_product_image_product FOREIGN KEY (product_id) REFERENCES product (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  • 注意: 咱们经过把产品图片的文件命名为 id.jpg ,而后经过相对路径来获取到产品图片

表七:用户表

用户表很简单,也没有权限之类的东西:

CREATE TABLE user (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', name varchar(255) NOT NULL COMMENT '用户名称', password varchar(255) NOT NULL COMMENT '用户密码', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  • 咱们或许会在以后把密码弄成 “*********” 这种形式的,可是如今一切为了简单!

表八:评价表

 
 

评价表对应了用户和产品两个表,也比较简单,咱们为了简单,把上面红色的部分所有砍掉,由于没有商家,因此也不须要回复用户的评价,都砍掉砍掉!

CREATE TABLE review (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', content varchar(4000) DEFAULT NULL COMMENT '评价内容', user_id int(11) NOT NULL COMMENT '对应的用户id', product_id int(11) NOT NULL COMMENT '对应的产品id', createDate datetime DEFAULT NULL COMMENT '评价时间', PRIMARY KEY (id), CONSTRAINT fk_review_product FOREIGN KEY (product_id) REFERENCES product (id), CONSTRAINT fk_review_user FOREIGN KEY (user_id) REFERENCES user (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

表九:订单表

因为 Order 是 MySql 的一个关键字,因此咱们在订单表的最后添加一个下划线:

CREATE TABLE order_ (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', order_code varchar(255) NOT NULL COMMENT '订单号', address varchar(255) NOT NULL COMMENT '收货地址', post varchar(255) NOT NULL COMMENT '邮编', receiver varchar(255) NOT NULL COMMENT '收货人姓名', mobile varchar(255) NOT NULL COMMENT '手机号码', user_message varchar(255) NOT NULL COMMENT '用户备注的信息', create_date datetime NOT NULL COMMENT '订单建立时间', pay_date datetime DEFAULT NULL COMMENT '订单支付时间', delivery_date datetime DEFAULT NULL COMMENT '发货日期', confirm_date datetime DEFAULT NULL COMMENT '确认收货日期', user_id int(11) DEFAULT NULL COMMENT '对应的用户id', status varchar(255) NOT NULL COMMENT '订单状态', PRIMARY KEY (id), CONSTRAINT fk_order_user FOREIGN KEY (user_id) REFERENCES user (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

表十:订单项表

一个订单里面可能有多个订单项,一个产品也可能对应多个订单项,因此这个表应该有两个外键:

CREATE TABLE order_item (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', product_id int(11) NOT NULL COMMENT '对应产品id', order_id int(11) NOT NULL COMMENT '对应订单id', number int(11) DEFAULT NULL COMMENT '对应产品购买的数量', PRIMARY KEY (id) COMMENT '邮编', CONSTRAINT fk_order_item_product FOREIGN KEY (product_id) REFERENCES product (id), CONSTRAINT fk_order_item_order FOREIGN KEY (order_id) REFERENCES order_ (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

汇总:

咱们在建立表以前,应该建立一个新的数据库,并命名为【tmall_ssm】

DROP DATABASE IF EXISTS tmall_ssm; CREATE DATABASE tmall_ssm DEFAULT CHARACTER SET utf8; 

将这十个表汇个总就是:

DROP DATABASE IF EXISTS tmall_ssm; CREATE DATABASE tmall_ssm DEFAULT CHARACTER SET utf8; use tmall_ssm; CREATE TABLE category ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', name varchar(255) NOT NULL COMMENT '分类的名字', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE referal_link ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', text varchar(255) NOT NULL COMMENT '超链显示的文字', link varchar(255) NOT NULL COMMENT '超链的地址', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE product ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', name varchar(255) NOT NULL COMMENT '产品的名称', sub_title varchar(255) DEFAULT NULL COMMENT '小标题', price float DEFAULT NULL COMMENT '价格', sale int(11) DEFAULT NULL COMMENT '销量', stock int(11) DEFAULT NULL COMMENT '库存', category_id int(11) DEFAULT NULL COMMENT '对应的分类id', PRIMARY KEY (id), CONSTRAINT fk_product_category FOREIGN KEY (category_id) REFERENCES category (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE property ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', name varchar(255) DEFAULT NULL COMMENT '属性名称', category_id int(11) NOT NULL COMMENT '对应的分类id', PRIMARY KEY (id), CONSTRAINT fk_property_category FOREIGN KEY (category_id) REFERENCES category(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE property_value ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', product_id int(11) NOT NULL COMMENT '对应产品id', properti_id int(11) NOT NULL COMMENT '对应属性id', value varchar(255) DEFAULT NULL COMMENT '具体的属性值', PRIMARY KEY (id), CONSTRAINT fk_property_value_property FOREIGN KEY (properti_id) REFERENCES property (id), CONSTRAINT fk_property_value_product FOREIGN KEY (product_id) REFERENCES product (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE product_image ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', product_id int(11) DEFAULT NULL COMMENT '对应的产品id', PRIMARY KEY (id), CONSTRAINT fk_product_image_product FOREIGN KEY (product_id) REFERENCES product (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE user ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', name varchar(255) NOT NULL COMMENT '用户名称', password varchar(255) NOT NULL COMMENT '用户密码', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE review ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', content varchar(4000) DEFAULT NULL COMMENT '评价内容', user_id int(11) NOT NULL COMMENT '对应的用户id', product_id int(11) NOT NULL COMMENT '对应的产品id', createDate datetime DEFAULT NULL COMMENT '评价时间', PRIMARY KEY (id), CONSTRAINT fk_review_product FOREIGN KEY (product_id) REFERENCES product (id), CONSTRAINT fk_review_user FOREIGN KEY (user_id) REFERENCES user (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE order_ ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', order_code varchar(255) NOT NULL COMMENT '订单号', address varchar(255) NOT NULL COMMENT '收货地址', post varchar(255) NOT NULL COMMENT '邮编', receiver varchar(255) NOT NULL COMMENT '收货人姓名', mobile varchar(255) NOT NULL COMMENT '手机号码', user_message varchar(255) NOT NULL COMMENT '用户备注的信息', create_date datetime NOT NULL COMMENT '订单建立时间', pay_date datetime DEFAULT NULL COMMENT '订单支付时间', delivery_date datetime DEFAULT NULL COMMENT '发货日期', confirm_date datetime DEFAULT NULL COMMENT '确认收货日期', user_id int(11) DEFAULT NULL COMMENT '对应的用户id', status varchar(255) NOT NULL COMMENT '订单状态', PRIMARY KEY (id), CONSTRAINT fk_order_user FOREIGN KEY (user_id) REFERENCES user (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE order_item ( id int(11) NOT NULL AUTO_INCREMENT COMMENT '惟一索引id', product_id int(11) NOT NULL COMMENT '对应产品id', order_id int(11) NOT NULL COMMENT '对应订单id', number int(11) DEFAULT NULL COMMENT '对应产品购买的数量', PRIMARY KEY (id) COMMENT '邮编', CONSTRAINT fk_order_item_product FOREIGN KEY (product_id) REFERENCES product (id), CONSTRAINT fk_order_item_order FOREIGN KEY (order_id) REFERENCES order_ (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

直接复制进 MySql 中执行,就能看到咱们建立好的十个数据库:

 
 

第三步:建立 SSM 开发环境

根据以前我写过的博文:IDEA 整合 SSM 搭建好 SSM 开发环境,这里给出完整的项目结构和 pom.xml 文件:

  • 完整的项目结构:
 
 
  • pom.xml 文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <packaging>war</packaging> <name>wmyskxz</name> <groupId>cn.wmyskxz</groupId> <artifactId>wmyskxz</artifactId> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.7</version> <configuration> <connectors> <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> <port>8888</port> <maxIdleTime>30000</maxIdleTime> </connector> </connectors> <webAppSourceDirectory>${project.build.directory}/${pom.artifactId}-${pom.version} </webAppSourceDirectory> <contextPath>/</contextPath> </configuration> </plugin> </plugins> </build> <properties> <!-- 设置项目编码编码 --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- spring版本号 --> <spring.version>4.3.5.RELEASE</spring.version> <!-- mybatis版本号 --> <mybatis.version>3.4.1</mybatis.version> </properties> <dependencies> <!-- pageHelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.2-beta</version> </dependency> <!--jsqlparser--> <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>1.0</version> </dependency> <!-- jstl标签 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-impl</artifactId> <version>1.2.5</version> </dependency> <!-- java ee --> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> </dependency> <!-- 单元测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!-- 实现slf4j接口并整合 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.2</version> </dependency> <!-- JSON --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.7</version> </dependency> <!-- 数据库 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.41</version> <scope>runtime</scope> </dependency> <!-- 数据库链接池 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <!-- MyBatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!-- mybatis/spring整合包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> </dependencies> </project> 

MyBatis 逆向工程

按照正常的流程,咱们应该去建立数据库对应的 POJO 和 DAO 类还有对应的 mapper 映射文件,按照上面的分析咱们一共有十张表,想象一下为这十张表作这些无技术含量的机械化的繁杂的工做是多么头疼的一件事,咱们但愿的是:有人帮我自动建立好这些!

  • MyBatis 官方提供了一种名为 “逆向工程” 的机制,其能够针对数据库中的单表自动生成 MyBatis 执行所须要的代码
  • 包括:
    Java 实体类、Mapper映射配置、Mapper代理接口

第一步:添加必要的 jar 包

咱们使用逆向工程,须要先导入 Mybatis Generator 的官方包,因为咱们使用的是 Maven 搭建的 SSM 项目,全部咱们能够去 Maven 的官网去查询须要的相关包:http://mvnrepository.com/

 
 

戳进去点击最新的包:

 
 

就能够在下方找到 Maven 依赖添加的语句:

 
 

直接粘进 pom.xml 就能够了,这里就不演示了。

第二步:generatorConfig.xml

在【resources】下建立 generatorConfig.xml 配置文件,该配置文件说明了一些逆向工程的细节:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <context id="DB2Tables" targetRuntime="MyBatis3"> <!-- 是否去除自动生成的代码中的注释 true:是 false:否--> <commentGenerator> <property name="suppressDate" value="true"/> <property name="suppressAllComments" value="true"/> </commentGenerator> <!-- 数据库链接信息:驱动类、链接地址、用户名、密码 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost/tmall_ssm" userId="root" password="root"> </jdbcConnection> <!-- 默认 false,把 JDBC DECIMAL 和 NUMERIC 类型解析为 Integer 为 true 时解析为 java.math.BigDecimal --> <javaTypeResolver> <property name="forceBigDecimals" value="false"/> </javaTypeResolver> <!-- targetProject:生成 POJO 类的位置 --> <javaModelGenerator targetPackage="cn.wmyskxz.pojo" targetProject="src/main/java"> <!-- enableSubPackages:是否让 schema 做为包的后缀--> <property name="enableSubPackages" value="false"/> <!-- trimStrings:从数据库返回的值被清理先后的空格 --> <property name="trimStrings" value="true"/> </javaModelGenerator> <!-- targetProject:生成xml映射文件存放位置 --> <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"> <!-- enableSubPackages:是否让 schema 做为包的后缀--> <property name="enableSubPackages" value="true"/> </sqlMapGenerator> <!-- targetProject:生成mapper类存放位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="cn.wmyskxz.mapper" targetProject="src/main/java"> <!-- enableSubPackages:是否让 schema 做为包的后缀--> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <!--生成对应表及类名 tableName:要生成的表名 domainObjectName:生成后的实例名 enableCountByExample:Count语句中加入where条件查询,默认为true开启 enableUpdateByExample:Update语句中加入where条件查询,默认为true开启 enableDeleteByExample:Delete语句中加入where条件查询,默认为true开启 enableSelectByExample:Select多条语句中加入where条件查询,默认为true开启 selectByExampleQueryId:Select单个对象语句中加入where条件查询,默认为true开启 --> <table tableName="category" domainObjectName="Category" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <!-- 使用数据库中实际的字段名做为生成的实体类的属性 --> <property name="useActualColumnNames" value="true"/> <!-- 使用自增加键 --> <property name="my.isgen.usekeys" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="property" domainObjectName="Property" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="useActualColumnNames" value="true"/> <property name="my.isgen.usekeys" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="product" domainObjectName="Product" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="product_image" domainObjectName="ProductImage" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="order_" domainObjectName="Order" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="property_value" domainObjectName="PropertyValue" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="review" domainObjectName="Review" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="order_item" domainObjectName="OrderItem" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="referal_link" domainObjectName="ReferalLink" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> </context> </generatorConfiguration> 

这样配置文件也就编写好了

第三步:逆向数据文件生成类

在编写完配置文件只有,就须要加载该配置文件,利用逆向工程的机制来对数据库的各个表进行一系列文件的生成,咱们在【test/java】包下建立【TestMyBatisGenerator】类:

import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.api.ShellCallback; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; import java.io.File; import java.util.ArrayList; import java.util.List; /** * 逆向工程测试类 * * @author: @我没有三颗心脏 * @create: 2018-04-27-上午 8:26 */ public class TestMybatisGenerator { public static void main(String[] args) throws Exception { // warnings 为用于放置生成过程当中警告信息的集合对象 List<String> warnings = new ArrayList<String>(); // 指定是否覆盖重名文件 boolean overwrite = true; // 加载配置文件 File configFile = new File(MyBatisGenerator.class.getClassLoader().getResource("generatorConfig.xml").toURI()); // 配置解析类 ConfigurationParser cp = new ConfigurationParser(warnings); // 配置解析类解析配置文件并生成 Configuration 配置对象 Configuration config = cp.parseConfiguration(configFile); // ShellCallback 负责如何处理重复文件 ShellCallback callback = new DefaultShellCallback(overwrite); // 逆向工程对象 MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); // 执行逆向文件生成操做 myBatisGenerator.generate(null); // 打印提示信息 System.out.println("MyBatis 逆向工程执行成功,刷新项目查看文件!"); } } 

执行该测试类,就能看见自动生成的文件:

 
 
  • Oh!这真的是太爽了!忽然开心(**)

看一下自动生成的文件

以 Category 为例,咱们来看一下自动生成的文件:

  • Category 实体类:
package cn.wmyskxz.pojo; public class Category { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name == null ? null : name.trim(); } } 
  • CategoryMapper 映射类:
package cn.wmyskxz.mapper; import cn.wmyskxz.pojo.Category; import cn.wmyskxz.pojo.CategoryExample; import java.util.List; public interface CategoryMapper { int deleteByPrimaryKey(Integer id); int insert(Category record); int insertSelective(Category record); List<Category> selectByExample(CategoryExample example); Category selectByPrimaryKey(Integer id); int updateByPrimaryKeySelective(Category record); int updateByPrimaryKey(Category record); } 
  • CategoryMapper.xml 映射文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.wmyskxz.mapper.CategoryMapper"> <resultMap id="BaseResultMap" type="cn.wmyskxz.pojo.Category"> <id column="id" jdbcType="INTEGER" property="id"/> <result column="name" jdbcType="VARCHAR" property="name"/> </resultMap> <sql id="Example_Where_Clause"> <where> <foreach collection="oredCriteria" item="criteria" separator="or"> <if test="criteria.valid"> <trim prefix="(" prefixOverrides="and" suffix=")"> <foreach collection="criteria.criteria" item="criterion"> <choose> <when test="criterion.noValue"> and ${criterion.condition} </when> <when test="criterion.singleValue"> and ${criterion.condition} #{criterion.value} </when> <when test="criterion.betweenValue"> and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} </when> <when test="criterion.listValue"> and ${criterion.condition} <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=","> #{listItem} </foreach> </when> </choose> </foreach> </trim> </if> </foreach> </where> </sql> <sql id="Base_Column_List"> id, name </sql> <select id="selectByExample" parameterType="cn.wmyskxz.pojo.CategoryExample" resultMap="BaseResultMap"> select <if test="distinct"> distinct </if> 'false' as QUERYID, <include refid="Base_Column_List"/> from category <if test="_parameter != null"> <include refid="Example_Where_Clause"/> </if> <if test="orderByClause != null"> order by ${orderByClause} </if> </select> <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from category where id = #{id,jdbcType=INTEGER} </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"> delete from category where id = #{id,jdbcType=INTEGER} </delete> <insert id="insert" keyColumn="id" keyProperty="id" parameterType="cn.wmyskxz.pojo.Category" useGeneratedKeys="true"> insert into category (name) values (#{name,jdbcType=VARCHAR}) </insert> <insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="cn.wmyskxz.pojo.Category" useGeneratedKeys="true"> insert into category <trim prefix="(" suffix=")" suffixOverrides=","> <if test="name != null"> name, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="name != null"> #{name,jdbcType=VARCHAR}, </if> </trim> </insert> <update id="updateByPrimaryKeySelective" parameterType="cn.wmyskxz.pojo.Category"> update category <set> <if test="name != null"> name = #{name,jdbcType=VARCHAR}, </if> </set> where id = #{id,jdbcType=INTEGER} </update> <update id="updateByPrimaryKey" parameterType="cn.wmyskxz.pojo.Category"> update category set name = #{name,jdbcType=VARCHAR} where id = #{id,jdbcType=INTEGER} </update> </mapper> 

其中就只有映射文件稍微有些复杂,但细看下来其实跟咱们本身写的差很少,甚至自动生成的完成得更好。

xxxExample

MybatisGenerator会生成一个类叫作XXXXExample的。,它的做用是进行排序,条件查询的时候使用。

这里有详细的说明,了解一下就行了:戳这里

第四步:测试

咱们这里仅仅就用 CategoryMapper 映射类来进行简单测试了:

@Autowired CategoryMapper categoryMapper; @Test public void test() { Category category = new Category(); category.setName("分类1"); categoryMapper.insert(category); } 

因为咱们使用了自增加键 id ,因此仅仅只须要提供 name 属性就能够了,执行,能够看到数据库中有正确的数据:

 
 

总结

根据以上的 “折腾” 算是完成了项目的起步工做了吧,我是一边写项目一边写博客的,因此可能有时候想着想着写着写着思绪会有点飘,写得凌乱,这也是没有办法的事,无论写得好仍是差我都但愿能记录下来,这些都是属于我本身的思路和学习路程。

欢迎转载,转载请注明出处!转载自@我没有三颗心脏

相关文章
相关标签/搜索