原创

SSM从零开始整合教学(二)

大家好,今天是对 SSM进行整合第二期!。 本文是坐着对bilibili的尚硅谷的SSM整合视频进行使用并记录流程进行发布。

逆向工程

执行完上期的内容后,我们现在来进行Mybatis的基本配置,以及逆向工程。 Mybatis的很多固定的语句可以在官方文档直接复制使用-->我是官方文档 首先需要先将下面的语句导入进我们的mybatis配置文件上方,有了这个语句,才能进行之后mybatis的配置操作

在这里插入图片描述

<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
 <configuration>
 </configuration>

然后我们可以在配置文件中配置一些命名属性,如驼峰命名起别名等。。这些可以便于数据库查出来直接与javabean对应,以及起别名方便使用。

在这里插入图片描述

<configuration>
 	<settings>
 		<!-- 驼峰命名 -->
 		<setting name="mapUnderscoreToCamelCase" value="true"/>
 	</settings>
 	<typeAliases>
 		<!-- 起别名 -->
 		<package name="com.atguigu.crud.bean"/>
 	</typeAliases>
 </configuration>

配置好以上最最基本的配置以后,我们需要去建立数据库的表,未来是要从数据库中提取数据进行CRUD的操作。 我们使用的数据库是Mysql,首先创建一个database,名字就叫ssm_crud吧。 然后开始建表的操作,创建一个emp表dept表

