SSM-CRUD入门项目——环境搭建
一、项目概述
项目功能点:
1.分页
2.数据校验:
jQuery前端校验+JSR303后端校验
3.ajax
4.RESTful风格的URI
技术点:
1.基础框架——SSM
2.数据库——MySQL
3.前端框架bootstrap快速搭建前端界面
4.项目构建工具——maven
5.mybatis分页插件——pagehelper进行分页
6.mybatsi-generator逆向工程进行mapper生成
二、环境搭建
1.构建一个maven工程(如何构建web的maven工程参见Maven的博客)
//注意点:打包方式请记得选择war包,请配置为标准的web程序目录结构,自己写结束标签
(去掉原来web-app标签下的/,改为闭合标签</web-app>)
此时的web.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
</web-app>
2.引入依赖
spring
springMVC
mybatis
连接池+数据库驱动
其它jar(jstl,servlet-api,junit等等)
(上maven仓库中搜索相关的依赖坐标信息)
//注意: maven servlet-api 和 javax.servlet-api区别 :
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.jiangbei</groupId>
<artifactId>ssm-crud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging> <dependencies>
<!-- 引入分页插件pageHelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.0.0</version>
</dependency>
<!-- 引入spring springMVC依赖 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- spring-JDBC -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- spring切面 spring-aspects模块 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- spring-test -->
<!-- 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> <!-- 引入Mybatis -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency> <!-- 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> <!-- spring整合mybatis的包 -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency> <!-- 数据库连接池与驱动包,注意c3p0是c3p0 c3p0下的包(版本有问题请更换版本) -->
<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
</dependency> <!-- jstl(和c3p0一样,是jstl>jstl下的),
servlet-api(请注意正确引入),
junit -->
<!-- https://mvnrepository.com/artifact/jstl/jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<!-- <dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency> -->
<!-- 因为sprngTest要求更高版本的servlet,我们将其替换为3.0以上的版本 -->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- <dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1</version>
<scope>provided</scope>
</dependency>
-->
<!-- jsp依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 引入jackson的包 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>
</dependency>
<!-- 后端校验JSR303的实现——hibernate-validator依赖
如果是tomcat7以下的服务器,需要额外给服务器的Lib包中替换新的EL
-->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8080</port>
<path>/ssm-crud</path>
<uriEncoding>UTF-8</uriEncoding>
<finalName>ssm-crud</finalName>
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.引入bootstrap环境
下载解压后,解压至项目web-app下static文件夹
具体引入css与js可以参见官网的基本模板
引入完成的情况如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<link href="static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<!-- 先引入jQuery,再引入js-->
<script type="text/javascript" src="static/bootstrap/js/jquery.min.js"> </script>
<script src="static/bootstrap/js/bootstrap.min.js"></script>
</head>
<body> </body>
</html>
4.编写整合的配置文件
web.xml:
1.配置启动spring容器>(通过springIDE快速编写相关的监听器)——在对应位置定义spring配置文件
2.配置前端控制器——用来拦截请求(url设置为/),这里使用默认的命名与位置(默认命名为${servlet-name}-Servlet.xml,位置与web.xml同级,即位WEB-INF下,当然可以自己指定。)
3.配置springMVC的字符编码过滤器(参见springMVC day01博客第五章)
4.配置HiddenHttpMethodFilter,处理DELETE 和 PUT请求。
//注意多个过滤器时,按照先后顺序,而处理编码的是必须在前面的。
至此,web.xml配置完成:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- 1.启动spring容器 -->
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param> <!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 2.配置springMVC前端控制器 -->
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet> <!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 3.springMVC的字符编码过滤器 ,在所有过滤器之前-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 4.配置HiddenHttpMethodFilter过滤器,处理RESTful风格的请求 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
//补充:
<!-- 若不适用默认的,可以通过init-param进行初始化位置的定义 -->
<!-- <init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param> -->
【更新】:springMVC的前端控制器的url-pattern必须为 / ,详见springMVC博客。
<!-- 可以配置/ ,此工程 所有请求全部由springmvc解析,此种方式可以实现 RESTful方式,需要特殊处理对静态文件的解析不能由springmvc解析
可以配置*.do或*.action,所有请求的url扩展名为.do或.action由springmvc解析,此种方法常用 不可以/*,如果配置/*,返回jsp也由springmvc解析,这是不对的。 -->
使用自定义位置的sprinMVC扫描如下:
<!-- MVC Servlet -->
<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring-mvc*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
dispatcherServlet-servlet.xml:
1.包扫描(只扫描controller的注解)
2.三大件
3.静态资源访问
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <!-- springMVC的配置文件,跳转逻辑有关的 -->
<!-- 配置包扫描 -->
<context:component-scan base-package="cn.crud" use-default-filters="false">
<!-- 配置只扫描@Controller注解 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 配置三大件 -->
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 两个标配 -->
<!-- 1.配置注解驱动(处理器适配器和映射器),还有更多高级特性 -->
<mvc:annotation-driven/>
<!-- 2.配置静态资源访问 -->
<mvc:default-servlet-handler/>
</beans>
applicationContext.xml:注意与springMVC的父子容器关系
0.配置包扫描(除了springMVC已经存在的contrller都进行扫描)
1.数据源
2.与Mybatis的整合(全局配置文件引入,mapper配置文件引入,mapper接口实现扫描加入IOC容器等)
3.事务控制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!-- spring的配置文件,处理一些业务逻辑 -->
<!-- 配置包扫描 -->
<context:component-scan base-package="cn.crud">
<!-- 不扫描controller组件,其他都扫描 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- ==========数据源配置 ================-->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- ===========配置和mybatis的整合=========== -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 配置mybatis全局配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 配置数据源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 配置mapper文件位置 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
<!-- 配置包扫描,将mapper接口实现加入IOC容器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 扫描所有dao接口的实现 -->
<property name="basePackage" value="cn.crud.dao"></property>
</bean>
<!-- ==============事务控制的配置=============== -->
<!-- 配置事务管理器:管理数据源的bean -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 数据源的开启关闭回滚 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启基于注解的事务,必要的都使用配置实现 -->
<aop:config>
<!-- 配置切入点,在service层控制事务,..表示即使有子包也可以扫描 -->
<aop:pointcut expression="execution(* cn.crud.service..*(..))" id="txPoint"/>
<!-- 配置 事务增强-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
</aop:config>
<!-- transaction-manager默认值即为 transactionManager,所以可以不配-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 所有方法都是事务 -->
<tx:method name="*"/>
<!-- 所有get开头的方法都是可读的事务 -->
<tx:method name="get*" read-only="true"/>
</tx:attributes>
</tx:advice>
</beans>
//其中,只读事务的配置为优化配置,详情见网友博客分析:
“只读事务”并不是一个强制选项,它只是一个“暗示”,提示数据库驱动程序和数据库系统,这个事务并不包含更改数据的操作,那么JDBC驱动程序和数据库就有可能根据这种情况对该事务进行一些特定的优化,比方说不安排相应的数据库锁,以减轻事务对数据库的压力,毕竟事务也是要消耗数据库的资源的。 但是你非要在“只读事务”里面修改数据,也并非不可以,只不过对于数据一致性的保护不像“读写事务”那样保险而已。 因此,“只读事务”仅仅是一个性能优化的推荐配置而已,并非强制你要这样做不可
mybatis-config.xml
可以到github的网址上找到Mybatis,然后进入其官方文档,get started找到需要的东西
1.开启驼峰式命名
2.开启别名设置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 开启驼峰命名规则,详细请参见官方文档 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<!-- 为类起别名 -->
<package name="cn.crud.bean"/>
</typeAliases>
</configuration>
//事务、数据源等配置都交给spring来配置了,mybatis核心配置文件需要配置的内容较少
mapper
首先通过maven引入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>
配置文件可以参考官方的配置文件
<?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" />
配置好后可以从官网文档的配置处,配置不生成注释(太多的我们不需要的注释)
从官方文档参考相关注释后,我们得出相关的逆向工程配置文件:
<?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">
<!-- 配置不生产注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 配置数据库连接信息 -->
<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生成的 位置 -->
<javaModelGenerator targetPackage="cn.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="cn.crud.dao"
targetProject=".\src\main\java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 指定每 表的生成策略 -->
<table tableName="t_emp" domainObjectName="Employee" ></table>
<table tableName="t_dept" domainObjectName="Department" ></table>
</context>
</generatorConfiguration>
通过文档的
- From another Java program with an XML configuration
我们得到逆向工程的生成代码:
package cn.crud.tests; 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 MBGTest { public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("mbg.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);
} }
当然,逆向工程的生成代码不能100%符合我们的要求,我们对它进行适当改造:
由于我们需要查询员工的时候将员工的部门查询出来,而不是将ID查询出来,我们在mapper接口中新增两个方法:
List<Employee> selectByExample(EmployeeExample example); Employee selectByPrimaryKey(Integer empId); List<Employee> selectByExampleWithDept(EmployeeExample example); Employee selectByPrimaryKeyWithDept(Integer empId);
//对比前面两个方法,后两个为我们新增的方法
这样,我们对实体类Employee进行改造,新增部门字段,完成部门名的查询条件:
private Department department;
//注意生成set/get方法
改造完成后的配置文件与接口文件如下:
<?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.crud.dao.EmployeeMapper">
<resultMap id="BaseResultMap" type="cn.crud.bean.Employee">
<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" />
</resultMap>
<resultMap id="WithDeptResultMap" type="cn.crud.bean.Employee">
<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 -->
<association property="department" javaType="cn.crud.bean.Employee">
<id column="dept_id" jdbcType="INTEGER" property="deptId" />
<result column="dept_name" jdbcType="VARCHAR" property="deptName" />
</association>
</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="Update_By_Example_Where_Clause">
<where>
<foreach collection="example.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">
emp_id, emp_name, gender, email, d_id
</sql>
<sql id="WithDept_Column_List">
e.emp_id, e.emp_name, e.gender, e.email, e.d_id,d.dept_id, d.dept_name
</sql>
<select id="selectByExample" parameterType="cn.crud.bean.EmployeeExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from t_emp
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<!-- 增新带部门查询的sql -->
<select id="selectByExampleWithDept" parameterType="cn.crud.bean.EmployeeExample" resultMap="WithDeptResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="WithDept_Column_List" />
from t_emp e LEFT JOIN t_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>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="WithDept_Column_List" />
from t_emp e LEFT JOIN t_dept d ON e.d_id=d.dept_id
where e.emp_id = #{empId,jdbcType=INTEGER}
</select>
<!-- 新增带部门的按ID查询 -->
<select id="selectByPrimaryKeyWithDept" parameterType="java.lang.Integer" resultMap="WithDeptResultMap">
select
<include refid="WithDept_Column_List" />
from t_emp e LEFT JOIN t_dept d ON e.d_id=d.dept_id
where emp_id = #{empId,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from t_emp
where emp_id = #{empId,jdbcType=INTEGER}
</delete>
<delete id="deleteByExample" parameterType="cn.crud.bean.EmployeeExample">
delete from t_emp
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="cn.crud.bean.Employee">
insert into t_emp (emp_id, emp_name, gender,
email, d_id)
values (#{empId,jdbcType=INTEGER}, #{empName,jdbcType=VARCHAR}, #{gender,jdbcType=CHAR},
#{email,jdbcType=VARCHAR}, #{dId,jdbcType=INTEGER})
</insert>
<insert id="insertSelective" parameterType="cn.crud.bean.Employee">
insert into t_emp
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="empId != null">
emp_id,
</if>
<if test="empName != null">
emp_name,
</if>
<if test="gender != null">
gender,
</if>
<if test="email != null">
email,
</if>
<if test="dId != null">
d_id,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="empId != null">
#{empId,jdbcType=INTEGER},
</if>
<if test="empName != null">
#{empName,jdbcType=VARCHAR},
</if>
<if test="gender != null">
#{gender,jdbcType=CHAR},
</if>
<if test="email != null">
#{email,jdbcType=VARCHAR},
</if>
<if test="dId != null">
#{dId,jdbcType=INTEGER},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="cn.crud.bean.EmployeeExample" resultType="java.lang.Long">
select count(*) from t_emp
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map">
update t_emp
<set>
<if test="record.empId != null">
emp_id = #{record.empId,jdbcType=INTEGER},
</if>
<if test="record.empName != null">
emp_name = #{record.empName,jdbcType=VARCHAR},
</if>
<if test="record.gender != null">
gender = #{record.gender,jdbcType=CHAR},
</if>
<if test="record.email != null">
email = #{record.email,jdbcType=VARCHAR},
</if>
<if test="record.dId != null">
d_id = #{record.dId,jdbcType=INTEGER},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
update t_emp
set emp_id = #{record.empId,jdbcType=INTEGER},
emp_name = #{record.empName,jdbcType=VARCHAR},
gender = #{record.gender,jdbcType=CHAR},
email = #{record.email,jdbcType=VARCHAR},
d_id = #{record.dId,jdbcType=INTEGER}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="cn.crud.bean.Employee">
update t_emp
<set>
<if test="empName != null">
emp_name = #{empName,jdbcType=VARCHAR},
</if>
<if test="gender != null">
gender = #{gender,jdbcType=CHAR},
</if>
<if test="email != null">
email = #{email,jdbcType=VARCHAR},
</if>
<if test="dId != null">
d_id = #{dId,jdbcType=INTEGER},
</if>
</set>
where emp_id = #{empId,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="cn.crud.bean.Employee">
update t_emp
set emp_name = #{empName,jdbcType=VARCHAR},
gender = #{gender,jdbcType=CHAR},
email = #{email,jdbcType=VARCHAR},
d_id = #{dId,jdbcType=INTEGER}
where emp_id = #{empId,jdbcType=INTEGER}
</update>
</mapper>
package cn.crud.dao; import cn.crud.bean.Employee;
import cn.crud.bean.EmployeeExample;
import java.util.List;
import org.apache.ibatis.annotations.Param; public interface EmployeeMapper {
long countByExample(EmployeeExample example); int deleteByExample(EmployeeExample example); int deleteByPrimaryKey(Integer empId); int insert(Employee record); int insertSelective(Employee record); List<Employee> selectByExample(EmployeeExample example); Employee selectByPrimaryKey(Integer empId); List<Employee> selectByExampleWithDept(EmployeeExample example); Employee selectByPrimaryKeyWithDept(Integer empId); int updateByExampleSelective(@Param("record") Employee record, @Param("example") EmployeeExample example); int updateByExample(@Param("record") Employee record, @Param("example") EmployeeExample example); int updateByPrimaryKeySelective(Employee record); int updateByPrimaryKey(Employee record);
}
三、单元测试
这里我们使用spring的单元测试进行测试,避免了传统的获取IOC容器等操作
引入相关的依赖:
<!-- 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>
这里我们执行spring的单元测试,详细步骤见注释:
package cn.crud.tests; import java.util.UUID; import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import cn.crud.bean.Department;
import cn.crud.bean.Employee;
import cn.crud.dao.DepartmentMapper;
import cn.crud.dao.EmployeeMapper; /**
* 测试dao层的环境
* @author Administrator
*1.使用@ContextConfiguration指定配置文件路径
*2.使用@Runwith指定单元测试使用spring的单元测试
*3.可以像原生开发一样直接注入
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class MapperTest { @Autowired
private DepartmentMapper departmentMapper;
@Autowired
private EmployeeMapper employeeMapper;
@Autowired
private SqlSession sqlSession;
/**
* 测试dept表的Mapper
*/
@Test
public void TestDao(){
// 部门插入
// departmentMapper.insertSelective(new Department(null,"宣传部"));
// departmentMapper.insertSelective(new Department(null,"测试部"));
// 员工插入
// employeeMapper.insertSelective(new Employee(null,"Alan","M","1001@qq.com",1));
// employeeMapper.insertSelective(new Employee(null,"Bob","F","1002@qq.com",2));
//通过此方法得到的mapper可以批量操作
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
for(int i = 0; i<500; i++){
String gender = i%2==0?"M":"F";
String uid = UUID.randomUUID().toString().substring(0, 5);
mapper.insertSelective(new Employee(null, uid, gender, uid+"@qq.com", 1));
}
System.out.println("批量完成");
}
}
执行批处理参阅:http://blog.csdn.net/baidu_25310663/article/details/45243683
至此,环境搭建完成!
SSM-CRUD入门项目——环境搭建的更多相关文章
- Android入门之环境搭建
欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/1376935560.html 原创:An ...
- 新手嘛,先学习下 Vue2.0 新手入门 — 从环境搭建到发布
Vue2.0 新手入门 — 从环境搭建到发布 转自:http://www.runoob.com/w3cnote/vue2-start-coding.html 具体文章详细就不搬了,步骤可过去看,我这就 ...
- 总结Vue 第四天:vue-cli(Vue2.0 新手入门 — 从环境搭建到发布)
总结Vue 第四天:vue-cli(Vue2.0 新手入门 - 从环境搭建到发布) 一.Vue CLI----(Vue2.0 新手入门 - 从环境搭建到发布): ■ CLI是Command-Lin ...
- 【个人笔记】003-PHP基础-01-PHP快速入门-03-PHP环境搭建
003-PHP基础-01-PHP快速入门 03-PHP环境搭建 1.客户端(浏览器) IE FireFox CHROME Opera Safari 2.服务器 是运行网站的基本 是放置程序代码的地方 ...
- 第一周博客之二---OA项目环境搭建及开发包部署
OA项目环境搭建 一个项目想要能够在开发人员打包好项目包之后进行测试,就必须进行项目测试环境的搭建,要根据开发工程师的开发环境采用不同的测试环境,以下只是浅谈下Java项目OA(办公自动化平台)的环境 ...
- scala 入门Eclipse环境搭建
scala 入门Eclipse环境搭建及第一个入门经典程序HelloWorld IDE选择并下载: scala for eclipse 下载: http://scala-ide.org/downloa ...
- mac OS X下Java项目环境搭建+IntelliJ IDEA Jrebel插件安装与破解+Office 2016破解版安装
一.mac OS X下Java项目环境搭建 因为某些原因新入手了台最新版的MacBook Pro,意味着今天要花一天时间安装各种软件以及项目环境搭建╮(╯▽╰)╭ 项目环境搭建步骤: 1.安装jdk ...
- vue项目ide(vue项目环境搭建)
一.先介绍一下我接下来要做的项目 项目:ide可视化工具 技术应用: Vue2.0(js框架):https://cn.vuejs.org/ ElementUi(饿了吗ui框架基于vue的):http: ...
- react 开发 PC 端项目(一)项目环境搭建 及 处理 IE8 兼容问题
步骤一:项目环境搭建 首先,你不应该使用 React v15 或更高版本.使用仍然支持 IE8 的 React v0.14 即可. 技术选型: 1.react@0.14 2.bootstrap3 3. ...
随机推荐
- Java对于表达式中的自动类型提升
1 表达式中的自动类型提升: 表达式求值时,Java自动的隐含的将每个byte.short或char操作数提升为int类型,这些类型的包装类型也是可以的. 例如: short s1 = 1; s1 = ...
- HBase RegionServer宕机处理恢复
本文分析RegionServer宕机后这个region server上的region是如何在其他region server上恢复的. region server宕机后发生了什么 HMaster有一 ...
- Orcal数据库,使用EF的自增处理
1.定义EF拦截器,截获执行命令前的操作.修改执行sql.还需要定义orcal序列,供自增使用 using System; using System.Collections.Generic; usin ...
- linuxGame:文明5汉化
此包来源苹果戏台的steam平台 参考网页: 1.https://tieba.baidu.com/p/4529797745 2.http://www.civclub.net/bbs/forum.php ...
- [翻译] TSMessages
TSMessages https://github.com/KrauseFx/TSMessages This library provides an easy to use class to show ...
- [翻译] DKTagCloudView - 标签云View
DKTagCloudView 效果(支持点击view触发事件): Overview DKTagCloudView is a tag clouds view on iOS. It can generat ...
- 解决UITableView在iOS7中UINavigationController里的顶部留白问题
解决UITableView在iOS7中UINavigationController里的顶部留白问题 出现问题时候的截图: 源码: 用到的类: UIViewController+TitleTextAtt ...
- 剑指offer 11二进制中1的个数
输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. java版本: public class Solution { public int NumberOf1(int n) { Strin ...
- November 15th 2016 Week 47th Tuesday
Success is finding satisfaction in giving a little more than you take. 成功就是付出比得到多,仍然心满意足. Can I find ...
- DevExpress01:Bar Manager,bar 、Toolbars
Bar Manager : 不可见的控件 如果想在窗体或用户控件添加工具条或弹出菜单,我们需要把一个不可见的控件 BarManager拖放到这个窗体或用户控件上. 这个BarManager控件维护工具 ...