Spring01 —— Spring概念及快速入门
Spring02 —— Spring配置文件详解和依赖注入
Spring03 —— SpringAPI和在Spring中配置数据源
Spring04 —— Spring的注解开发
Spring05 —— Spring集成Junit
Spring06 —— Spring集成web环境
SpringMVC01 —— SpringMVC简介&快速入门
SpringMVC02 —— SpringMVC的各组件详解
SpringMVC03 —— Spring的请求和响应
Spring07 —— Spring JdbcTemplate的相关操作
在之前我们已经学习了Spring和SpringMVC。Spring的每一层都提供了相应的解决方案,web层有SpringMVC,整体Spring有Spring容器和di依赖注入,我们可以将每一层的bean都交由Spring去产生,dao层有Spring jdbctemplate,所以可以基于上述技术做一个案例小练习。
资料下载地址:
https://pan.baidu.com/s/1HuKBWv94S6Scrs9VzpU-vQ?pwd=itch
提取码:itch
<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.0modelVersion>
<groupId>com.zhougroupId>
<artifactId>spring_ExampleTestartifactId>
<version>1.0-SNAPSHOTversion>
<dependencies>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.32version>
dependency>
<dependency>
<groupId>c3p0groupId>
<artifactId>c3p0artifactId>
<version>0.9.1.2version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.10version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.0.5.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>5.0.5.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>5.0.5.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.0.5.RELEASEversion>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.0.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>javax.servlet.jsp-apiartifactId>
<version>2.2.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.3.1version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.3version>
dependency>
<dependency>
<groupId>commons-logginggroupId>
<artifactId>commons-loggingartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>1.7.7version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.0.5.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>5.0.5.RELEASEversion>
dependency>
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
dependencies>
project>
导入成功!
用户实体类
package com.itch.exercise.domain;
public class User {
private Long id;
private String username;
private String email;
private String password;
private String phoneNum;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", email='" + email + '\'' +
", password='" + password + '\'' +
", phoneNum='" + phoneNum + '\'' +
'}';
}
}
角色实体类
package com.itch.exercise.domain;
public class Role {
private Long id;
private String roleName;
private String roleDesc;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
@Override
public String toString() {
return "Role{" +
"id=" + id +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
'}';
}
}
1、创建log4j配置文件
2、创建jdbc.properties
3、创建applicationContext.xml
在spring的核心配置文件中我们只需要配置数据源和配置jdbc的模板对象
<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"
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.xsd
">
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
bean>
beans>
4、创建spring-mvc.xml
在spring-mvc.xml文件中我们需要配置springMVC的注解驱动、视图解析器、静态资源访问权限的开放
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"/>
<property name="suffix" value=".jsp"/>
bean>
<mvc:default-servlet-handler />
beans>
spring和Spring个mvc想集成到web项目中需要配置web.xml
5、web.xml
在web.xml中配置spring的监听器,springMVC的前端控制器
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring-mvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
需求:点击角色管理展示所有角色信息
思路:
①点击角色管理菜单发送请求到服务器端(修改角色管理菜单的url地址)
②创建RoleController和list()方法
③创建RoleService和list()方法
④创建RoleDao和findAll()方法
⑤使用JdbcTemplate完成查询操作
⑥将查询数据存储到modelAndView中
⑦转发到role-list.jsp页面进行展示
public interface RoleDao {
public List<Role> findAllRole();
}
public class RoleDaoImpl implements RoleDao {
// 通过set注入jdbctemplate
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<Role> findAllRole() {
// 定义sql
String sql = "select * from sys_role";
// 执行sql
List<Role> roleList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Role>(Role.class));
return roleList;
}
}
public interface RoleService {
public List<Role> findAllRole();
}
public class RoleServiceImpl implements RoleService {
// 通过set注入RoleDao
private RoleDao roleDao;
public void setRoleDao(RoleDao roleDao) {
this.roleDao = roleDao;
}
public List<Role> findAllRole() {
return roleDao.findAllRole();
}
}
@Controller
@RequestMapping("/role")
public class RoleController {
// 注入RoleService
@Autowired
private RoleService roleService;
@RequestMapping("/list")
public ModelAndView listRole(){
List<Role> roleList = roleService.findAllRole();
System.out.println(roleList);
ModelAndView modelAndView = new ModelAndView();
// 设置模型
modelAndView.addObject("roleList",roleList);
// 设置视图
modelAndView.setViewName("role-list");
// 返回ModelAndView
return modelAndView;
}
}
修改侧边栏得到请求路径
前端页面数据展示 role-list.jsp
引入jstl
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
配置spring-mvc.xml开启组件扫描
<context:component-scan base-package="com.itch.test.controller" />
配置applicationContext.xml
<bean id="roleDao" class="com.itch.test.dao.impl.RoleDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
bean>
<bean id="roleService" class="com.itch.test.service.impl.RoleServiceImpl">
<property name="roleDao" ref="roleDao" />
bean>
刷新页面
需求:点击新建 创关键一个新的角色
/**
* 添加角色
* @param role
*/
public void saveRole(Role role);
public void saveRole(Role role) {
String sql = "insert into sys_role values(null,?,?)";
jdbcTemplate.update(sql,role.getRoleName(),role.getRoleDesc());
}
/**
* 添加角色
* @param role
*/
public void saveRole(Role role);
public void saveRole(Role role) {
roleDao.saveRole(role);
}
controller层调用service层进行保存 重定向到list进行查询
@RequestMapping("/save")
public String save(Role role){
roleService.saveRole(role);
return "redirect:/role/list";
}
由于是使用post请求方式,所以存在乱码问题,配置全局乱码过滤器
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
需求:点击删除按钮删除该角色
/**
* 删除角色
* @param id 根据id删除角色
*/
public void deleteRole(int id);
public void deleteRole(int id) {
String sql = "delete from sys_role where id = ?";
jdbcTemplate.update(sql,id);
}
/**
* 删除角色
* @param id
*/
public void deleteRole(int id);
public void deleteRole(int id) {
roleDao.deleteRole(id);
}
@RequestMapping("/delete")
public String delete(String id){
int rid = Integer.parseInt(id);
roleService.deleteRole(rid);
return "redirect:/role/list";
}
需求:点击用户管理查询数据库 展示所有用户信息
思路:
①点击用户管理菜单发送请求到服务器端(修改用户管理菜单的url地址)
②创建UserController和list()方法
③创建UserService和list()方法
④创建UserDao和fifindAll()方法
⑤使用JdbcTemplate完成查询操作
⑥将查询数据存储到modelAndView中
⑦转发到user-list.jsp页面进行展示
编码:
public interface UserDao {
/**
* 查询所有用户
* @return
*/
public List<User> findAllUser();
}
public class UserDaoImpl implements UserDao {
// 注入jdbctemplate
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<User> findAllUser() {
String sql = "select * from sys_user";
List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<User>(User.class));
return userList;
}
}
public interface UserService {
/**
* 查找所有用户
* @return
*/
public List<User> findAllUser();
}
public class UserServiceImpl implements UserService {
// 注入userDao
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public List<User> findAllUser() {
return userDao.findAllUser();
}
}
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/list")
public ModelAndView list(){
List<User> userList = userService.findAllUser();
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("userList",userList);
modelAndView.setViewName("user-list");
return modelAndView;
}
}
在spring核心配置文件application.xml中添加如下配置:
<bean id="userDao" class="com.itch.test.dao.impl.UserDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
bean>
<bean id="userService" class="com.itch.test.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao" />
bean>
发现问题:用户具有的角色我们并不能够查出来,所以查询用户的时候关联查询出该用户所具有的所有角色信息,需要完善查询用户的service层代码
所以我们需要在业务层UserService中向每一个User封装角色信息roles
dao层处理简单业务 service层处理复杂业务
【1】给User实体类添加roles属性
【2】在UserService中完善代码
public List<User> findAllUser() {
List<User> userList = userDao.findAllUser();
// 封装每一个user的roles数据
for (User user : userList) {
Long id = user.getId();//获得每个用户的id
// 将id作为参数查询出当前用户对应的具有的角色信息 根据userId查询出roleId 再根据roleId查询出角色信息
List<Role> roles = roleDao.findRolesById(id);
// 将roles设置到user
user.setRoles(roles);
}
return userList;
}
这里我们需要在UserService中也注入roleDao,注意在配置文件中进行相应的注入。
【3】在RoleDao中添加根据id查询角色信息
/**
* 根据id查询角色
* @param id
* @return
*/
public List<Role> findRolesById(Long id);
public List<Role> findRolesById(Long id) {
List<Role> roleList = null;
try {
String sql = "SELECT * FROM sys_role r,sys_user_role ur WHERE ur.`roleId` = r.`id` AND ur.`userId` = ?";
roleList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Role>(Role.class), id);
} catch (DataAccessException e) {
e.printStackTrace();
}
return roleList;
}
【4】修改前端代码
【5】部署测试
新建用户时,点击新建按钮先去到添加用户的页面user-add.jsp,在添加用户页面需要展示可供选择的角色信息,因此来到添加页面时需要查询所有的角色信息并展示。所以第一步需要查询出角色信息而不是直接跳转到新增个用户页面
在之前的角色管理中我们已经写了查询所有角色的dao实现,所以我们只需要使用就行
在userController中新增一个方法,是为了查询角色并展示到页面
@RequestMapping("/saveUserUI")
public ModelAndView saveUserUI(){
ModelAndView modelAndView = new ModelAndView();
List<Role> roleList = roleService.findAllRole();
modelAndView.addObject("roleList",roleList);
modelAndView.setViewName("user-add");
return modelAndView;
}
添加用户,需要向sys_user表中存放数据,也需要向sys_user_role表中存放数据
所以需要接收的参数一个是user 一个是选择的角色id们,添加用户时用户分配的角色信息应存储到中间表sys_user_role表中,需要用户的id,角色的id,而角色的id由前台页面点选的,用户的id应该是在保存操作由mysql主键自动生成的,那如何获取mysql自增的主键值呢?
@RequestMapping("/saveUser")
public String saveUser(User user,Long[] roleIds){
userService.addUser(user,roleIds);
return "redirect:/user/list";
}
public void addUser(User user, Long[] roleIds) {
// 1、向sys_user表中存储数据 该方法的返回值是自增生成的主键id
Long userId = userDao.addUser(user);
// 2、向sys_user_role关系中间表中存储多条数据 映射用户id和角色
userDao.saveUserRoleRelation(userId,roleIds);
}
这里发现在存放数据到sys_user表的时候,由于后续需要使用到自动生成的主键id,所以需要返回自动生成的主键id,那么关键问题就在于怎样返回自动生成的主键id呢?
其实jdbctemplate有一个API可以帮助我们返回生成的主键id,这个API相对比较复杂
通过自定义底层的preparestatement开启返回自动生成的主键id
所以dao层的代码编写如下;
添加用户的dao层操作:
public Long addUser(final User user) {
// 1、创建PrepareStatementCreator
PreparedStatementCreator creator = new PreparedStatementCreator(){
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
// 使用原始的jdbc完成一个preparestatement的创建
String sql = "isnert into sys_user values(?,?,?,?,?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);
preparedStatement.setObject(1,null);
preparedStatement.setString(2,user.getUsername());
preparedStatement.setString(3,user.getEmail());
preparedStatement.setString(4,user.getPassword());
preparedStatement.setString(5,user.getPhoneNum());
return preparedStatement;
}
};
// 2、创建keyHolder
GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(creator,keyHolder);
// 3、通过keyholder获得生成的主键
long userId = keyHolder.getKey().longValue();
return userId;
}
添加用户月角色映射的dao层操作:
public void saveUserRoleRelation(Long userId, Long[] roleIds) {
// 向关系表中保存用户id对应的角色id
for (Long roleId : roleIds) {
jdbcTemplate.update("insert into sys_user_role values(?,?)",userId,roleId);
}
}
需求:点击删除按钮删除该用户
思路:
①点击用户列表的删除按钮,发送请求到服务器端
②编写UserController的del()方法
③编写UserService的del()方法
⑤编写UserDao的delUserRoleRel()方法
⑥跳回当前用户列表页面
完成用户的删除操作,不仅要删除用户表数据,同时需要将用户和角色的关联表数据进行删除
/**
* 删除用户
* @param userId
*/
public void deleteUser(Long userId);
/**
* 删除用户与角色的关系
* @param userId
*/
public void deleteRelation(Long userId);
public void deleteUser(Long userId) {
String sql = "delete from sys_user where id = ?";
jdbcTemplate.update(sql, userId);
}
public void deleteRelation(Long userId) {
String sql = "delete from sys_user_role where userId = ?";
jdbcTemplate.update(sql,userId);
}
public void deleteUser(Long uid);
public void deleteUser(Long uid) {
// 要先删除关系表
userDao.deleteRelation(uid);
// 再删除user表
userDao.deleteUser(uid);
}
@RequestMapping("/delete/{uid}")
public String deleteUser(@PathVariable("uid") Long id){
userService.deleteUser(id);
return "redirect:/user/list";
}