SSM总结

SSM
Spring
SpringMVC
MyBatis

Spring
核心思想:IOC控制反转;AOP面向切面
Spring默认是以单例形式管理Bean
介绍:Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
框架的特性:
1轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。
2控制反转——Spring通过一种称作控制反转(IoC)的技术促进了低耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
3面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。
4容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。
5框架——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。
6MVC——Spring的作用是整合,但不仅仅限于整合,Spring 框架可以被看做是一个企业解决方案级别的框架。客户端发送请求,服务器控制器(由DispatcherServlet实现的)完成请求的转发,控制器调用一个用于映射的类HandlerMapping,该类用于将请求映射到对应的处理器来处理请求。HandlerMapping 将请求映射到对应的处理器Controller(相当于Action)在Spring 当中如果写一些处理器组件,一般实现Controller 接口,在Controller 中就可以调用一些Service 或DAO 来进行数据操作 ModelAndView 用于存放从DAO 中取出的数据,还可以存放响应视图的一些数据。 如果想将处理结果返回给用户,那么在Spring 框架中还提供一个视图组件ViewResolver,该组件根据Controller 返回的标示,找到对应的视图,将响应response 返回给用户。
所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。
Spring之IOC详解
一.spring IOC简介
IOC(控制反转:Inverse of Control),又称依赖注入,是一种重要的面向对象编程法则来削弱计算机程序的耦合问题,也是轻量级的Spring框架的核心。

二.spring IOC实例讲解
控制权转从业务代码转到主管手上
通过xml文件将实例依赖注入到某个类的属性中,底层原理还是依靠反射

Zhangsan.java
JavaWork.java(张三)
Test.java
控制反转。让每个人执行测试工作转交给主管。
Tester.java
ZhangSan.java Lisi.java
JavaWork.java(定义一个测试员tester,具体是哪个测试员,我们从主管那里设置)(这个程序只是负责有个人来做测试,而不管具体的某个人)
Test.java
这样的话,控制权就不是由业务代码(JavaWork)来搞了,而是转交给主管了(Test)。

beans.xml(ZhangSan. Lisi. JavaWork(属性tester,参考zhangsan或lisi))
Test2.java getBean

三.装配一个bean
在xml文件里面配置
id是javabean的唯一标识,通过id可以取出bean的实例
四.依赖注入
1.属性注入
People.java
beans.xml(People. property name id name age. valueXX XX XX)
Test2.java
2.构造函数注入(通过类型,通过索引,联合使用)
通过类型,按照构造方法的参数注入
beans.xml(People constructor-arg type int String int valueXX XX XX)
Test2.java
通过索引,按照构造方法的顺序注入
beans.xml(People constructor-arg index 0 1 2 valueXX XX XX)
Test2.java
联合使用
beans.xml(People constructor-arg index 0 1 2 type int String int valueXX XX XX)

Test2.java
3.工厂方法注入(非静态工厂,静态工厂)
工厂是用来造东西的
PeopleFactory.java
beans.xml (PeopleFactory. people指定是哪个工厂、工厂的哪个方法factory-bean=peopleFactory. factory-method=createPeople)
Test2.java
静态工厂
PeopleFactory2.java
beans.xml(静态的话,是不用new实例的,直接用类名.方法调用
people class=com.java1234.factory.PeopleFactory2 factory-method=createPeople)
Test2.java
4.泛型依赖注入(Spring4整合Hibernate4的时候顺带讲)
五.注入参数
1.基本类型值

