SSM(九)使用foreach完成复杂查询

本文深入探讨了MyBatis框架中的高级特性,包括foreach循环的使用,choose、when、otherwise语句的逻辑控制,以及如何处理不同类型的输入参数,如数组、列表和Map,通过具体示例展示了如何构建动态SQL查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、学习目标

掌握foreach的使用

掌握choose(when、otherwise)的使用

理解MyBatis的入参处理机制

二、foreach

迭代一个集合,通常用于in条件

属性:

  • item:表示集合里每一个元素进行迭代时的别名
  • index:迭代过程中的位置,可省略
  • collection:必须指定,指定属性的值

list:入参的单参数类型为List

array:入参是数组

map-key:入参封装成map

  • open:这个语句以什么为开始
  • separator:迭代之间以什么为间隔
  • close:语句以什么结束

三、需求:指定用户角色(1-n个),获取这些用户角色下的用户列表信息

查询SQL与含有in条件

select * from smbms_user where userRole in (参数1, 参数2, 参数3);

使用foreach实现:

参数:用户角色列表

参数类型:

  • 数组
  • list

四、array

UserMapper.java


	/**
	 * 根据用户角色列表,获取该角色列表下用户列表信息
	 * @param roleIds
	 * @return
	 */
	public List<User> getUserByRoleId_foreach_array(Integer[] roleIds);

UserMapper.xml


	<resultMap type="user" id="userMapByRole">
		<id property="id" column="id"/>
		<result property="userCode" column="userCode"/>
		<result property="userName" column="userName"/>
	</resultMap>
	<select id="getUserByRoleId_foreach_array" resultMap="userMapByRole">
		select * from smbms_user where userRole in
		<foreach collection="array" item="roleIds" open="(" separator="," close=")">
			#{roleIds}
		</foreach>
	</select>

