一、持久层编写(Mybatis)
- 导入必须要的jar包【mybatis、mysql】
- 创建pojo类(实体类)
public class Dept {
private int deptno;
private String dname;
private String loc;
public Dept() {
super();
// TODO Auto-generated constructor stub
}
public Dept(int deptno, String dname, String loc) {
super();
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
public int getDeptno() {
return deptno;
}
public void setDeptno(int deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
@Override
public String toString() {
return "Dept [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]";
}
}
- 建立mapper接口
public interface DeptMapper {
/**
* 添加部门
*/
public void saveDept(Dept dept);
}
- 建立mapper接口的sql映射文件【对应mapper的空间】
<!-- 编写mybatis中mapper接口的方法,提供对应的sql语句 -->
<mapper namespace="cn.ssm.dao.DeptMapper">
<!-- 添加客户 -->
<insert id="saveDept" parameterType="cn.ssm.po.Dept">
insert into dept(deptno,dname,loc) values (#{deptno},#{dname},#{loc})
</insert>
</mapper>
- 建立sqlMapConfig.xml文件【包含数据库连接,查找sql的映射文件】
<configuration>
和spring整合以后就会将environment配置删除
<environments default="development">
<environment id="development">
<!--使用JDBC事务管理-->
<transactionManager type="JDBC"></transactionManager>
<!--数据库连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test2?serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<!--查找sql映射文件的位置-->
<mappers>
<mapper resource="mapper/DeptMapper.xml"/>
</mappers>
</configuration>
<!-- 整合spring后,数据库连接在applicationContext.xml中配置,还有sqlSessionFactory,并在sqlSessionFactory中加载sql映射文件 -->
- 编写测试类【读取xml文件,创建会话工厂,创建会话并打开,获取并返回mapper接口的对象】
@Test
public void test1() {
try {
Reader reader = Resources.getResourceAsReader("sqlMapConfig.xml");
SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sf.openSession();
DeptMapper deptMapper = session.getMapper(DeptMapper.class);
Dept dept = new Dept();
dept.setDeptno(001);
dept.setDname("张三丰");
dept.setLoc("浙江");
deptMapper.saveDept(dept);
session.commit();
System.out.println("数据插入成功....");
session.close();
} catch (Exception e) {
e.printStackTrace();
}
}
二、Mybatis和Spring整合(三种方法–不断优化的过程)
- 有mapper实现类(在applicationContext中配置实现类的bean)
- 无mapper实现类(在applicationContext中配置接口类的bean)
- 使用mapper的扫描
- 导包【mybatis-spring,IOC,aop,tx,comtext】
- mapper实现类【继承dao层接口】 (在不使用mapper实现类定义的时候可以删除)
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import cn.ssm.dao.DeptMapper;
import cn.ssm.po.Dept;
//SqlSessionDaoSupport是一个抽象的支持类,用来为你提供SqlSession。
//调用getSqlSession()方法你会得到一个SqlSessionTemplate,这然后可以用于执行SQL方法
public class DeptMapperImpl extends SqlSessionDaoSupport implements DeptMapper {
@Override
public void saveDept(Dept dept) {
SqlSession session = this.getSqlSession();
session.insert("saveDept", dept);
//不需要事务的提交,spring的过程自动帮助进行提交事务
}
}
- 编写applicationContext.xml文件【读取jdbc.properties,配置连接池对象,创建出sqlsessionfactory对象】
<!-- 读取db.properties -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 创建数据源(datesource) -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<!-- 最大连接数 -->
<property name="maxIdle" value="10"></property>
<!-- 最大空闲数 -->
<property name="maxActive" value="5"></property>
</bean>
<!-- 创建sqlsessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 关联连接池 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 加载sql的映射文件 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
此时sqlMapConfig文件已经没有用了(可以删除),在applicationContext中已经将所有的东西配置完成(数据库连接池、sqlSessionFasctory以及实现类的对象)
3.1 需要实现类(1、接口实现类 2、实现类对象的bean)
<!-- 创建DeptMapperImpl对象,注入sqlSessionFactory -->
<bean id="deptMapper" class="cn.ssm.dao.impl.DeptMapperImpl">
<!-- 关联sqlSessionFactory -->
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
3.2 不需要实现类(1、接口mapper的bean)
- 将DeptMapperImpl实现类删除
- 在applicationContext中创建的bean也可以删除
<!-- 需要配置mapper接口 -->
<bean id="deptMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!-- 关联一个mapper接口 -->
<property name="mapperInterface" value="cn.ssm.dao.DeptMapper"></property>
<!-- 关联sqlSessionFactory -->
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
3.3 mapper接口扫描的方式(删除配置mapper接口的bean)---------最优的方案
<!-- mapper接口的扫描 -->
<!-- 注意:如果使用mapper接口包扫描的方式,那么每个mapper接口在Spring容器中的ID名称为类名称 例如:DeptMapper ——> deptMapper -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 配置mapper接口所在包的路径 -->
<property name="basePackage" value="cn.ssm.dao"></property>
</bean>
- 编写测试类
@Test
public void test() {
//加载spring配置
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取对象
DeptMapper deptMapper = (DeptMapper) ac.getBean("deptMapper");
//调用方法
Dept dept = new Dept();
dept.setDeptno(000);
dept.setDname("张四丰");
dept.setLoc("浙江");
deptMapper.saveDept(dept);
}
5. 整合spring事务管理(业务层)
5.1 编写业务层接口
public interface DeptService {
public void saveDept(Dept dept);
}
5.2 编写业务层接口实现类(使用注解需要有包的扫描)
@Service("deptService")
public class DeptServiceImpl implements DeptService {
//注入mapper对象
@Resource
private DeptMapper deptMapper;
@Override
public void saveDept(Dept dept) {
deptMapper.saveDept(dept);
int i = 100/0;
deptMapper.saveDept(dept);
}
}
<!-- 开启spring 的IOC注解的扫描 -->
<context:component-scan base-package="cn.ssm"></context:component-scan>
5.3 编写测试类(没有添加事务管理)
@Test
public void test() {
//加载spring配置
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取对象
DeptService deptService = (DeptService) ac.getBean("deptService");
//调用方法
Dept dept = new Dept();
dept.setDeptno(005);
dept.setDname("业务部");
dept.setLoc("山西");
deptService.saveDept(dept);
}
显示除0异常,但是第一条在数据库中插入并没有业务回滚
5.4 开启事务管理器
<!-- 开启spring事务 -->
<!-- 数据事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 启用spring的事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
5.5 编写业务接口实现类(添加事务管理—在业务类添加事务注解(表明在类所有的方法都会使用事务管理,也可以加在单个类的方法上))
@Service("deptService")
@Transactional
public class DeptServiceImpl implements DeptService {
//注入mapper对象
@Resource
private DeptMapper deptMapper;
@Override
public void saveDept(Dept dept) {
deptMapper.saveDept(dept);
int i = 100/0;
deptMapper.saveDept(dept);
}
}
5.6 编写测试类(添加事务管理)
@Test
public void test() {
//加载spring配置
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取对象
DeptService deptService = (DeptService) ac.getBean("deptService");
//调用方法
Dept dept = new Dept();
dept.setDeptno(005);
dept.setDname("业务部");
dept.setLoc("山西");
deptService.saveDept(dept);
}
显示除0异常,两条数据均没有插入数据库中,实现事务的回滚,事务管理成功
三、整合SpringMVC
-
导入springMVC的jar包
-
配置web.xml文件
2.1 启动spring,加载applicationContext.xml【启动监听器】(ContextLoaderListener)
<!-- 启动spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
①ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。
②默认的路径是"/WEB-INF/applicationContext.xml
<!-- 修改路径 -->
//如果applicationContext.xml配置文件存放在WEB-INF下面
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext*.xml</param-value>
</context-param>
//如果applicationContext.xml配置文件存放在src目录下
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
2.2 启动springMVC,加载spring-mvc.xml
<!-- 启动springMVC -->
<!-- DispatcherSevlet负责将请求分发,所有的请求都有经过它来统一分发 -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 参数:读取spring-mvc.xml文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
配置SpringMVC.xml
3.1 扫描controller所在的包
<!-- 扫描controller所在的包 -->
<context:component-scan base-package="cn.ssm.controller"></context:component-scan>
3.2 加载注解驱动
mvc:annotation-driven</mvc:annotation-driven>
3.3 配置视图解析器
<!-- 视图解析器:简化controller类编写的视图路径 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
注意“/”的位置以及数量 /WEB-INF/jsp
编写controller
@Controller
@RequestMapping("/dept")
public class DeptController {
@RequestMapping("/test")
public String test() {
return "test";
}
}
编写页面展示(网址:http://localhost:8888/test_ssm/dept/test.action)
测试springmvc是否可用ssm框架的步骤:
-
创建entity类
-
创建entity的mapper接口EntityMapper.java
-
创建mapper接口的sql映射文件EntityMapper.xml
-
创建applicationContext.xml配置文件【①读取db.properties文件 ②配置JDBC数据源
③创建sqlSessionFactory对象】 -
扫描mapper接口包 DeptMapper ——> deptMapper
*此时使用 二(4)测试类可以对数据库进行操作【】
-
编写业务层接口EntityService.java
-
先在applicationContext.xml中配置IOC注解的扫描
-
编写业务层接口实现类EntityServiceImpl.java,并注解@service
-
开启spring事务 数据事务管理器和spring事务注解(transactionManager)
*此时使用 二(5.6)测试类可以对数据库进行操作,并可以进行事务管理
-
在web.xml中配置上下文监听器,并在web.xml中修改applicationContext.xml的位置
-
启动springmvc(编写servlet【DispatcherSevlet】)
-
编写配置spring-mvc.xml文件(①扫描controller所在的包
②加载注解驱动器(annotation-driven)③配置视图解析器(InternalResourceViewResolver)) -
编写控制层(①@controller控制器层注解 ②@RequestMapping地址映射注解) 编写简单jsp文件进行测试
-
SSM整合(客户的添加)
-
在controller中添加了两个方法
//注入业务对象(切记添加注入的注解)
@Resource
private DeptService deptService;
/**
* 跳转到input.jsp页面
*/
@RequestMapping("/input")
public String input() {
return "input";
}
/**
* 保存客户
*/
@RequestMapping("/save")
public String save(Dept dept) {
deptService.saveDept(dept);
return "succ";
}
-
编写input.jsp录入界面
-
编写succ.jsp转入页面
此时会出现一个问题,那就是中文数据乱码问题,传入数据库的编码格式不是按照UTF-8进行输入 在web.xml进行编码过滤器的编写
<!-- 配置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>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!-- 表示对所有的请求都拦截 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
列表的展示
mapper接口
/**
* 查询所有的数据
*/
public List<Dept> findAll();
sql映射文件
<!-- 查询所有数据 -->
<select id="findAll" resultType="cn.ssm.po.Dept">
select deptno,dname,loc from dept
</select>
Service
/**
- 查询所有数据
*/
public List<Dept> findAll();
ServiceImpl实现类
//注入接口对象
@Resource
private DeptService deptService;
@Override
public List<Dept> findAll() {
return deptService.findAll();
}
Controller
//注入service对象
@Resource
private DeptService deptService;
/**
* 查询所有数据,给页面返回json格式数据
* easyui的datagrid组件 ,需要展示json数据,:【{id:1,name:XXX},{id:1,name:XXX}】
* easyui的datagrid组件有分页的功能,需要接受json格式{total:总计}
*/
@RequestMapping("/list")
@ResponseBody //用于转换对象为json
public List<Dept> list(){
List<Dept> list = deptService.findAll();
return list;
}
页面(.jsp)