beans.xml(People. property name id name age. valueXX XX XX)
2.注入bean
beans.xml(Dog. Property name name valueXX
People. property name id name age dog valueXX XX XX ref=dog)
3.注入内部bean
beans.xml(People. property name id name age dog valueXX XX XX [Dog. Property name name valueXX])
4.null值
beans.xml(People. property name id name age dog valueXX XX XX
5.级联属性
注入当前对象的成员变量(也是对象)的属性
我们这边不用引入bean的形式
beans.xml(People. property name id name age dog.name valueXX XX XX XX)
6.集合类型属性
List
beans.xml(People. property name id name age dog hobbies valueXX XX XX ref=dog. list value sing dance)
Set不能重复
beans.xml(People. property name id name age dog hobbies loves valueXX XX XX ref=dog. list value sing dance set value sing2 dance2)
Map
beans.xml(People. property name id name age dog hobbies loves works valueXX XX XX ref=dog. list value sing dance set value sing2 dance2
map entry keyvalue value. entry keyvalue value. …)
Properties
beans.xml(People. property name addresses props prop key address1 address2 )
六.自动装配(很少用)
通过配置 default-autowire 属性,Spring IOC 容器可以自动为程序注入 bean;默认是 no,不启用自动装配;
default-autowire 的类型有 byName,byType,constructor;
byName:通过名称进行自动匹配;
byType:根据类型进行自动匹配;
constructor:和 byType 类似,只不过它是根据构造方法注入而言的,根据类型,自动注入;
建议:自动装配机制慎用,它屏蔽了装配细节,容易产生潜在的错误;项目不是很大时或者命名很规范可以用

byName
beans.xml. default-autowire=“byName”

byType
beans.xml default-autowire=“byType”
当我们有两个dog的bean时他不识别,但是只有一个dogbean时就会自动识别
Constructor
people.java写构造方法
beans.xml. default-autowire=“constructor”

七.方法注入(很少用)
Spring bean作用域默认是 单例 singleton;可以通过配置prototype,实现多例;方法注入 lookup-method
beans.xml. dog class=XX scope=”prototype”. Property name name value XX
这样就实现了每次创建的狗都不一样!
我们把狗注入给people,注入的时候规定死了是同一条狗,所以又变回了单例
改为抽象的方法
People.java. public abstract Dog getDog();
beans.xml. people class=XX property name id name age value XX XX XX. Lookup-method name getDog bean dog

八.方法切换(很少用)
九.bean之间的关系
继承
依赖
引用

继承
定义抽象bean,一些公共的属性
abstractPeople. classXX abstract=”true” property…name className age valueXX XX
定义具体的bean
zhangsan. parent=” abstractPeople” property…name id name valueXX XX
依赖
abstractPeople. classXX abstract=”true” property…name className age valueXX XX
定义具体的bean
authority class service=Autority
zhangsan. parent=” abstractPeople”depends-on=”autority” property…name id name valueXX XX
应该是先获取权限再初始化people呀,这时就要配置依赖关系

引用
ref
十.bean的作用范围
1,singletonSpring ioc 容器中仅有一个 Bean 实例,Bean 以单例的方式存在;默认是单例
2,prototype 每次从容器中调用 Bean 时,都返回一个新的实例;
3,request 每次 HTTP 请求都会创建一个新的 Bean;
4,session 同一个 HTTPSession 共享一个 Bean;
5,globalsession 同一个全局 Session 共享一个 Bean,一般用于 Portlet 应用环境;
6,application 同一个 Application 共享一个 Bean

第三章 Spring之AOP详解
第一节 AOP简介
AOP 简介: 面向切面编程(也叫面向方面编程):Aspect Oriented Programming(AOP),是软件开发中的一个热点,也是 Spring 框架中的一个重要内容。利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度 降低,提高程序的可重用性,同时提高了开发的效率。 主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。
将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

第二节 SpringAOP实例
1.前置通知
可以获取调用的类名,方法名和传入的参数
2.后置通知
3.环绕通知
一般只用一个,用了环绕通知,前置和后置通知就可不用
4.返回通知(很少用)
5.异常通知

StudentService.java
StudentServiceImpl.java 业务逻辑代码
beans.xml
T.java
现在我们不想要日志代码侵入正常的业务逻辑代码,要用AOP来解决,用Spring把日志代码切进去
StudentServiceAspect.java
前置通知doBefore(JoinPoint jp)能在日志中获取类名、方法名、输入参数,通过joinpoint可以获取到
后置通知doAfter(JoinPoint jp)
环绕方法是有返回值的,参数也不一样Object doAround(ProceedingJoinPoint pjp)
System.out.println(“添加学生前”);
Object retVal=pjp.proceed();
System.out.println(retVal);
System.out.println(“添加学生后”);
return retVal;
返回通知doAfterReturning(JoinPoint jp)
异常通知doAfterThrowing(JoinPoint jp,Throwable ex)

beans.xml
在<beans xmlns中加入aop的网址
studentServiceAspect classXX
studentService classXX
aop:config
//首先定义一个切面
<aop:aspect id=“studentServiceAspect” ref=“studentServiceAspect”>
//定义切点,用到了表达式,来匹配addStudent这个方法,即我们的业务逻辑部分的代码
<aop:pointcut expression=“execution(* com.java1234.service..(…))” id=“businessService”/>
//定义前置通知
<aop:before method=“doBefore” pointcut-ref=“businessService”/>
//定义后置通知
<aop:after method=“doAfter” pointcut-ref=“businessService”/>
//定义环绕通知
<aop:around method=“doAround” pointcut-ref=“businessService”/>发现环绕通知比前置后置通知的优先级要低,但是用了环绕通知、前置后置就不需要了。
<aop:after-returning method=“doAfterReturning” pointcut-ref=“businessService”/>
<aop:after-throwing method=“doAfterThrowing” pointcut-ref=“businessService” throwing=“ex”/>

这样就好了

第四章 Spring对DAO的支持
第一节 Spring对JDBC的支持
JDBC是最原始的连接数据库的一种操作
1.配置数据源dbcp;
2.使用JdbcTemplate;
3.JdbcDaoSupport的使用;
daoimpl类不用写jdbcTemplate实例,直接设DataSource,getJdbcTemplate()即可.
4.NamedParameterJdbcTemplate的使用;支持命名参数变量;
org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
MapSqlParameterSource接受输入参数。
1.配置数据源dbcp;
2.使用JdbcTemplate;

jdbc.properties
数据库db_spring 表t_student
beans.xml
添加与数据源有关的包context的网址
//定义数据源

//dbcp的数据源连接池





//加载配置文件
<context:property-placeholder location=“jdbc.properties”/>

model-Student.java
dao-StudentDao.java interface 增删改查
dao.impl-StudentDaoImpl.java 增删改查
//将jdbcTemplate作为属性。后面的bean中也作为属性
private JdbcTemplate jdbcTemplate;
//用jdbcTemplate来实现增删改查操作
增加
String sql=“insert into t_student values(null,?,?)”;
Object []params=new Object[]{student.getName(),student.getAge()};
return jdbcTemplate.update(sql,params);
查找
String sql=“select * from t_student”;
final List studentList=new ArrayList();
jdbcTemplate.query(sql, new RowCallbackHandler(){
@Override
public void processRow(ResultSet rs) throws SQLException {
Student student=new Student();
student.setId(rs.getInt(“id”));
student.setName(rs.getString(“name”));
student.setAge(rs.getInt(“age”));
studentList.add(student);
}
});
return studentList;

service-StudentService.java 接口 增删改查
service.impl-StudentServiceImpl.java 调用dao层的方法增删改查
//将studentDao作为属性在后面bean中也作为属性注入
private StudentDao studentDao;
增加
return studentDao.addStudent(student);
T.java
beans.xml
//studentDao,注入jdbcTemplate



//studentService,注入studentDao


3.JdbcDaoSupport的使用;
daoimpl类不用写jdbcTemplate实例,直接设DataSource,getJdbcTemplate()即可.
StudentDaoImpl.java
//extends JdbcDaoSupport
//它的源码里面有jdbctemplate就不需要我们自己定义了
public class StudentDaoImpl extends JdbcDaoSupport implements StudentDao{
增加
String sql=“insert into t_student values(null,?,?)”;
Object []params=new Object[]{student.getName(),student.getAge()};
return this.getJdbcTemplate().update(sql,params);
查找
String sql=“select * from t_student”;
final List studentList=new ArrayList();
this.getJdbcTemplate().query(sql, new RowCallbackHandler(){
@Override
public void processRow(ResultSet rs) throws SQLException {
Student student=new Student();
student.setId(rs.getInt(“id”));
student.setName(rs.getString(“name”));
student.setAge(rs.getInt(“age”));
studentList.add(student);
}

	});

return studentList;

beans.xml


T.java 调用service层进行增删改查

jdbcsupport方便了一些

4.NamedParameterJdbcTemplate的使用;支持命名参数变量;
beans.xml

// 这里就不是属性了而是构造方法传入数据源








StudentDaoImpl.java
//NamedParameterJdbcTemplate
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
增加
String sql=“insert into t_student values(null,:name,:age)”;
//MapSqlParameterSource专门来放参数
MapSqlParameterSource sps=new MapSqlParameterSource();
sps.addValue(“name”, student.getName());
sps.addValue(“age”, student.getAge());
return namedParameterJdbcTemplate.update(sql,sps);
查找
String sql=“select * from t_student”;
final List studentList=new ArrayList();
namedParameterJdbcTemplate.query(sql, new RowCallbackHandler(){
@Override
public void processRow(ResultSet rs) throws SQLException {
Student student=new Student();
student.setId(rs.getInt(“id”));
student.setName(rs.getString(“name”));
student.setAge(rs.getInt(“age”));
studentList.add(student);
}

	});

return studentList;
第二节:Spring 对 Hibernate 的支持
后面 Spring 整合 Hibernate 的时候讲;

第五章 Spring对事务的支持
第一节 事务简介
要满足四个条件:
1.原子性
2.一致性
3.隔离性
4.持久性

第二节 编程式事务管理(用的较少,不是太好,会侵入业务代码)
Spring提供的事务模板类:org.springframework.transaction.support.TransactionTemplate
事务管理器:org.springframework.jdbc.datasource.DataSourceTransactionManager
银行转账例子
在数据库中建立db_bank
表t_count(id,userid,username,count)
BankDao.java
BankDaoImpl.java
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

String sql=“update t_count2 set count=count+:money where userId=:userId”;
MapSqlParameterSource sps=new MapSqlParameterSource();
sps.addValue(“money”, money);
sps.addValue(“userId”, userId);
namedParameterJdbcTemplate.update(sql,sps);
BankService.java
public void transferAccounts(int count,int userIdA,int userIdB);
BankServiceImpl.java
//首先引入dao
private BankDao bankDao;
//引入TransactionTemplate
private TransactionTemplate transactionTemplate;
//execute实现的方法体里面,写入doInTransactionWithoutResult方法
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
// TODO Auto-generated method stub
bankDao.outMoney(count, userIdA);
bankDao.inMoney(count, userIdB);
}
});
}
}
beans.xml






<context:property-placeholder location=“jdbc.properties”/>






//在service层注入事务transactionTemplate




//先配置事务管理器,注入数据源这个属性

//注入transactionTemplate,注入属性事务管理器 T.java 这个编程式事务管理不太好,因为事务的代码已经入侵到业务代码中了 第三节 声明式事务管理 1.使用XML配置声明式事务(一般情况下使用) 优点:只要配置一个xml文件,所有service都可以事务管理 BankServiceImpl.java beans.xml 首先引入事务相关的tx命名空间

<tx:advice id=“txAdvice” transaction-manager=“transactionManager”>
tx:attributes
//切的都是方法
<tx:method name=“insert*” propagation=“REQUIRED” />
</tx:attributes>
</tx:advice>

aop:config

//切的都是service层的所有方法使用表达式标准写法
<aop:pointcut id=“serviceMethod” expression=“execution(* com.java1234.service..(…))” />

//已经切到里面后要增加通知
<aop:advisor advice-ref=“txAdvice” pointcut-ref=“serviceMethod”/>
</aop:config>

<context:property-placeholder location=“jdbc.properties”/>