UserMapperTest.java


	@Test
	public void testGetUserByRoleId_foreach_array() {
		List<User> userList = new ArrayList<User>();
		SqlSession sqlSession = null;
		Integer[] roleIds = {2,3};
		try {
			sqlSession = MyBatisUtil.createSqlSession();
			userList = sqlSession.getMapper(UserMapper.class).getUserByRoleId_foreach_array(roleIds);
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		for(User _user:userList) {
			logger.debug("testGetUserByRoleId_foreach_array userCode: " + _user.getUserCode()
					+ "and userName: " + _user.getUserName());
		}
	}

五、list

UserMapper.java

public List<User> getUserByRoleId_foreach_list(List<Integer> roleList);

UserMapper.xml

<resultMap type="user" id="userMapByRole">
		<id property="id" column="id"/>
		<result property="userCode" column="userCode"/>
		<result property="userName" column="userName"/>
	</resultMap>
	<select id="getUserByRoleId_foreach_list" resultMap="userMapByRole">
		select * from smbms_user where userRole in
		<foreach collection="list" item="roleList" open="(" separator="," close=")">
			#{roleIds}
		</foreach>
	</select>

UserMapperTest.java


	@Test
	public void testGetUserByRoleId_foreach_list() {
		List<User> userList = new ArrayList<User>();
		SqlSession sqlSession = null;
		List<Integer> roleList = new ArrayList<Integer>();
		roleList.add(2);
		roleList.add(3);
		try {
			sqlSession = MyBatisUtil.createSqlSession();
			userList = sqlSession.getMapper(UserMapper.class).getUserByRoleId_foreach_list(roleList);
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		for(User _user:userList) {
			logger.debug("testGetUserByRoleId_foreach_list userCode: " + _user.getUserCode()
					+ " and userName: " + _user.getUserName());
		}
	}

六、需求:在上一个例子中,增加一个参数:gender,要求查询出指定性别和用户角色列表下的用户列表。

多参数入参,封装成Map

UserMapper.java

public List<User> getUserByConditionMap_foreach_map(Map<String, Object> conditionMap);

UserMapper.xml


	<resultMap type="user" id="userMapByRole">
		<id property="id" column="id"/>
		<result property="userCode" column="userCode"/>
		<result property="userName" column="userName"/>
	</resultMap>
	<select id="getUserByConditionMap_foreach_map" resultMap="userMapByRole">
		select * from smbms_user where gender=#{gender} and userRole in
		<foreach collection="roleIds" item="roleId" open="(" separator="," close=")">
			#{roleId}
		</foreach>
	</select>

UserMapperTest.java

@Test
	public void testGetUserByConditionMap_foreach_map() {
		List<User> userList = new ArrayList<User>();
		SqlSession sqlSession = null;
		Map<String, Object> conditionMap = new HashMap<String, Object>();
		List<Integer> roleList = new ArrayList<Integer>();
		roleList.add(2);
		roleList.add(3);
		conditionMap.put("gender", 1);
		conditionMap.put("roleIds", roleList);
		try {
			sqlSession = MyBatisUtil.createSqlSession();
			userList = sqlSession.getMapper(UserMapper.class).getUserByConditionMap_foreach_map(conditionMap);
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		for(User _user:userList) {
			logger.debug("testGetUserByRoleId_foreach_list userCode: " + _user.getUserCode()
					+ " and userName: " + _user.getUserName());
		}
	}

七、单参数也可以封装成Map吗?

实际上,MyBatis会把参数封装成Map进行入参

参数名:Map的key

参数值:Map的value

UserMapper.java

public List<User> getUserByRoleId_foreach_map(Map<String, Object> roleMap);

UserMapper.xml

<resultMap type="user" id="userMapByRole">
	<id property="id" column="id"/>
	<result property="userCode" column="userCode"/>
	<result property="userName" column="userName"/>
</resultMap>
<select id="getUserByRoleId_foreach_map" resultMap="userMapByRole">
	select * from smbms_user where userRole in
	<foreach collection="roleKey" item="key" open="(" separator="," close=")">
		#{key}
	</foreach>
</select>

UserMapperTest.java

@Test
	public void testGetUserByRoleId_foreach_map() {
		List<User> userList = new ArrayList<User>();
		SqlSession sqlSession = null;
		Map<String, Object> roleMap = new HashMap<String, Object>();
		List<Integer> roleList = new ArrayList<Integer>();
		roleList.add(2);
		roleList.add(3);
		roleMap.put("roleKey", roleList);
		try {
			sqlSession = MyBatisUtil.createSqlSession();
			userList = sqlSession.getMapper(UserMapper.class).getUserByRoleId_foreach_map(roleMap);
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		for(User _user:userList) {
			logger.debug("testGetUserByRoleId_foreach_list userCode: " + _user.getUserCode()
					+ " and userName: " + _user.getUserName());
		}
	}

八、choose(when、otherwise)

相当于Java中的switch

当有条件满足when时,跳出choose

UserMapper.java

public List<User> getUserList_choose(@Param("userName")String userName,
	 @Param("userCode")String userCode,
	 @Param("userRole")Integer userRole,
	 @Param("creationDate")Date creationDate);

UserMapper.xml

<select id="getUserList_choose" resultType="user">
		select * from smbms_user where 1=1
		<choose>
			<when test="userName != null and userName !=''">
				and userName like CONCAT('%',#{userName},'%')
			</when>
			<when test="userCode !=null and userCode !=''">
				and userCode like CONCAT('%',#{userCode},'%')
			</when>
			<when test="userRole != null">
				and userRole = #{userRole}
			</when>
			<otherwise>
				and YEAR(creationDate) = YEAR(#{creationDate})
			</otherwise>
		</choose>
	</select>

UserMapperTest.java

@Test
	public void testGetUserList_choose() {
		List<User> userList = new ArrayList<User>();
		SqlSession sqlSession = null;
		String userName = "";
		String userCode = "";
		Integer userRole = 1;
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date creationDate = format.parse("2018-1-1");
			sqlSession = MyBatisUtil.createSqlSession();
			userList = sqlSession.getMapper(UserMapper.class).getUserList_choose(userName, userCode, userRole, creationDate);
		} catch (ParseException e) {
			e.printStackTrace();
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		for(User _user:userList) {
			logger.debug("testGetUserByRoleId_foreach_list userCode: " + _user.getUserCode()
					+ " and userName: " + _user.getUserName()
					+ " and userRole: " + _user.getUserRole()
					+ " and creationDate: " + _user.getCreationDate());
		}
	}

 

<think>根据你的要求,我将为你设计一个使用SSM(Spring+SpringMVC+MyBatis)框架的简易记事本应用。这个应用将实现基本的增删改查功能。由于代码量较大,我将分步骤进行说明,并提供关键代码。###项目结构```src├──main│├──java││└──com││└──example││└──notebook││├──controller│││└──NoteController.java││├──dao│││└──NoteMapper.java││├──entity│││└──Note.java││├──service│││├──NoteService.java│││└──impl│││└──NoteServiceImpl.java││└──config││└──AppConfig.java(可选,使用Java配置类)│├──resources││├──spring│││├──spring-dao.xml(MyBatis配置)│││├──spring-service.xml(Service层配置)│││└──spring-mvc.xml(SpringMVC配置)││├──mybatis│││└──mapper│││└──NoteMapper.xml││├──jdbc.properties││└──log4j.properties(日志配置)│└──webapp│├──WEB-INF││└──web.xml│└──index.jsp```###步骤1.**创建实体类(Note.java)**2.**创建数据访问层(Mapper接口和XML文件)**3.**创建服务层(Service接口和实现类)**4.**创建控制器(Controller)**5.**配置Spring、SpringMVC和MyBatis**6.**创建视图(JSP页面)**###1.实体类(Note.java)```javapackagecom.example.notebook.entity;importjava.util.Date;publicclassNote{privateIntegerid;privateStringtitle;privateStringcontent;privateDatecreateTime;privateDateupdateTime;//省略getter和setter//省略toString}```###2.数据访问层**NoteMapper.java(接口)**```javapackagecom.example.notebook.dao;importcom.example.notebook.entity.Note;importjava.util.List;publicinterfaceNoteMapper{intinsert(Notenote);intdeleteById(Integerid);intupdate(Notenote);NoteselectById(Integerid);List<Note>selectAll();}```**NoteMapper.xml**```xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="com.example.notebook.dao.NoteMapper"><resultMapid="BaseResultMap"type="com.example.notebook.entity.Note"><idcolumn="id"property="id"jdbcType="INTEGER"/><resultcolumn="title"property="title"jdbcType="VARCHAR"/><resultcolumn="content"property="content"jdbcType="VARCHAR"/><resultcolumn="create_time"property="createTime"jdbcType="TIMESTAMP"/><resultcolumn="update_time"property="updateTime"jdbcType="TIMESTAMP"/></resultMap><sqlid="Base_Column_List">id,title,content,create_time,update_time</sql><insertid="insert"parameterType="Note"useGeneratedKeys="true"keyProperty="id">INSERTINTOnote(title,content,create_time,update_time)VALUES(#{title},#{content},now(),now())</insert><deleteid="deleteById"parameterType="Integer">DELETEFROMnoteWHEREid=#{id}</delete><updateid="update"parameterType="Note">UPDATEnoteSETtitle=#{title},content=#{content},update_time=now()WHEREid=#{id}</update><selectid="selectById"parameterType="Integer"resultMap="BaseResultMap">SELECT<includerefid="Base_Column_List"/>FROMnoteWHEREid=#{id}</select><selectid="selectAll"resultMap="BaseResultMap">SELECT<includerefid="Base_Column_List"/>FROMnote</select></mapper>```###3.服务层**NoteService.java(接口)**```javapackagecom.example.notebook.service;importcom.example.notebook.entity.Note;importjava.util.List;publicinterfaceNoteService{intaddNote(Notenote);intdeleteNote(Integerid);intupdateNote(Notenote);NotegetNoteById(Integerid);List<Note>getAllNotes();}```**NoteServiceImpl.java(实现类)**```javapackagecom.example.notebook.service.impl;importcom.example.notebook.dao.NoteMapper;importcom.example.notebook.entity.Note;importcom.example.notebook.service.NoteService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importjava.util.List;@ServicepublicclassNoteServiceImplimplementsNoteService{@AutowiredprivateNoteMappernoteMapper;@OverridepublicintaddNote(Notenote){returnnoteMapper.insert(note);}@OverridepublicintdeleteNote(Integerid){returnnoteMapper.deleteById(id);}@OverridepublicintupdateNote(Notenote){returnnoteMapper.update(note);}@OverridepublicNotegetNoteById(Integerid){returnnoteMapper.selectById(id);}@OverridepublicList<Note>getAllNotes(){returnnoteMapper.selectAll();}}```###4.控制器(NoteController.java)```javapackagecom.example.notebook.controller;importcom.example.notebook.entity.Note;importcom.example.notebook.service.NoteService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Controller;importorg.springframework.ui.Model;importorg.springframework.web.bind.annotation.*;importjava.util.List;@Controller@RequestMapping("/note")publicclassNoteController{@AutowiredprivateNoteServicenoteService;@GetMapping("/list")publicStringlistNotes(Modelmodel){List<Note>notes=noteService.getAllNotes();model.addAttribute("notes",notes);return"noteList";}@GetMapping("/add")publicStringaddNoteForm(Modelmodel){model.addAttribute("note",newNote());return"addNote";}@PostMapping("/add")publicStringaddNoteSubmit(@ModelAttributeNotenote){noteService.addNote(note);return"redirect:/note/list";}@GetMapping("/edit/{id}")publicStringeditNoteForm(@PathVariableIntegerid,Modelmodel){Notenote=noteService.getNoteById(id);model.addAttribute("note",note);return"editNote";}@PostMapping("/edit")publicStringeditNoteSubmit(@ModelAttributeNotenote){noteService.updateNote(note);return"redirect:/note/list";}@GetMapping("/delete/{id}")publicStringdeleteNote(@PathVariableIntegerid){noteService.deleteNote(id);return"redirect:/note/list";}}```###5.配置文件**spring-dao.xml(MyBatis配置)**```xml<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--配置数据库连接池--><context:property-placeholderlocation="classpath:jdbc.properties"/><beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource"><propertyname="driverClassName"value="${jdbc.driver}"/><propertyname="url"value="${jdbc.url}"/><propertyname="username"value="${jdbc.username}"/><propertyname="password"value="${jdbc.password}"/></bean><!--配置SqlSessionFactory--><beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean"><propertyname="dataSource"ref="dataSource"/><propertyname="mapperLocations"value="classpath:mybatis/mapper/*.xml"/></bean><!--配置Mapper扫描器--><beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer"><propertyname="basePackage"value="com.example.notebook.dao"/><propertyname="sqlSessionFactoryBeanName"value="sqlSessionFactory"/></bean></beans>```**spring-service.xml(Service层配置)**```xml<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--扫描service包,使用注解配置--><context:component-scanbase-package="com.example.notebook.service"/></beans>```**spring-mvc.xml(SpringMVC配置)**```xml<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--扫描controller包,使用注解--><context:component-scanbase-package="com.example.notebook.controller"/><!--开启注解驱动--><mvc:annotation-driven/><!--静态资源处理--><mvc:resourcesmapping="/static/**"location="/static/"/><!--视图解析器--><beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver"><propertyname="prefix"value="/WEB-INF/views/"/><propertyname="suffix"value=".jsp"/></bean></beans>```**web.xml**```xml<!DOCTYPEweb-appPUBLIC"-//SunMicrosystems,Inc.//DTDWebApplication2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><display-name>ArchetypeCreatedWebApplication</display-name><!--配置Spring--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/spring-*.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!--配置SpringMVC--><servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>```**jdbc.properties**```propertiesjdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/notebook?useUnicode=true&characterEncoding=utf8jdbc.username=rootjdbc.password=123456```###6.视图(JSP页面)**noteList.jsp(列表页面)**```jsp<%@pagecontentType="text/html;charset=UTF-8"language="java"%><%@taglibprefix="c"uri="http://java.sun.com/jsp/jstl/core"%><html><head><title>NoteList</title></head><body><h1>NoteList</h1><tableborder="1"><tr><th>ID</th><th>Title</th><th>Content</th><th>CreateTime</th><th>UpdateTime</th><th>Actions</th></tr><c:forEachitems="${notes}"var="note"><tr><td>${note.id}</td><td>${note.title}</td><td>${note.content}</td><td>${note.createTime}</td><td>${note.updateTime}</td><td><ahref="/note/edit/${note.id}">Edit</a><ahref="/note/delete/${note.id}">Delete</a></td></tr></c:forEach></table><ahref="/note/add">AddNote</a></body></html>```**addNote.jsp(添加页面)**```jsp<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>AddNote</title></head><body><h1>AddNote</h1><formaction="/note/add"method="post">Title:<inputtype="text"name="title"><br>Content:<textareaname="content"></textarea><br><inputtype="submit"value="Submit"></form></body></html>```**editNote.jsp(编辑页面)**```jsp<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>EditNote</title></head><body><h1>EditNote</h1><formaction="/note/edit"method="post"><inputtype="hidden"name="id"value="${note.id}">Title:<inputtype="text"name="title"value="${note.title}"><br>Content:<textareaname="content">${note.content}</textarea><br><inputtype="submit"value="Submit"></form></body></html>```###数据库表结构```sqlCREATETABLE`note`(`id`int(11)NOTNULLAUTO_INCREMENT,`title`varchar(255)DEFAULTNULL,`content`text,`create_time`timestampNOTNULLDEFAULTCURRENT_TIMESTAMP,`update_time`timestampNOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,PRIMARYKEY(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8;```###运行说明1.创建数据库`notebook`,并执行上面的建表语句。2.修改`jdbc.properties`中的数据库连接信息。3.将项目部署到Tomcat等Servlet容器中运行。###注意事项-确保所有依赖的jar包已正确引入(Spring、SpringMVC、MyBatis、数据库驱动等)。-配置文件的路径和名称需要与代码中的配置一致。###相关技术点解释-**Spring**:用于管理Bean和依赖注入。-**SpringMVC**:处理Web请求和视图解析。-**MyBatis**:操作数据库的持久层框架。-**JSP**:视图层技术,用于展示数据。###可能遇到的问题1.**数据库连接失败**:检查`jdbc.properties`配置是否正确,数据库服务是否启动。2.**MyBatis映射文件未找到**:检查`spring-dao.xml`中`mapperLocations`的配置路径是否正确。3.**请求404**:检查控制器中的`@RequestMapping`和JSP页面中的链接地址是否匹配。希望这个简易记事本能帮助你理解SSM框架的基本使用。如果有任何问题,请随时提问。§§相关问题§§:1.在SSM框架中,Spring、SpringMVC和MyBatis分别扮演什么角色?2.如何在MyBatis中实现动态SQL?3.Spring中的依赖注入有哪些方式?4.如何优化SSM框架的性能?</think>### 简易记事本实现(SSM框架) #### 1. 项目结构 ``` src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── example/ │ │ ├── controller/ # 控制器 │ │ ├── entity/ # 实体类 │ │ ├── dao/ # 数据访问层 │ │ ├── service/ # 服务层 │ │ └── config/ # 配置类 │ ├── resources/ │ │ ├── mapper/ # MyBatis映射文件 │ │ ├── spring/ # Spring配置 │ │ └── application.properties # 数据库配置 │ └── webapp/ │ ├── WEB-INF/ │ │ └── views/ # JSP视图 │ └── index.jsp pom.xml # Maven依赖 ``` #### 2. 核心代码实现 **实体类 (Note.java)** ```java package com.example.entity; import java.util.Date; public class Note { private Integer id; private String title; private String content; private Date createTime; private Date updateTime; // 省略getter/setter } ``` **Mapper接口 (NoteMapper.java)** ```java package com.example.dao; import com.example.entity.Note; import java.util.List; public interface NoteMapper { int insert(Note note); int deleteById(Integer id); int update(Note note); Note selectById(Integer id); List<Note> selectAll(); } ``` **Mapper映射文件 (NoteMapper.xml)** ```xml <?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="com.example.dao.NoteMapper"> <insert id="insert" parameterType="Note" useGeneratedKeys="true" keyProperty="id"> INSERT INTO note(title, content, create_time) VALUES(#{title}, #{content}, now()) </insert> <select id="selectById" resultType="Note"> SELECT * FROM note WHERE id = #{id} </select> <select id="selectAll" resultType="Note"> SELECT * FROM note ORDER BY create_time DESC </select> <update id="update" parameterType="Note"> UPDATE note SET title = #{title}, content = #{content}, update_time = now() WHERE id = #{id} </update> <delete id="deleteById"> DELETE FROM note WHERE id = #{id} </delete> </mapper> ``` **Service接口 (NoteService.java)** ```java package com.example.service; import com.example.entity.Note; import java.util.List; public interface NoteService { void saveNote(Note note); void deleteNote(Integer id); void updateNote(Note note); Note getNoteById(Integer id); List<Note> getAllNotes(); } ``` **ServiceImpl实现类** ```java package com.example.service.impl; import com.example.dao.NoteMapper; import com.example.entity.Note; import com.example.service.NoteService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class NoteServiceImpl implements NoteService { @Autowired private NoteMapper noteMapper; @Override public void saveNote(Note note) { noteMapper.insert(note); } @Override public void deleteNote(Integer id) { noteMapper.deleteById(id); } @Override public void updateNote(Note note) { noteMapper.update(note); } @Override public Note getNoteById(Integer id) { return noteMapper.selectById(id); } @Override public List<Note> getAllNotes() { return noteMapper.selectAll(); } } ``` **Controller控制器 (NoteController.java)** ```java package com.example.controller; import com.example.entity.Note; import com.example.service.NoteService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; @Controller @RequestMapping("/note") public class NoteController { @Autowired private NoteService noteService; // 显示所有笔记 @GetMapping("/list") public String listNotes(Model model) { model.addAttribute("notes", noteService.getAllNotes()); return "noteList"; } // 添加笔记表单 @GetMapping("/add") public String addForm() { return "addNote"; } // 保存笔记 @PostMapping("/save") public String saveNote(Note note) { noteService.saveNote(note); return "redirect:/note/list"; } // 编辑笔记 @GetMapping("/edit/{id}") public String editForm(@PathVariable Integer id, Model model) { model.addAttribute("note", noteService.getNoteById(id)); return "editNote"; } // 删除笔记 @GetMapping("/delete/{id}") public String deleteNote(@PathVariable Integer id) { noteService.deleteNote(id); return "redirect:/note/list"; } } ``` #### 3. 关键配置 **Spring配置 (spring-config.xml)** ```xml <!-- 组件扫描 --> <context:component-scan base-package="com.example" /> <!-- MyBatis配置 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:mapper/*.xml" /> </bean> <!-- Mapper扫描 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.example.dao" /> </bean> <!-- 事务管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> ``` **数据库配置 (application.properties)** ```properties # MySQL配置 jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/notebook?useSSL=false&serverTimezone=UTC jdbc.username=root jdbc.password=123456 # MyBatis配置 mybatis.type-aliases-package=com.example.entity ``` #### 4. 视图层(JSP示例) **noteList.jsp** ```jsp <%@ page contentType="text/html;charset=UTF-8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>笔记列表</title> </head> <body> <h1>我的笔记</h1> <a href="/note/add">添加新笔记</a> <table border="1"> <tr> <th>ID</th> <th>标题</th> <th>创建时间</th> <th>操作</th> </tr> <c:forEach items="${notes}" var="note"> <tr> <td>${note.id}</td> <td>${note.title}</td> <td>${note.createTime}</td> <td> <a href="/note/edit/${note.id}">编辑</a> <a href="/note/delete/${note.id}">删除</a> </td> </tr> </c:forEach> </table> </body> </html> ``` #### 5. 数据库表结构 ```sql CREATE TABLE `note` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `title` VARCHAR(100) NOT NULL, `content` TEXT NOT NULL, `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME ON UPDATE CURRENT_TIMESTAMP ); ``` ### 实现要点说明 1. **分层架构**: - Controller:处理HTTP请求,调用Service - Service:业务逻辑层,处理核心功能 - DAO/Mapper:数据库操作层 - Entity:数据模型 2. **依赖注入**: - 使用`@Autowired`实现Service和Mapper的自动装配 - 通过Spring的IoC容器管理Bean生命周期 3. **事务管理**: - 使用`DataSourceTransactionManager`声明式事务管理 - 默认在Service层方法上开启事务 4. **RESTful设计**: - 使用`@GetMapping`/`@PostMapping`区分请求类型 - 路径变量`@PathVariable`获取资源ID 5. **MyBatis优化**: - `useGeneratedKeys`获取自增主键 - 动态SQL处理复杂查询(示例未展示) ### 常见问题解决 **问题1:数据库连接失败** - **原因**:配置错误或驱动不匹配 - **解决**: ```properties # 使用正确驱动类 jdbc.driver=com.mysql.cj.jdbc.Driver # 添加时区参数 jdbc.url=jdbc:mysql://localhost:3306/db?serverTimezone=UTC ``` **问题2:404页面未找到** - **原因**: - 控制器扫描未配置 - 视图解析器路径错误 - **解决**: ```xml <!-- 在spring-mvc.xml中添加 --> <mvc:annotation-driven /> <context:component-scan base-package="com.example.controller" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> ``` **问题3:MyBatis映射失效** - **原因**: - XML文件未扫描到 - 命名空间与接口不匹配 - **解决**: ```xml <!-- 确保正确配置mapper位置 --> <property name="mapperLocations" value="classpath:mapper/*.xml" /> ``` ### 运行流程 1. 用户访问 `/note/list` 显示笔记列表 2. 点击"添加"跳转到表单页面 3. 提交表单保存到数据库 4. 编辑/删除操作通过ID定位记录 5. 数据变更后重定向到列表页 ### 技术栈说明 - **Spring**:IoC容器管理和事务控制 - **SpringMVC**:请求分发和视图解析 - **MyBatis**:SQL映射和结果集转换 - **MySQL**:数据持久化存储 - **JSP/JSTL**:视图层数据展示
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值