CREATE TABLE `tbl_dept` (
  `dept_id` int(11) NOT NULL AUTO_INCREMENT,
  `dept_name` varchar(255) NOT NULL,
  PRIMARY KEY (`dept_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

CREATE TABLE `tbl_emp` (
  `emp_id` int(11) NOT NULL AUTO_INCREMENT,
  `emp_name` varchar(255) NOT NULL,
  `gender` char(1) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `d_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`emp_id`),
  KEY `fk_emp_dept` (`d_id`),
  CONSTRAINT `fk_emp_dept` FOREIGN KEY (`d_id`) REFERENCES `tbl_dept` (`dept_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1006 DEFAULT CHARSET=utf8

创建好以后我们可以随便加一两条数据进入试试。

在这里插入图片描述 在这里插入图片描述 当表设置好以后,我们可以通过mybatis的逆向工程来创建对应的bean对应的dao信息以及mapper信息。 逆向工程的网址:-->我是网址 可以在网址的Quick Start Guide 中进行找到配置。 这里我们需要引入逆向工程的jar包

<!-- 逆向工程jar包  MBG -->
<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
<dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.3.5</version>
</dependency>

然后导入后需要建立MGB(逆向工程)的xml文件, 我们在ssm-crud的目录下建立xml文件 (这里我的名字错了 大家别介意)。

在这里插入图片描述

为这个xml文件取名为mgb.xml

在这里插入图片描述

然后将以下配置的内容都放到mgb.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>
  <classPathEntry location="/Program Files/IBM/SQLLIB/java/db2java.zip" />
  <context id="DB2Tables" targetRuntime="MyBatis3">
    <jdbcConnection driverClass="COM.ibm.db2.jdbc.app.DB2Driver"
        connectionURL="jdbc:db2:TEST"
        userId="db2admin"
        password="db2admin">
    </jdbcConnection>

    <javaTypeResolver >
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>

    <javaModelGenerator targetPackage="test.model" targetProject="\MBGTestProject\src">
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
    </javaModelGenerator>

    <sqlMapGenerator targetPackage="test.xml"  targetProject="\MBGTestProject\src">
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>

    <javaClientGenerator type="XMLMAPPER" targetPackage="test.dao"  targetProject="\MBGTestProject\src">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>

    <table schema="DB2ADMIN" tableName="ALLTYPES" domainObjectName="Customer" >
      <property name="useActualColumnNames" value="true"/>
      <generatedKey column="ID" sqlStatement="DB2" identity="true" />
      <columnOverride column="DATE_FIELD" property="startDate" />
      <ignoreColumn column="FRED" />
      <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />
    </table>

  </context>
</generatorConfiguration>

在这里插入图片描述

首先我们将刚复制进去的内容的开头 ,这一句话删除

<classPathEntry location="/Program Files/IBM/SQLLIB/java/db2java.zip" />

然后先将上头的jdbcConnection中的数据源替换成我们自己的配置。代码就不放了哈。

在这里插入图片描述

然后修改我们的bean包生成的位置,将javaModelGenerator这个文件中的文件地址修改一下即可。 在这里插入图片描述

<!-- 指定javaBean生成的位置 -->
<!-- targetPackage:生成包的位置 -->
<!--  targetProject:生成的工程的位置 -->
<javaModelGenerator targetPackage="com.atguigu.crud.bean" 
    targetProject=".\src\main\java">
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
</javaModelGenerator>

然后需要指定我们的sql生成位置的映射。在sqlMapGenerator中。

在这里插入图片描述

<!-- 指定sql映射文件生成的位置 -->
<sqlMapGenerator targetPackage="mapper"  
    targetProject=".\src\main\resources">
      <property name="enableSubPackages" value="true" />
</sqlMapGenerator>

之后再指定dao接口生成的位置。在javaClientGenerator配置中。

在这里插入图片描述

<!-- 指定dao接口生成的位置,mapper接口 -->
<javaClientGenerator type="XMLMAPPER" 
    targetPackage="com.atguigu.crud.dao"  targetProject=".\src\main\java">
      <property name="enableSubPackages" value="true" />
</javaClientGenerator>

最后的table指定每个表的生成策略。我们替换原内容,表示数据库表和bean的对应

在这里插入图片描述

<!-- table指定每个表的生成策略 -->
<table tableName="tbl_emp" domainObjectName="Employee"></table>
<table tableName="tbl_dept" domainObjectName="Department"></table>

最后再将这个页的完整代码贴一遍,可以再对照着看一下。

<?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">
  	<!-- 配置数据库连接 -->
    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
        connectionURL="jdbc:mysql://localhost:3306/ssm_crud"
        userId="root"
        password="root">
    </jdbcConnection>

    <javaTypeResolver >
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>
	
	<!-- 指定javaBean生成的位置 -->
	<!-- targetPackage:生成包的位置 -->
	<!--  targetProject:生成的工程的位置 -->
    <javaModelGenerator targetPackage="com.atguigu.crud.bean" 
    targetProject=".\src\main\java">
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
    </javaModelGenerator>

	<!-- 指定sql映射文件生成的位置 -->
    <sqlMapGenerator targetPackage="mapper"  
    targetProject=".\src\main\resources">
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>

	<!-- 指定dao接口生成的位置,mapper接口 -->
    <javaClientGenerator type="XMLMAPPER" 
    targetPackage="com.atguigu.crud.dao"  targetProject=".\src\main\java">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>

	<!-- table指定每个表的生成策略 -->
    <table tableName="tbl_emp" domainObjectName="Employee"></table>
	<table tableName="tbl_dept" domainObjectName="Department"></table>
  </context>
</generatorConfiguration>

在将配置文件这样配置好以后,我们就可以让逆向工程帮我们生成mapper.xml,dao等文件了。 首先我们在test文件下生成一个MGBjava文件

在这里插入图片描述

内容如下图所示,主要是将File(“mgb.xml”) 改成刚才设置的文件就ok了 ,然后我们直接main方法运行。 然后刷新一下,就发现需要生成的东西都帮我们生成了。

package com.atguigu.crud.test;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;

public class MGB {
	public static void main(String[] args) throws Exception {
		   List<String> warnings = new ArrayList<String>();
		   boolean overwrite = true;
		   File configFile = new File("mgb.xml");
		   ConfigurationParser cp = new ConfigurationParser(warnings);
		   Configuration config = cp.parseConfiguration(configFile);
		   DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		   MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
		   myBatisGenerator.generate(null);
	}
}

在这里插入图片描述

然后我们进入dao层,来到生成的文件,可以发现里面有开发者给我们写的一大堆的配置的注释,我们看的非常乱。所以我们可以选择将这些注释都删除掉。 那当然不能是自己手动的一个个删除,我们选择先将已经生成的文件删除掉,然后重新生成一遍没有注释的。 删掉以后,我们需要修改的仅仅是在mgb.xml中加入一段代码即可,具体在该网址中有-->我的网址

在这里插入图片描述

加入这段代码即可。

<commentGenerator>
	  <property name="suppressAllComments" value="true" />
</commentGenerator>

然后我们来重新生成一遍 ,生成的就是没有注释的了,记得生成了要刷新

在这里插入图片描述

这就大概生成了所有的方法啦,到时候我们可以修改一些我们需要用的。

Mybatis设置

首先我们来到为我们生成的EmployeeMapper.xml,会发现里面的文件非常多,我们可以进行缩小便于整理

在这里插入图片描述

我们查看其中为我们生成的方法,发现少了两个我们需要的方法,根据ID找到Employee连带Department。 那我们来到EmployeeMapper,来自己写一个方法

在这里插入图片描述

 //新增兩個
    List<Employee> selectByExampleWithDept(EmployeeExample example);

    Employee selectByPrimaryKeyWithDept(Integer empId);

然后我们来到Employee,会发现我们的Employee根本没有获取到部门的信息,所以我们也得加上。 所以需要为Employee增加department字段 并且生成get,set方法。

在这里插入图片描述

    private Department department;
    public Department getDepartment() {
		return department;
	}
	public void setDepartment(Department department) {
		this.department = department;
	}

定义好了EmployeeMapperbean 那么就需要去定义xml的映射sql语句。 来到EmployeeMapper.xml ,插入下方内容。

 <!--     List<Employee> selectByExampleWithDept(EmployeeExample example);

    Employee selectByPrimaryKeyWithDept(Integer empId);
   -->
   <select id="selectByExampleWithDept" >
	   	select
	    <if test="distinct">
	      distinct
	    </if>
	    <include refid="Base_Column_List" />
	    from tbl_emp
	    <if test="_parameter != null">
	      <include refid="Example_Where_Clause" />
	    </if>
	    <if test="orderByClause != null">
	      order by ${orderByClause}
	    </if>
   </select>

这个之后再进行修改,先进行修改那个Base_Column_List的引用语句,这个语我们查询的属性不一致,并不包含新增加的department。所以我们重新写一个一致的。

在这里插入图片描述

  <sql id="WithDept_Column_List">
  	 emp_id, emp_name, gender, email, d_id,dept_id,dept_name
  </sql>

然后将原来的Base_Column_List 改成我们新定义的id(WithDept_Column_List),然后因为原来的语句是从emp表查询,而我们需要查出department的属性,那就肯定需要联合查询了。 那我这里就直接放代码了.

在这里插入图片描述

  <!--     List<Employee> selectByExampleWithDept(EmployeeExample example);

    Employee selectByPrimaryKeyWithDept(Integer empId);
   -->
   <select id="selectByExampleWithDept" >
	   	select
	    <if test="distinct">
	      distinct
	    </if>
	    <include refid="WithDept_Column_List" />
	    FROM tbl_emp e LEFT JOIN tbl_dept d ON e.`d_id` = d.`dept_id`
	    <if test="_parameter != null">
	      <include refid="Example_Where_Clause" />
	    </if>
	    <if test="orderByClause != null">
	      order by ${orderByClause}
	    </if>
   </select>

将上述动态sql信息定义好后,还需要定义一个返回的类型,因为我们使用了别名,就使用resultMap来定义返回的Employee对象

在这里插入图片描述

  <resultMap type="com.atguigu.crud.bean.Employee" id="WithDeptResultMap">
  	<id column="emp_id" jdbcType="INTEGER" property="empId" />
    <result column="emp_name" jdbcType="VARCHAR" property="empName" />
    <result column="gender" jdbcType="CHAR" property="gender" />
    <result column="email" jdbcType="VARCHAR" property="email" />
    <result column="d_id" jdbcType="INTEGER" property="dId" />
    <association property="department" javaType="com.atguigu.crud.bean.Department">
    	<id column="dept_id" property="deptId"/>
    	<result column="dept_name" property="deptName"/>
    </association>
  </resultMap>

然后将定义好的resultMapid传回之前的select语句。

在这里插入图片描述

到这里第一个方法就完成了,然后我们来写第二个方法,根据主键查询,并且将resultMap设为刚才的resultMap的id 其他的都与上一个一样.。

在这里插入图片描述

  <select id="selectByPrimaryKeyWithDept" resultMap="WithDeptResultMap">
  	select 
    <include refid="WithDept_Column_List" />
     FROM tbl_emp e LEFT JOIN tbl_dept d ON e.`d_id` = d.`dept_id`
    where emp_id = #{empId,jdbcType=INTEGER}
  </select>

然后我们需要的sql方法也就设置好了,可以去写一个测试的方法测试一下效果。 现在test包下建立测试类。

在这里插入图片描述

这里我们直接使用Spring的单元测试,则需要导入Spring单元测试的jar包

<!-- Spring单元测试 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.3.7.RELEASE</version>
    <!-- <scope>test</scope> -->
</dependency>

然后使用**@ContextConfiguration这个注解,这个注解代表可以使用Spring测试类**,并制定Spring配置文件的位置

在这里插入图片描述

然后再加上RunWith,表示使用Spring的单元测试模块。

在这里插入图片描述

再用@Autowired注解,这里没有标注任何信息则是通过Department这个类去寻找引入,引入我们的Department类。

在这里插入图片描述

然后我们如下测试一下,看看我们是否能成功取到Autowired所标注的对象。 如果出现如下就代表成功了。

在这里插入图片描述

然后我们要去给department表中插入数据,首先要给department赋值,我们建立一个构造方法来方便赋值,来到department实体类,加上如下构造方法。记得加上有参构造的同时也一定要加上无参构造

在这里插入图片描述

private void department() {
	// TODO Auto-generated method stub
}
    
public Department(Integer deptId, String deptName) {
	super();
	this.deptId = deptId;
	this.deptName = deptName;
}

然后我们开始插入部门信息 ,顺便测试一下数据库是否能成功的插入数据。

在这里插入图片描述

	@Test
	public void testCRUD() {
		//1.插入部门
		departmentMapper.insertSelective(new Department(null, "开发部"));
		departmentMapper.insertSelective(new Department(null, "测试部"));
	}

然后部门插入完毕以后,我们可以插入Employee的具体信息,为了方便,还是一样去Employee实体类增加有参构造无参构造器。 有参构造器先不要加department

    private void employee() {
		// TODO Auto-generated method stub
	}
    public Employee(Integer empId, String empName, String gender, String email, Integer dId) {
		super();
		this.empId = empId;
		this.empName = empName;
		this.gender = gender;
		this.email = email;
		this.dId = dId;
	}

然后我们再插入一条用户信息试试。

在这里插入图片描述

	@Test
	public void testCRUD() {
		//1.插入部门
//		departmentMapper.insertSelective(new Department(null, "开发部"));
//		departmentMapper.insertSelective(new Department(null, "测试部"));
		
		//测试员工插入
		employeeMapper.insertSelective(new Employee(null, "sasa", "M", "qwe@qq.com", 1));
	}

运行成功后可以去数据库里看看。看看数据是否已经成功插入了。 如果成功了,我们可以进行批量的插入数据。 那么既然要批量的插入数据,那么我们就需要返回applicationContext.xml中去定义可以批量插入的sqlSession了。 其中SqlSessionTemplate 就是跟Spring整合时使用的。

在这里插入图片描述

	<!-- 配置一个可以执行批量的SqlSession   executorType 执行器类型改为批量-->
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
		<constructor-arg name="executorType" value="BATCH"></constructor-arg>
	</bean>

配置好以后就可以在测试页面注入sqlsession了 。

在这里插入图片描述

然后我们来编写代码,使用UUID来插入名字各不相同的用户。

在这里插入图片描述

	@Test
	public void testCRUD() {
		//1.插入部门
//		departmentMapper.insertSelective(new Department(null, "开发部"));
//		departmentMapper.insertSelective(new Department(null, "测试部"));
		
		//测试员工插入
		//employeeMapper.insertSelective(new Employee(null, "sasa", "M", "qwe@qq.com", 1));
		
//		for() {
//			employeeMapper.insertSelective(new Employee(null, empName, gender, email, dId))
//		}
		//只有通过sqlSession来插入才是批量 直接for循环那就不是批量插入了
		EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
		for(int i=0;i<1000;i++) {
			String uid = UUID.randomUUID().toString().substring(0,5)+i;
			mapper.insertSelective(new Employee(null, uid, "M", uid+"@qq.com", 1));
		}
	}

如下是成功插入的效果图

在这里插入图片描述

到这基本所有的配置,以及数据库的设置都已经完成了,剩下的就是正式开工做项目了!

分页查询

在成功的测试了Departmentmapper的功能与在EmployeeMapper中插入1000条数据后,我们可以正式的开始写项目类。首先要完成的是一个分页的操作,首先我们要进入员工信息表格的话 需要先将员工的信息全部查找出来放在页面上,需要一个通道进入controller查找,于是我们将index.jsp改造一下,变成一个跳板,去到我们的Controller

在这里插入图片描述

在将index.jsp设置好跳板后,我们就需要写一个后续接收的地方(controller)层。 新建一个EmployeeController

在这里插入图片描述

在设置好以后进入,因为这是要接收页面通过Springmvc的请求,之前在SpringMVC中标注了只扫描@Controller的包,那么就给这个class标注@Controller。

在这里插入图片描述

标注好后,我们需要写一个方法来接收之前传输来的/emp请求,创建一个getEmps方法 并标注@RequestMapping(“/emps”)接收页面传来的指令。

在这里插入图片描述

然后我们要去数据库中获取员工的信息,所以我们要去Service层进行数据库操作,在service中创建一个EmployeeService

在这里插入图片描述

创好以后先给EmployeeService标注上@Service注解,表示被Spring扫描,之后需要引用EmployeeMapper来进行引用dao层方法进行数据库操作。 通过@Autowired引入EmployeeMapper的bean对象。

在这里插入图片描述

然后建立一个查询所有员工的方法。暂时先标注为null,代表返回表中所有的信息

在这里插入图片描述

所以现在EmployeeService的样子是这样的。

在这里插入图片描述

然后就回到EmployeeController,在上方引入EmployeeService,也是加@Autowired。

在这里插入图片描述

并使用getAll()方法,用一个List接收传输过来的表信息

在这里插入图片描述

但是由于我们做的是分页查询,需要对每一页进行判别,参数会传来需要获取哪一页的信息,于是我们需要在**getEmps()**中写入可能会传来的参数,并赋给一个值。

在这里插入图片描述

再然后我们可以通过分页的插件对分页进行处理,这时需要引入PageHelper插件,通过插件来帮我们进行数据的分页,会比我们自己手动精确并且稳定一些。 所以来到pom.xml在这里插入图片描述

	<!-- 分页插件 -->
	<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.0.0</version>
	</dependency>

传入后保存加载,回到EmployeeController。 这时就可以引用传入的插件了,首先在查询之前先调用startPage() 传入页码以及每页需要多少的数据,我们规定为5.

在这里插入图片描述

然后要注意了,这个分页查询的PageHelper下一行一定是分页数据(就是从service传回来的所有表信息),之后我们通过new一个PageInfo对查询后的结果进行包装,只需要将pageInfo交给页面就行了 PageInfo(emps,num) 将查询后的结果传入,num代表一个页码连续显示几页 比如传入的是第3页,那么就从3开始连续显示num页。 最后用model接收这个pageinfo, 这时要在参数处传入Model model 。

在这里插入图片描述

最后将model传到request请求中。 最后的页面是这样的:

在这里插入图片描述

好的,当我们已经将分页的步骤基本设计好以后,那么就先去测试中测试一下。在test包下建立一个MvcTest.

在这里插入图片描述

当我们建好以后,还是跟上次一样通过Spring进行测试 那么先引入注解.

@RunWith(SpringJUnit4ClassRunner.class)		
@ContextConfiguration(locations = {"classpath:applicationContext.xml","file:src/main/webapp/WEB-INF/dispatcherServlet-servlet.xml"})

因为这次我们测试用到了Springmvc ,所以需要它的配置文件,我们也顺带一起引入.

在这里插入图片描述

引入后,因为我们这次要配合SpringMVC一起测试,那么先传入SpringMvc的ioc WebApplicationContext,然后虚拟MVC请求并获取处理结果,在这里我们使用MockMvc(详细见图)

在这里插入图片描述

然后我们写一个初始化MockMvc的方法。

在这里插入图片描述

建立好后呢,我们就可以开始写Test方法 ,首先 先建立一个testPage方法并标注@Test。

在这里插入图片描述

然后在方法中设置MvcResult,result用来接收处理的结果,并使用刚初始化的mockMvc执行模拟进入**/emps**,并传入参数pn为1的参数返回。

在这里插入图片描述

在获取之后 创建一个MockHttpServletRequest request 获取结果中的请求信息。 然后再从请求信息中获取pageInfo

在这里插入图片描述

(之前忘了一个在initMockMvc前加上一个@Before注解表示最先执行,记住引入的是测试的包) 并且在类上方加入@WebAppConfiguration注解表示传入web ioc容器。

在这里插入图片描述

做到这一步后,之后就是从pageInfo中获取信息啦,就不一一阐述了,直接上

在这里插入图片描述

输出的结果是这样的 ,我们的测试也就完成了!

在这里插入图片描述

剩下的内容就下一期上吧!应该还有两期...

java
eclipse
SpringMVC
Spring
Mybatis

  • 作者:LinJy(联系作者)
  • 发表时间:2020-04-24 14:02
  • 版权声明:自由转载-非商用-非衍生-保持署名(null)
  • undefined
  • 评论

    留言