2.使用注解配置声明式样事务
缺点:每个service都要加注解
BankServiceImpl.java
//加注解
@Transactional
public class BankServiceImpl implements BankService{

beans.xml





//要加入这个,表明是注解,把事务管理器加进去
<context:property-placeholder location="jdbc.properties"/>

第四节 事务传播行为
事务传播行为:Spring 中,当一个 service 方法调用另外一个 service 方法的时候,因为每个 service 方法都有事务,这时候就出现了事务的嵌套;由此,就产生了事务传播行为; 在 Spring 中,通过配置 Propagation,来定义事务传播行为;
1PROPAGATION_REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
2PROPAGATION_SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。
3PROPAGATION_MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。 4PROPAGATION_REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。 5PROPAGATION_NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6PROPAGATION_NEVER–以非事务方式执行,如果当前存在事务,则抛出异常。
beanx.xml
<tx:method name=“update*” propagation=“REQUIRED” />
<tx:method name=“edit*” propagation=“REQUIRED” />
<tx:method name=“save*” propagation=“REQUIRED” />
<tx:method name=“add*” propagation=“REQUIRED” />
<tx:method name=“new*” propagation=“REQUIRED” />
<tx:method name=“set*” propagation=“REQUIRED” />
<tx:method name=“remove*” propagation=“REQUIRED” />
<tx:method name=“delete*” propagation=“REQUIRED” />
<tx:method name=“change*” propagation=“REQUIRED” />
<tx:method name=“get*” propagation=“REQUIRED” read-only=“true” />
<tx:method name=“find*” propagation=“REQUIRED” read-only=“true” />
<tx:method name=“load*” propagation=“REQUIRED” read-only=“true” />
<tx:method name="*" propagation=“REQUIRED” read-only=“true” />

tx:attributes
<tx:methodname=“insert*” propagation=“REQUIRED”/> tx:methodname="update*"propagation=“REQUIRED”/
<tx:methodname=“edit*” propagation=“REQUIRED”/> tx:methodname="save*"propagation=“REQUIRED”/ tx:methodname="add*"propagation=“REQUIRED”/
<tx:methodname=“new*” propagation=“REQUIRED” /> <tx:methodname=“set*” propagation=“REQUIRED”/> tx:methodname="remove*"propagation=“REQUIRED”/
<tx:methodname=“delete*” propagation=“REQUIRED”/> <tx:methodname=“change*” propagation=“REQUIRED”/> <tx:methodname=“get*” propagation=“REQUIRED"read-only=“true”/> <tx:methodname=“find*” propagation=“REQUIRED” read-only=“true”/> <tx:methodname=“load*” propagation=“REQUIRED” read-only=“true”/> <tx:methodname=”*" propagation="REQUIRED"read-only=“true”/>
</tx:attributes>

SpringMVC
第一节:SpringMVC 简介
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts2(一般老项目使用)等。

通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术、Velocity、Tiles、iText和POI。Spring MVC 框架并不知道使用的视图,所以不会强迫开发者只使用 JSP 技术。Spring MVC 分离了控制器、模型对象、过滤器以及处理程序对象的角色,这种分离让它们更容易进行定制。

MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用心得。
之前的项目比较简单,多是用JSP 、Servlet + JDBC 直接搞定,在项目中尝试用 Struts(Struts MVC)+Spring+Hibernate, 严格按照分层概念驱动项目开发,因项目需求一直不断变化,功能不断扩充、增强,技术构建也几经改变到目前有个稳定的应用,体会了很多感受,这次先对 Spring MVC 层进行一些个人总结。

MVC作为WEB项目开发的核心环节,正如三个单词的分解那样,C(控制器)将V(视图、用户客户端)与M(javaBean:封装数据)分开构成了MVC ,这边不去讨论项目中是否应用MVC ,也不针对MVC的实现原理进行讲解,而是探讨实践中如何从应用SSH, 到Struts(Struts MVC)+Spring+Hibernate的演化过程。
先看 Struts 如何与 Spring 结合处理一次简单的请求响应代码,前台可以设为用 AJAX 调用:
1.在 struts-config.xml 文件中加入
2.在 applicationContext.xml 文件中加入
3.cn.base.GetPersonListAction 实现请求响应代码
可以看出一次请求需求如此多的步骤,在加上一个项目下来有很多这样的请求响应,将给配置文件管理带来很大的麻烦。
经过对 Spring 的深入应用, Spring 本身提供的 URL 请求控制,对其天然支持可以让我们不需要 applicationContext.xml 再次声明一次 URL 请求 Bean ,即减少了 Struts 的声明 URL ,达到减少些繁琐的配置。但只是少了一些而已,同样也会面临着配置文件的管理问题。

Spring 注解将给我们的工作带来些轻松,利用反射机制原理出现的注解就是为了解决配置大量的配置问题。请看下处理一次简单的请求响应代码
@Controller --声明控制器
@RequestMapping("/person") –声明URL
public class PersonControl extends BaseController {
@Autowired –业务接口注入
private personServices personServices;/*** 获得人员列表*@param request* @param response* @throws Exception*/
@RequestMapping(params = “method=geList”) --即处理/person.do? method=geList方法
public void getnodeList(HttpServletRequest request,HttpServletResponse response) throws Exception { //处理请求//处理响应}}
可以看出,在代码上加入注解可以省去我们上面说的多个配置文件的工作,达到简便的 MVC 处理请求响应。
再配上简单的配置文件声明,即可轻松处理项目的全部请求控制工作。

Spring MVC乱码问题
在使用Spring MVC 做java Web 项目时,乱码问题时常都会出现,解决方法也不尽相同,有简单也有复杂的;如果加入了Spring框架之后就不一样了,可以采用Spring框架自带的过滤器CharacterEncodingFilter,这样可以大大减轻了我们的工作量,即简单方便又容易理解,配置方式如下:在web.xml文件中filter的位置加上如下内容:
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter

encoding
UTF-8

forceEncoding
true

encodingFilter
*.htm

springmvc实现上传文件代码片段

<?xml version="1.0" encoding="UTF-8"?>

@Controller
@RequestMapping("/common")
public class CommonController {
@RequestMapping(value = “/upload”)
public @ResponseBody String upload(@RequestParam(“file”) MultipartFile file, HttpSession session) throws Exception {
File localFile = new File(“c:/test/a.rar”);
file.transferTo(localFile);
return “success”;
}
}

第二节:SpringMVC 版 HelloWorld 实现
web.xml
SpringMvc01

index.html


CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter

encoding
utf-8



CharacterEncodingFilter
/*

springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:spring-mvc.xml springmvc *.do

spring-mvc.xml

//等会写写@controller
<context:component-scan base-package=“com.java1234”/>




HelloWorldController.java
@Controller
public class HelloWorldController {

@RequestMapping("/helloWorld")
public String helloWorld(Model model){
	model.addAttribute("message", "StringMVC你好!");
	return "helloWorld";
}

}

index.html
helloworld.jsp ${message }
执行结果
http://localhost:8080/SpringMVC
把请求获取到,分发处理到contronller

第二章 SpringMVC 控制器
第一节:@RequestMapping 请求映射
第二节:@RequestParam 请求参数
第三节:ModelAndView 返回模型和视图

Student.java
StudentController.java
@Controller
@RequestMapping("/student")
//这个是用来区分模块
public class StudentController {

private static List<Student> studentList=new ArrayList<Student>();

//这里为了简单起见不用service了,只用一个静态数据
static{
	studentList.add(new Student(1,"张三",11));
	studentList.add(new Student(2,"李四",12));
	studentList.add(new Student(3,"王五",13));
}

@RequestMapping("/list")
public ModelAndView list(){
	ModelAndView mav=new ModelAndView();
	mav.addObject("studentList", studentList);
	mav.setViewName("student/list");
	return mav;
}

@RequestMapping("/preSave")
//ModelAndView 添加的时候不需要,但修改的时候需要
//@RequestParam请求参数,然后要修改哪个数据,就会把它的参数传递过来
public ModelAndView preSave(@RequestParam(value="id",required=false) String id){
	ModelAndView mav=new ModelAndView();
	if(id!=null){//这是要修改数据,因为传递过来要修改的那个数据id
		mav.addObject("student", studentList.get(Integer.parseInt(id)-1));
		mav.setViewName("student/update");
	}else{//这里是要添加
		mav.setViewName("student/add");			
	}
	return mav;
}

spring-mvc.xml

<context:component-scan base-package="com.java1234"/>

<!-- 视图解析器 -->
<bean id="viewResolver"
	class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="prefix" value="/WEB-INF/jsp/" />
	<property name="suffix" value=".jsp"></property>
</bean>

index.jsp
<% response.sendRedirect(“student/list.do”); %>
//要返回给首页的话,要重定向后台

web.xml
SpringMvc01

index.jsp

<servlet>
	<servlet-name>springmvc</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>
</servlet>
<servlet-mapping>
	<servlet-name>springmvc</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>

list.jsp
添加学生

编号姓名年龄操作
${student.id }${student.name }${student.age }修改
启动程序 http://loclahost:8080/SpringMVC02 显示出list.jsp页面 编号 姓名 年龄 1 张三 11 2 李四 12 3 王五 13 执行顺序 我们通过list.do,先到达了controller层的/list,放上数据,返回到视图list.jsp,

add.jsp

学生添加
姓名
年龄
点击添加,到达了add.jsp页面

update.jsp

学生修改
姓名
年龄
点击修改哪个学生的数据,到达了相应的update.jsp页面

第四节:SpringMVC 对象属性自动封装
第五节:SpringMVCPOST 请求乱码解决
第六节:Controller 内部转发和重定向

接着项目SpringMVC02
->StudentController.java中新加下面两个方法
@RequestMapping("/save")
public String save(Student student){
if(student.getId()!=0){ //这是修改,因为id获取到了
Student s=studentList.get(student.getId()-1);
s.setName(student.getName());
s.setAge(student.getAge());
}else{
studentList.add(student); //这是添加
}
// return “redirect:/student/list.do”;//这是重定向list.do,地址栏会变化
return “forward:/student/list.do”;//转发是可以带一些数据过去的,地址栏不会变化
}

@RequestMapping("/delete")
public String delete(@RequestParam(“id”) int id){
studentList.remove(id-1);
return “redirect:/student/list.do”;
}
add.jsp

点击添加学生,赵六21,到controller层/save开始执行,重定向到/list 发现展出数据了,但是是乱码的 web.xml中加一个过滤器 characterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding utf-8 characterEncodingFilter *.do//对所有的controller都做过滤处理 第七节:SpringMvc 对 ServletAPI 的支持 第八节:SpringMvc 对 Json 的支持 User.java UserController.java @Controller @RequestMapping("/user") public class UserController {
@RequestMapping("/login")
public String login(HttpServletRequest request,HttpServletResponse response){
	System.out.println("----登录验证---");
	String userName=request.getParameter("userName");
	String password=request.getParameter("password");
	Cookie cookie=new Cookie("user",userName+"-"+password);//封装用户名密码
	cookie.setMaxAge(1*60*60*24*7);
	User currentUser=new User(userName,password);
	response.addCookie(cookie);//设置cookie
	HttpSession session=request.getSession();
	session.setAttribute("currentUser", currentUser);//获取Session
	return "redirect:/main.jsp";
}

@RequestMapping("/login2")
public String login2(HttpServletRequest request){
	return "redirect:/main.jsp";
}

@RequestMapping("/login3")
public String login3(HttpSession session){
	return "redirect:/main.jsp";
}

login.jsp
测试ajax

用户名:
密码:

main.jsp
Main.jsp ${currentUser.userName }
执行结果
输入zhangsan 123跳到main.jsp页面
显示Mai n.jsp zhangsan

spring-mvc.xml 加上下面的代码就可以用json了,支持mvc

mvc:annotation-driven/
UserController.java
@RequestMapping("/ajax")
public @ResponseBody User ajax(){
User user=new User(“zhangsan”,“123”);
return user;
}
运行结果
点击测试ajax,跳到页面显示

第三章 Rest 风格的资源 URL
第一节:Restful 风格的资源 URL 简介
没有后缀风格的URL
第二节:SpringMvc 对 Rest 风格的支持
第三节:@PathVariable 获取 Url 变量
第四节:SpringMvc 对静态资源的处理

Article.java
ArticleController.java
@Controller
@RequestMapping("/article")
//基路径
public class ArticleController {

@RequestMapping("/list")
public String list(Model model){
	return "article/list";
}

@RequestMapping("/details/{id}")
//@PathVariable可以获取url的值
public ModelAndView details(@PathVariable("id") int id){
	ModelAndView mav=new ModelAndView();
	if(id==1){
		mav.addObject("article", new Article("文章一","文章一的内容"));
	}else if(id==2){
		mav.addObject("article", new Article("文章二","文章二的内容"));
	}
	mav.setViewName("article/details");
	return mav;
}

}

list.jsp

文章列表
1 文章一
2 文章二
运行结果 文章列表 1文章一 2文章二 details.jsp

${article.title }

${article.content }

运行结果
请求到了
现在有一个需求要显示图片
spring-mvc.xml
mvc:annotation-driven/

<mvc:resources mapping="/resources/**" location="/images/"/>

<mvc:resources mapping="/resources2/**" location="/css/"/>

第四章 SpringMvc 文件上传
第一节:SpringMvc 单文件上传
第二节:SpringMvc 多文件上传
spring-mvc.xml 加一个bean

	<property name="defaultEncoding" value="UTF-8"/>  
    <property name="maxUploadSize" value="10000000"/>
FileUploadController.java @Controller public class FileUploadController {
@RequestMapping("/upload")
public String uploadFile(@RequestParam("file1") MultipartFile file1,HttpServletRequest request)throws Exception{
	String filePath=request.getServletContext().getRealPath("/");
	System.out.println(filePath);
	file1.transferTo(new File(filePath+"upload/"+file1.getOriginalFilename()));
	return "redirect:success.html";
}

@RequestMapping("/upload2")
public String uploadFiles(@RequestParam("file") MultipartFile[] files,HttpServletRequest request)throws Exception{
	String filePath=request.getServletContext().getRealPath("/");
	System.out.println(filePath);
	for(MultipartFile file:files){
		file.transferTo(new File(filePath+"upload/"+file.getOriginalFilename()));			
	}
	return "redirect:success.html";
}

}

index.jsp

上传文件
文件一
文件二

success.jsp
上传成功!
->执行结果
上传文件,成功后,访问路径就可以显示了
多文件也可以了

MyBatis
第一章 问候 MyBatis
第一节:MyBatis 简介
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

MyBatis [2] 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。
每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。
用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。

(1)加载配置并初始化
触发条件:加载配置文件
处理过程:将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
(2)接收调用请求
触发条件:调用Mybatis提供的API
传入参数:为SQL的ID和传入参数对象
处理过程:将请求传递给下层的请求处理层进行处理。
(3)处理操作请求
触发条件:API接口层传递请求过来
传入参数:为SQL的ID和传入参数对象
处理过程:
(A)根据SQL的ID查找对应的MappedStatement对象。
(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
©获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
(E)释放连接资源。
(4)返回处理结果将最终的处理结果返回。

我们把Mybatis的功能架构分为三层:
(1)API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
(2)数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
(3)基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

框架架构讲解:
(1)加载配置:配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个
mybatis结构
mybatis结构
个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
(2)SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。
(3)SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。
(4)结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回。

第二节:MyBatis 版 HelloWorld 实现
创建数据库db_mybatis,创建数据表t_student
id,name,age
jdbc.properties
mybaties-config.xml
















//映射器



Student.java
SqlSessionFactoryUtil .java
public class SqlSessionFactoryUtil {

private static SqlSessionFactory sqlSessionFactory;

public static SqlSessionFactory getSqlSessionFactory(){
	if(sqlSessionFactory==null){
		InputStream inputStream=null;
		try{
			inputStream=Resources.getResourceAsStream("mybatis-config.xml");
			sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	return sqlSessionFactory;
}

public static SqlSession openSession(){
	return getSqlSessionFactory().openSession();
}

}
StudentMapper.java 有的公司用DAO
public interface StudentMapper {

public int add(Student student);

}

StudentMapper.xml

<insert id="add" parameterType="Student"  >
	insert into t_student values(null,#{name},#{age})
</insert>
StudentTest.java SqlSession sqlSession=SqlSessionFactoryUtil.openSession(); StudentMapper studentMapper=sqlSession.getMapper(StudentMapper.class); Student student=new Student("李四",11); int result=studentMapper.add(student); sqlSession.commit(); if(result>0){ System.out.println("添加成功!"); }

第二章 MyBatis 项目配置
第一节:environments
MyBatis 支持多个环境,可以任意配置;
mybatis-config.xml




















第二节:transactionManager
MyBatis 支持两种类型的事务管理器:JDBC 和 MANAGED(托管);
JDBC:应用程序负责管理数据库连接的生命周期;
MANAGED:由应用服务器负责管理数据库连接的生命周期;(一般商业服务器才有此功能,如 JBOSS,WebLogic)

第三节:dataSource
用来配置数据源;类型有:UNPOOLED,POOLED,JNDI;
UNPOOLED,没有连接池,每次数据库操作,MyBatis 都会创建一个新的连接,用完后,关闭;适合小并发项目;
POOLED,用上了连接池;
JNDI,使用应用服务器配置 JNDI 数据源获取数据库连接;

第四节:properties
配置属性
->mybatis-config.xml

//不用properties文件的话,你就自己定义吧






第五节:typeAliases
给类的完成限定名取别名,方便使用;
->mybatis-config.xml

//不用每次都写完整路径了,而是只需要写个Student
//但是有100个类就得写100个吗?
//有一种方便的方法就是取package,即这个包下面的所有的类都进行扫描,直接取简易别名
<typeAliases>
	<package name="com.java1234.model"/>
</typeAliases>

第六节:mappers
引入映射文件
->mybatis-config.xml



//可以找配置文件,还可以找类
//有100个映射文件,难道要写100个mapper
//可以用package,此包下面的所有映射文件都进行了扫描


第七节:配置 Log4j 日志
->log4j.properties
log4j.rootLogger=info,appender1,appender2//输出目标

log4j.appender.appender1=org.apache.log4j.ConsoleAppender //控制台输出

log4j.appender.appender2=org.apache.log4j.FileAppender //向文件输出
log4j.appender.appender2.File=C:/logFile.txt

log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout
log4j.appender.appender2.layout=org.apache.log4j.TTCCLayout
StudentTest .java
private static Logger logger=Logger.getLogger(StudentTest.class);

public static void main(String[] args) {
	SqlSession sqlSession=SqlSessionFactoryUtil.openSession();
	StudentMapper studentMapper=sqlSession.getMapper(StudentMapper.class);
	Student student=new Student("李四",11);
	int result=studentMapper.add(student);
	sqlSession.commit();
	if(result>0){
		logger.info("添加成功!");
	}
}

第三章 使用 XML 配置 SQL 映射器
第一节:INSERT 映射语句
第二节:UPDATE 映射语句
第三节:DELETE 映射语句
第四节:SELECT 映射语句
StudentMapper.java 接口 增删改查
StudentMapper.xml

//返回是集合的话,要先定义一个resultMap

//和实体、列里面的要一一对应



<insert id="add" parameterType="Student"  >
	insert into t_student values(null,#{name},#{age})
</insert>

<update id="update" parameterType="Student">
	update t_student set name=#{name},age=#{age} where id=#{id}
</update>

<delete id="delete" parameterType="Integer">
	delete from t_student where id=#{id}
</delete>

<select id="findById" parameterType="Integer" resultType="Student">
	select * from t_student where id=#{id}
</select>

<select id="find" resultMap="StudentResult">
	select * from t_student
</select>

StudentTest2,java
private static Logger logger=Logger.getLogger(StudentTest.class);
private SqlSession sqlSession=null;
private StudentMapper studentMapper=null;

/**
 * 测试方法前调用
 * @throws Exception
 */
@Before
public void setUp() throws Exception {
	sqlSession=SqlSessionFactoryUtil.openSession();
	studentMapper=sqlSession.getMapper(StudentMapper.class);
}

/**
 * 测试方法后调用
 * @throws Exception
 */
@After
public void tearDown() throws Exception {
	sqlSession.close();
}

@Test
public void testAdd() {
	logger.info("添加学生");
	Student student=new Student("王五",12);
	studentMapper.add(student);
	sqlSession.commit();
}

@Test
public void testUpdate(){
	logger.info("修改学生");
	Student student=new Student(8,"王五2",13);
	studentMapper.update(student);
	sqlSession.commit();
}

@Test
public void testDelete(){
	logger.info("删除学生");
	studentMapper.delete(8);
	sqlSession.commit();
}

@Test
public void testFindById(){
	logger.info("通过ID查找学生");
	Student student=studentMapper.findById(1);
	System.out.println(student);
}

@Test
public void testFind(){
	logger.info("查找所有学生");
	List<Student> studentList=studentMapper.find();
	for(Student s:studentList){
		System.out.println(s);
	}
}

第四章 MyBatis 关系映射
第一节:一对一关系实现
新建表t_address
id sheng shi qu
要实现一对多的话
在t_student中加一个字段address,外键关联表t_address主键
Id name age address
Address.java
Student.java
StudentTest3.java
private static Logger logger=Logger.getLogger(StudentTest.class);
private SqlSession sqlSession=null;
private StudentMapper studentMapper=null;

/**
 * 测试方法前调用
 * @throws Exception
 */
@Before
public void setUp() throws Exception {
	sqlSession=SqlSessionFactoryUtil.openSession();
	studentMapper=sqlSession.getMapper(StudentMapper.class);
}

/**
 * 测试方法后调用
 * @throws Exception
 */
@After
public void tearDown() throws Exception {
	sqlSession.close();
}

StudentMapper.java中加一个方法
public Student findStudentWithAddress(Integer id);

StudentMapper.xml



	<result property="address.id" column="addressId"/>//这里要写外键的名字
	<result property="address.sheng" column="sheng"/>
	<result property="address.shi" column="shi"/>
	<result property="address.qu" column="qu"/>
</resultMap>
select * from t_student t1,t_address t2 where t1.addressId=t2.id and t1.id=#{id}

StudentTest3.java
@Test
public void testFindStudentWithAddress() {
logger.info(“查询学生(带地址)”);
Student student=studentMapper.findStudentWithAddress(1);
System.out.println(student);
}
查出了张三的信息和地址
但是这种方式不好,看下面的方式
StudentMapper.xml





<resultMap type="Student" id="StudentResult">
	<id property="id" column="id"/>
	<result property="name" column="name"/>
	<result property="age" column="age"/>
	<association property="address" resultMap="AddressResult"/>
</resultMap> 

把地址独立成一个模块,这样直接引用它就比较方便
另一种方式
StudentMapper.xml











最后一种方式才能高度重用
AddressMapper .java
public Address findById(Integer id);
AddressMapper .xml

<resultMap type="Address" id="AddressResult">
	<result property="id" column="id"/>
	<result property="sheng" column="sheng"/>
	<result property="shi" column="shi"/>
	<result property="qu" column="qu"/>
</resultMap>

<select id="findById" parameterType="Integer" resultType="Address">
	select * from t_address where id=#{id}
</select>
StudentMapper.xml //这里的column对应于student表的外键
<select id="findStudentWithAddress" resultMap="StudentResult" parameterType="Integer">
	select * from t_student t1,t_address t2 where t1.addressId=t2.id and t1.id=#{id}
</select>

运行结果
过程是在student表首先传了2进去,主键是2,查到addressid为几,再回到address的表

第二节:一对多关系实现
一个年级里面有很多学生
建表t_grade
id gradeName
表t_student
id name age addressId gradeId
通过年级来查询学生
Grade.java id gradeName students
GradeMapper .java
public Grade findById(Integer id);
GradeMapper .xml

<resultMap type="Grade" id="GradeResult">
	<result property="id" column="id"/>
	<result property="gradeName" column="gradeName"/>
	//这里的column才是student的主键
	<collection property="students" column="id" select="com.java1234.mappers.StudentMapper.findByGradeId"></collection>
</resultMap>

<select id="findById" parameterType="Integer" resultMap="GradeResult">
	select * from t_grade where id=#{id}
</select>

StudentMapper.java
public Student findByGradeId(Integer gradeId);
StudentMapper.xml






<select id="findByGradeId" resultMap="StudentResult" parameterType="Integer">
	select * from t_student where gradeId=#{gradeId}
</select>

GradeTest .java
@Test
public void testFindGradeWithStudents() {
logger.info(“查询年级(带学生)”);
Grade grade=gradeMapper.findById(2);
System.out.println(grade);
}

address也级联打印了
如果我们查学生时也想要查到他的年级
Student.java id name age address grade
StudentMapper.xml






其实相当于双向的一对一
StudentTest3.java
@Test
public void testFindStudentWithGrade(){
logger.info(“查询学生(带年级)”);
Student student=studentMapper.findStudentWithAddress(1);
System.out.println(student);
}
多对多用两个一对多实现

第五章 动态 SQL
第一节:if 条件
第二节:choose,when 和 otherwise 条件
StudentMapper.java
public List searchStudents(Map<String,Object> map);

public List<Student> searchStudents2(Map<String,Object> map);

StudentMapper.xml

<resultMap type="Student" id="StudentResult">
	<id property="id" column="id"/>
	<result property="name" column="name"/>
	<result property="age" column="age"/>
</resultMap>
//id对应方法,
<select id="searchStudents" parameterType="Map" resultMap="StudentResult">
	select * from t_student 
	 where gradeId=#{gradeId}
	 <if test="name!=null">
	 	and name like #{name}
	 </if>
	 <if test="age!=nulll">
	 	and age=#{age}
	 </if>
</select>

<select id="searchStudents2" parameterType="Map" resultMap="StudentResult">
	select * from t_student 
	 <choose>
	 	<when test="searchBy=='gradeId'">
	 		where gradeId=#{gradeId}
	 	</when>
	 	<when test="searchBy=='name'">
	 		where name like #{name}
	 	</when>
	 	<otherwise>
	 		where age=#{age}
	 	</otherwise>
	 </choose>
	 
</select>

StudentTest.java
@Test
public void testSearchStudents() {
logger.info(“添加学生(带条件)”);
Map<String,Object> map=new HashMap<String,Object>();
map.put(“gradeId”, 2);
map.put(“name”, “%李%”);
map.put(“age”, 11);
List studentList=studentMapper.searchStudents(map);
for(Student student:studentList){
System.out.println(student);
}
}

@Test
public void testSearchStudents2() {
	logger.info("添加学生(带条件)");
	Map<String,Object> map=new HashMap<String,Object>();
	map.put("searchBy", "age");
	map.put("gradeId", 2);
	map.put("name", "%李%");
	map.put("age", 11);
	List<Student> studentList=studentMapper.searchStudents2(map);
	for(Student student:studentList){
		System.out.println(student);
	}
}

第三节:where 条件
1,自动加上 where;
2,如果 where 子句以 and 或者 or 开头,则自动删除第一个 and 或者 or;
StudentMapper.xml

select * from t_student


gradeId=#{gradeId}


and name like #{name}


and age=#{age}



StudentTest.java
@Test
public void testSearchStudents3() {
logger.info(“添加学生(带条件)”);
Map<String,Object> map=new HashMap<String,Object>();
map.put(“gradeId”, 2);
map.put(“name”, “%李%”);
map.put(“age”, 11);
List studentList=studentMapper.searchStudents3(map);
for(Student student:studentList){
System.out.println(student);
}
}
第四节:trim 条件
功能和 where 元素类似,提供了前缀,后缀功能,更加灵活;
StudentMapper.xml

select * from t_student


gradeId=#{gradeId}


and name like #{name}


and age=#{age}



StudentTest.java
@Test
public void testSearchStudents4() {
logger.info(“添加学生(带条件)”);
Map<String,Object> map=new HashMap<String,Object>();
map.put(“gradeId”, 2);
// map.put(“name”, “%李%”);
// map.put(“age”, 11);
List studentList=studentMapper.searchStudents4(map);
for(Student student:studentList){
System.out.println(student);
}
}
第五节:foreach 循环
StudentMapper.xml

select * from t_student


gradeId in

#{gradeId}




StudentTest.java
@Test
public void testSearchStudents5() {
logger.info(“添加学生(带条件)”);
Map<String,Object> map=new HashMap<String,Object>();
List gradeIds=new ArrayList();
gradeIds.add(1);
gradeIds.add(2);
map.put(“gradeIds”, gradeIds);
List studentList=studentMapper.searchStudents5(map);
for(Student student:studentList){
System.out.println(student);
}
}
第六节:set 条件
1,自动加上 set;
2,自动剔除最后一个逗号“,”;
StudentMapper.xml

update t_student


name=#{name},


age=#{age},


where id=#{id}

StudentTest.java
@Test
public void testUpdateStudent(){
logger.info(“更新学生(带条件)”);
Student student=new Student();
student.setId(1);
student.setName(“张三3”);
student.setAge(13);
studentMapper.updateStudent(student);
sqlSession.commit();
}
第六章 Mybatis 杂项
第一节:处理 CLOB、BLOB 类型数据
第二节:传入多个输入参数
t_student
id name age pic remark
Student.java
StudentMapper.java
public List searchStudents6(String name,int age);//输入多个参数来查询

public int updateStudent(Student student);

public int insertStudent(Student student);//插入clob blob

public Student getStudentById(Integer id);//取出clob blob

StudentMapper.java




<insert id="insertStudent" parameterType="Student">
	insert into t_student values(null,#{name},#{age},#{pic},#{remark});
</insert>

<select id="getStudentById" parameterType="Integer" resultType="Student">
	select * from t_student where id=#{id}
</select>

<select id="searchStudents6" resultMap="StudentResult">
	select * from t_student where name like #{param1} and age=#{param2}
</select>

StudentTest2.java
@Test
public void testInsertStudent(){
logger.info(“添加学生”);
Student student=new Student();
student.setName(“张三4”);
student.setAge(14);
student.setRemark(“很长的本文…”);
byte []pic=null;
try{
File file=new File(“c://boy.jpg”);
InputStream inputStream=new FileInputStream(file);
pic=new byte[inputStream.available()];
inputStream.read(pic);
inputStream.close();
}catch(Exception e){
e.printStackTrace();
}
student.setPic(pic);
studentMapper.insertStudent(student);
sqlSession.commit();
}

@Test
public void testGetStudentById(){
	logger.info("通过ID查找学生");
	Student student=studentMapper.getStudentById(4);
	System.out.println(student);
	byte []pic=student.getPic();
	try{
		File file=new File("d://boy2.jpg");
		OutputStream outputStream=new FileOutputStream(file);
		outputStream.write(pic);
		outputStream.close();
	}catch(Exception e){
		e.printStackTrace();
	}
}

@Test
public void testSearchStudents6() {
	logger.info("添加学生(带条件)");
	List<Student> studentList=studentMapper.searchStudents6("%3%",12);
	for(Student student:studentList){
		System.out.println(student);
	}
}

第三节:Mybatis 分页
1,逻辑分页;
->StudentMapper.java

public List findStudents(RowBounds rowBounds);
1
->->StudentMapper.xml

select * from t_student ->StudentTest3.java

@Test
public void testFindStudent(){
logger.info(“查询学生”);
int offset=0,limit=3;//起始页,每页大小
RowBounds rowBounds=new RowBounds(offset,limit);
List studentList=studentMapper.findStudents(rowBounds);
for(Student student:studentList){
System.out.println(student);
}
}

select * from t_student ->查询结果 把所有数据取出来都放到内存中 2,物理分页; ->StudentMapper.java

public List findStudents2(Map<String,Object> map);

->StudentMapper.xml

select * from t_student limit #{start},#{size}//真正的物理分页 ->StudentTest3.java

@Test
public void testFindStudent2(){
logger.info(“查询学生”);
Map<String,Object> map=new HashMap<String,Object>();
map.put(“start”, 3);
map.put(“size”, 3);
List studentList=studentMapper.findStudents2(map);
for(Student student:studentList){
System.out.println(student);
}
}

第四节:Mybatis 缓存

Mybatis 默认情况下,MyBatis 启用一级缓存,即同一个 SqlSession 接口对象调用了相同的 select 语句,则直 接会从缓存中返回结果,而不是再查询一次数据库; 开发者可以自己配置二级缓存,二级缓存是全局的;
默认情况下,select 使用缓存的,insertupdatedelete 是不使用缓存的;

并发量很大,且都是在查询的情况下。
->StudentMapper.xml

<cache size="1024" flushInterval="60000" eviction="LRU" readOnly="false"/>
<select id="findStudents" resultMap="StudentResult" flushCache="false" useCache="true">
	select * from t_student
</select>
<insert id="insertStudent" parameterType="Student" flushCache="true">
insert into t_student values(null,#{name},#{age},#{pic},#{remark});
</insert>

第七章 使用注解配置 SQL 映射器
第一节:基本映射语句
1,@Insert 2,@Update 3,@Delete 4,@Select
StudentMapper.java 没有StudentMapper.xml了
@Insert(“insert into t_student values(null,#{name},#{age})”)
public int insertStudent(Student student);

@Update("update t_student set name=#{name},age=#{age} where id=#{id}")
public int updateStudent(Student student);

@Delete("delete from t_student where id=#{id}")
public int deleteStudent(int id);

@Select("select * from t_student where id=#{id}")
public Student getStudentById(Integer id);

@Select("select * from t_student")
@Results(
		{
			@Result(id=true,column="id",property="id"),
			@Result(column="name",property="name"),
			@Result(column="age",property="age")
		}
)
public List<Student> findStudents();

第二节:结果集映射语句
第三节:关系映射
1.一对一映射; 2,一对多映射;
->t_student
id name age addressid
t_address
t_grade
->Student.java id name age address grade
Address.java id sheng shi qu
Grade.java id gradeName students
StudentMapper.java
@Select(“select * from t_student where id=#{id}”)
@Results(
{
@Result(id=true,column=“id”,property=“id”),
@Result(column=“name”,property=“name”),
@Result(column=“age”,property=“age”),
//column外键property对应于address对象//one=@One addressid与address中的id一一对应
@Result(column=“addressId”,property=“address”,one=@One(select=“com.java1234.mappers.AddressMapper.findById”))
}
)
public Student selectStudentWithAddress(int id);//用学生查地址

@Select("select * from t_student where gradeId=#{gradeId}")
@Results(
		{
			@Result(id=true,column="id",property="id"),
			@Result(column="name",property="name"),
			@Result(column="age",property="age"),
			@Result(column="addressId",property="address",one=@One(select="com.java1234.mappers.AddressMapper.findById"))
		}
)
public Student selectStudentByGradeId(int gradeId);//用年级查学生

@Select("select * from t_student where id=#{id}")
@Results(
		{
			@Result(id=true,column="id",property="id"),
			@Result(column="name",property="name"),
			@Result(column="age",property="age"),
			@Result(column="addressId",property="address",one=@One(select="com.java1234.mappers.AddressMapper.findById")),
			@Result(column="gradeId",property="grade",one=@One(select="com.java1234.mappers.GradeMapper.findById"))

AddressMapper.java
@Select(“select * from t_address where id=#{id}”)
public Address findById(Integer id);
GradeMapper.java
@Select(“select * from t_grade where id=#{id}”)
@Results(
{
@Result(id=true,column=“id”,property=“id”),
@Result(column=“gradeName”,property=“gradeName”),
@Result(column=“id”,property=“students”,many=@Many(select=“com.java1234.mappers.StudentMapper.selectStudentByGradeId”))
}
)
public Grade findById(Integer id);

@Test
public void testSelectStudentWithAddress() {
logger.info(“查找学生(带地址)”);
Student student=studentMapper.selectStudentWithAddress(1);
System.out.println(student);
}

@Test
public void testSelectGradeWithStudents() {
logger.info(“查找年级(带学生)”);
Grade grade=gradeMapper.findById(2);
System.out.println(grade);
List studentList=grade.getStudents();
for(Student student:studentList){
System.out.println(student);
}
}
@Test
public void testSelectStudentWithAddressAndGrade() {
logger.info(“查找学生(带年级,带地址)”);
Student student=studentMapper.selectStudentWithAddressAndGrade(1);
System.out.println(student);
}

第四节:动态 SQL
@InsertProvider @UpdateProvider @DeleteProvider @SelectProvider
StudentMapper.java
@InsertProvider(type=StudentDynaSqlProvider.class,method=“insertStudent”)
public int insertStudent(Student student);

@UpdateProvider(type=StudentDynaSqlProvider.class,method=“updateStudent”)
public int updateStudent(Student student);

@DeleteProvider(type=StudentDynaSqlProvider.class,method=“deleteStudent”)
public int deleteStudent(int id);

@SelectProvider(type=StudentDynaSqlProvider.class,method=“getStudentById”)
public Student getStudentById(Integer id);

@SelectProvider(type=StudentDynaSqlProvider.class,method=“findStudents”)
public List findStudents(Map<String,Object> map);

StudentDynaSqlProvider.java
public String insertStudent(final Student student){
return new SQL(){
{
INSERT_INTO(“t_student”);
if(student.getName()!=null){
VALUES(“name”, “#{name}”);
}
if(student.getAge()!=null){
VALUES(“age”, “#{age}”);
}
}
}.toString();
}

	public String updateStudent(final Student student){
		return new SQL(){
			{
				UPDATE("t_student");
				if(student.getName()!=null){
					SET("name=#{name}");
				}
				if(student.getAge()!=null){
					SET("age=#{age}");
				}
				WHERE("id=#{id}");
			}
		}.toString();
	}
	
	public String deleteStudent(){
		return new SQL(){
			{
				DELETE_FROM("t_student");
				WHERE("id=#{id}");
			}
		}.toString();
	}
	
	public String getStudentById(){
		return new SQL(){
			{
				SELECT("*");
				FROM("t_student");
				WHERE("id=#{id}");
			}
		}.toString();
	}
	
	public String findStudents(final Map<String,Object> map){
		return new SQL(){
			{
				SELECT("*");
				FROM("t_student");
				StringBuffer sb=new StringBuffer();
				if(map.get("name")!=null){
					sb.append(" and name like '"+map.get("name")+"'");
				}
				if(map.get("age")!=null){
					sb.append(" and age="+map.get("age"));
				}
				if(!sb.toString().equals("")){
					WHERE(sb.toString().replaceFirst("and", ""));					
				}
			}
		}.toString();
	}

Mybatis 与 Spring,SpringMvc 整合
第一节:Spring 与 SpringMvc 整合
这个讲过了
第二节:Spring 与 Mybatis 整合
web.xml
MyBatisPro05

index.jsp

<!-- Spring配置文件 -->
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 编码过滤器 -->
<filter>
	<filter-name>encodingFilter</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	<async-supported>true</async-supported>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>encodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring监听器 -->
<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- 添加对springmvc的支持 -->
<servlet>
	<servlet-name>springMVC</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>
	<async-supported>true</async-supported>
</servlet>

spring-mvc.xml

<context:component-scan base-package="com.java1234.controller" />

<!-- 视图解析器 -->
<bean id="viewResolver"
	class="org.springframework.web.servlet.view.InternalResourceViewResolver">

applicationContext.xml

<context:component-scan base-package="com.java1234.dao" />
<context:component-scan base-package="com.java1234.service" />

<!-- 配置数据源 -->
<bean id="dataSource"
	class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
	<property name="url" value="jdbc:mysql://localhost:3306/db_mybatis"/>
	<property name="username" value="root"/>
	<property name="password" value="123456"/>
</bean>

<!-- 配置mybatis的sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource" />
	<!-- 自动扫描mappers.xml文件 -->
	<property name="mapperLocations" value="classpath:com/java1234/mappers/*.xml"></property>
	<!-- mybatis配置文件 -->
	<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>

<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	<property name="basePackage" value="com.java1234.dao" />
	<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>

<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource" />
</bean>

<!-- 配置事务通知属性 -->  
<tx:advice id="txAdvice" transaction-manager="transactionManager">  
    <!-- 定义事务传播属性 -->  
    <tx:attributes>  
        <tx:method name="insert*" propagation="REQUIRED" />  
        <tx:method name="update*" propagation="REQUIRED" />  
        <tx:method name="edit*" propagation="REQUIRED" />  
        <tx:method name="save*" propagation="REQUIRED" />  
        <tx:method name="add*" propagation="REQUIRED" />  
        <tx:method name="new*" propagation="REQUIRED" />  
        <tx:method name="set*" propagation="REQUIRED" />  
        <tx:method name="remove*" propagation="REQUIRED" />  
        <tx:method name="delete*" propagation="REQUIRED" />  
        <tx:method name="change*" propagation="REQUIRED" />  
        <tx:method name="get*" propagation="REQUIRED" read-only="true" />  
        <tx:method name="find*" propagation="REQUIRED" read-only="true" />  
        <tx:method name="load*" propagation="REQUIRED" read-only="true" />  
        <tx:method name="*" propagation="REQUIRED" read-only="true" />  
    </tx:attributes>  
</tx:advice>  

<!-- 配置事务切面 -->  
<aop:config>  
    <aop:pointcut id="serviceOperation"  
        expression="execution(* com.java1234.service.*.*(..))" />  
    <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />  
</aop:config>  

mybatis-config.xml






User.java
UserDao.java
public User login(User user);

UserMapper.java

<resultMap type="User" id="UserResult">
	<result property="id" column="id"/>
	<result property="userName" column="userName"/>
	<result property="password" column="password"/>
</resultMap>

<select id="login" parameterType="User" resultMap="UserResult">
	select * from t_user where userName=#{userName} and password=#{password}
</select>

UserService.java
public User login(User user);
UserServiceImpl.java
@Service(“userService”)
public class UserServiceImpl implements UserService{

@Resource
private UserDao userDao;

@Override
public User login(User user) {
	return userDao.login(user);
}

}

UserController.java
@Controller
@RequestMapping("/user")
public class UserController {

@Resource
private UserService userService;

@RequestMapping("/login")
public String login(User user,HttpServletRequest request){
	User resultUser=userService.login(user);
	if(resultUser==null){
		request.setAttribute("user", user);
		request.setAttribute("errorMsg", "用户名或密码错误!");
		return "index";
	}else{
		HttpSession session=request.getSession();
		session.setAttribute("currentUser", resultUser);
		return "redirect:/success.jsp";
	}
}

}

index.jsp

userName:
password:
${errorMsg }

success.jsp
欢迎:${currentUser.userName }

SSM-CRUD
SSM-CRUD ssm:SpringMVC+Spring+MyBatis

CRUD:Create(创建) Retrieve(查询) Update(更新) Delete(删除)
功能点
• 1、分页
• 2、数据校验
• jquery前端校验+JSR303后端校验
• 3、ajax
• 4、Rest风格的URI;使用HTTP协议请求方式的动词,来表示对资源的操作(GET(查询),POST(新增),PUT(修改),DELETE (删除))

技术点
• 基础框架-ssm(SpringMVC+Spring+MyBatis)
• 数据库-MySQL
• 前端框架-bootstrap快速搭建简洁美观的界面
• 项目的依赖管理-Maven
• 分页-pagehelper
• 逆向工程-MyBatis Generator

基础环境搭建
• 1、创建一个maven工程
• 2、引入项目依赖的jar包
• spring • springmvc • mybatis • 数据库连接池,驱动包 • 其他(jstl,servlet-api,junit)
• 3、引入bootstrap前端框架
• 4、编写ssm整合的关键配置文件
• web.xml,spring,springmvc,mybatis,使用mybatis的逆向工程生成对应的bean以 及mapper
• 5、测试mapper

1.创建Maven项目
设置maven
引入jar包
引入Bootstrap
配置web.xml
配置SpringMVC
配置Spring
MyBatis逆向工程
修改Mapper文件
搭建Spring单元测试环境

2.查询分页后台代码完成
查询使用Spring单元测试测试分页请求
查询搭建Bootstrap分页页面
查询_显示分页数据
查询_返回分页的json数据
查询_构建员工列表
查询_构建分页条
查询_分页显示完整细节

3.新增_创建员工新增的模态框
新增_Ajax显示部门信息
新增_新增基本完成
新增_jQuery前端校验完成
新增_校验信息显示优化
新增_Ajax校验用户名是否重复
新增_Ajax校验用户名细节处理
新增_JSR303校验

4.修改_创建员工修改模态框
修改_回显员工信息
修改_Ajax发送PUT请求引发的血案
修改_修改完成

5.删除_删除单一员工
删除_全选&全不选
删除_批量删除完成

CRUD-
1查询
• 1、访问index.jsp页面
• 2、index.jsp页面发送出查询员工列表请求
• 3、EmployeeController来接受请求,查出员工数据
• 4、来到list.jsp页面进行展示
• 5、pageHelper分页插件完成分页查询功能
• URI:/emps

查询-ajax
• 1、index.jsp页面直接发送ajax请求进行员工分页数据的查询
• 2、服务器将查出的数据,以json字符串的形式返回给浏览器
• 3、浏览器收到js字符串。可以使用js对json进行解析,使用js通过 dom增删改改变页面。
• 4、返回json。实现客户端的无关性。

2新增-逻辑
• 1、在index.jsp页面点击”新增”
• 2、弹出新增对话框
• 3、去数据库查询部门列表,显示在对话框中
• 4、用户输入数据,并进行校验 • jquery前端校验,ajax用户名重复校验,重要数据(后端校验(JSR303),唯一约束);
• 5、完成保存
• URI:
• /emp/{id} GET 查询员工
• /emp POST 保存员工
• /emp/{id} PUT 修改员工
• /emp/{id} DELETE 删除员工

3修改-逻辑
• 1、点击编辑
• 2、弹出用户修改的模态框(显示用户信息)
• 3、点击更新,完成用户修改

4删除-逻辑
• 1、单个删除
• URI:/emp/{id} DELETE
• 2、批量删除

ssm_crud 项目的功能点:
1、分页
2、数据校验(Jquery前端校验+JSR303后端校验)
3、ajax
4、Rest风格的URI:使用HTTP协议请求方式的动词,来表示对资源的操作(GET(查询)、POST(新赠)、PUT(修改)、DELETE(删除))

技术点:
1、基础框架-ssm(SpringMVC+Spring+Mybatis)
2、数据库-MySQL
3、前端框架-bootstrap快速搭建简洁美观的界面
4、项目的依赖管理-Maven
5、分页-pagehelper
6、mybatis Generator-逆向工程
接下来带领大家来进行工程的搭建:

一、基础环境搭建

  1. 1、 创建一个maven工程、在pom.xml 中引入项目依赖的jar包
    Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。当你使用Maven的时候,你用一个明确定义的项目对象模型来描述你的项目,然后Maven可以应用横切的逻辑,这些逻辑来自一组共享的(或者自定义的)插件。
    Maven 有一个生命周期,当你运行 mvn install 的时候被调用。这条命令告诉 Maven 执行一系列的有序的步骤,直到到达你指定的生命周期。遍历生命周期旅途中的一个影响就是,Maven 运行了许多默认的插件目标,这些目标完成了像编译和创建一个 JAR 文件这样的工作。
    此外,Maven能够很方便的帮你管理项目报告,生成站点,管理JAR文件,等等。
    新建一个maven工程
    具体需要加入什么jar,看自己的功能所需 , 可以到官网查https://mvnrepository.com
    1.2、引入bootstrap前端框架
    bootstrap-3.3.7-dist可以在(http://v3.bootcss.com)进行下载

1.3、编写SSM框架的关键配置文件。

web.xml 文件 : web项目工程的必备文件,主要用来启动Spring 容器以及关联applicationContext.xml 和拦截所有请求、以及字符编码过滤器
applicationContext.xml: Spring的配置文件、和mybatis的整合配置
dispatcherServlet-servlet.xml: SpringMVC配置文件
mybatis-config.xml: mybatis配置文件

->web.xml
1、启动Spring的容器
needed for ContextLoaderListener
Bootstraps the root web application context before servlet initialization

2、springmvc的前端控制器,拦截所有请求
The front controller of this Spring Web application, responsible for handling all application requests
Map all requests to the DispatcherServlet for handling

3、字符编码过滤器,一定要放在所有过滤器之前
4、使用Rest风格的URI,将页面普通的post请求转为指定的delete或者put请求
在resources 下创建dbconfig.properties配置文件:
这个数据库连接的一些常量配置 等一下会在spring中链接数据库是需要引用的

在resources 下创建applicationContext.xml配置文件:
spring的配置文件 ,这里主要配置和业务逻辑有关的 :
配置数据库数据
配置Spring和MyBatis的整合
置扫描器,将mybatis接口的实现加入到ioc容器中
配置一个可以执行批量的sqlSession
配置事务控制
开启基于注解的事务,使用xml配置形式的事务
配置事务增强,事务如何切入
配置MultipartReaolver 文件上传配置
………
自动扫描包
Spring的配置文件,这里主要配置和业务逻辑有关的,数据源
配置和MyBatis的整合:指定mybatis全局配置文件的位置、指定mybatis,mapper文件的位置、配置扫描器,将mybatis接口的实现加入到ioc容器中。扫描所有dao接口的实现,加入到ioc容器中
配置一个可以执行批量的sqlSession
事务控制的配置:控制住数据源、开启基于注解的事务,使用xml配置形式的事务(必要主要的都是使用配置式)、切入点表达式、配置事务增强

在webapp/WEB-INFO/ 下创建dispatcherServlet-servlet.xmll配置文件:
用于配置springmvc的
SpringMVC的配置文件,包含网站跳转逻辑的控制,配置,只扫描控制器
配置视图解析器,方便页面返回
两个标准配置:将springmvc不能处理的请求交给tomcat

在resources 下创建mybatis-config.xml配置文件
开启驼峰命名转换
指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean
分页插件

配置完成后即可用mybatis逆向工程生成对应的bean以及mapper文件
1.4 建立mbg.xml文件进行逆向工程配置
mbg.xml
配置数据库连接
指定javaBean生成的位置
指定sql映射文件生成的位置
指定dao接口生成的位置,mapper接口
table指定每个表的生成策略
然后在test包下面创建MBGTest.java 进行mapper、bean文件的生成
1.5新创建的项目Tomcat跟Maven都要重新配

二、MyBatis-逆向工程

MyBatis Generator 简介
• 简称MBG,是一个专门为MyBatis框架使用者定 制的代码生成器,可以快速的根据表生成对应的 映射文件,接口,以及bean类。支持基本的增删 改查,以及QBC风格的条件查询。但是表连接、 存储过程等这些复杂sql的定义需要我们手工编写

• 官方文档地址 http://www.mybatis.org/generator/
• 官方工程地址 https://github.com/mybatis/generator/releases

2.1创建数据库
创建部门表
创建员工表
注意:这里创建了一个外键d_id与tbl_emp的dept_id关联起来
2.2在resources 下创建mgb.xml配置文件:
这里每一个配置都有解释认真看下面内容即可在这不做说明,加入如下内容:
前面写过一遍mgb.xml,这里再复习一下
注意:自己在resources下创建一名叫mapper的文件夹
2.3在pom.xml配置文件中加入如下内容:
org.mybatis.generator
2.4MyBatis-逆向工程生成的代码更改
三、SSM实现简单的CRUD之DAO层
DepartmentMapper.xml
EmployeeMapper.xml
EmployeeMapper.java
DepartmentMapper.java
Employee.java
Department.java
MapperTest.java
四、SSM实现简单的CRUD之Service层

开始Service层的编码之前,我们首先需要进行Dao层编码之后的思考:在Dao层我们只完成了针对表的相关操作包括写了接口方法和映射文件中的sql语句,并没有编写逻辑的代码,例如对多个Dao层方法的拼接,当我们用户成功秒杀商品时我们需要进行商品的减库存操作和增加用户明细等等,这些逻辑我们都需要在Service层完成。但是这个CRUD并不需要什么很难的逻辑只是一个简单的增删查改,所以在这个CRUD的Service层会很简单,接下来我们便进行Service层代码的编写。
EmployeeService.java
DepartmentService.java
ServicceTest.java
五、SSM实现简单的CRUD之Controller层

Controller开发
在开发Controller之前先注意一点 因为整个crud我们是全程基于ajax,所以先创建一个在cn.hfbin.crud包下创建dto包,用来存放放回的数据。新建一个Msg类,内容如下:
Msg.java
Controller中的每一个方法都对应我们系统中的一个资源URL,其设计应该遵循Restful接口的设计风格。在cn.hfbin.crud包下创建一个controller包用于放web层Controller开发的代码,在该包下创建一个EmployeeController.java
下面说明一下这三个注解代表什么
@ResponseBody 返回json数据
@RequestMapping(“”) 请求路径
@RequestParam 请求参数
DepartmentController.java
六、SSM实现简单的CRUD之Web层
本篇文章主要来讲解Web层,主要介绍前端交互设计、Restful:url满足Restful设计规范、Spring MVC、bootstrap+jquery这四个方面的开发。
Restful接口设计学习
CRUD API URL 设计

页面开发
页面由前端工程师完成,这里直接拷贝我github上源代码中jsp的代码(webapp包下的所有资源)即可。
然后运行Tomcat服务器,在浏览器中输入http://localhost:8080/emps,即可访问我们的秒杀列表页面

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值