Java后台应用项目开发 Part 3 - MyBatis 框架的使用
【版本】
当前版本号v20211012
版本 | 修改说明 |
---|---|
v20211012 | 修正 spring-mvc.xml 注释 |
v20211009 | 修正 SqlMapConfig.xml 内容,缺失了一个",新增resource目录相关说明 |
v20210927 | 初始化版本 |
【实验名称】 实验3.1 新建 MyBatis 项目
【实验目的】
- 掌握新建 Maven 项目
- 掌握 MyBatis 框架的开发
【实验环境】
- 内存:至少4G
- 硬盘:至少空余10G
- 操作系统: 64位 Windows系统。
【实验资源】
- IDEA
- Maven 3.6
【实验步骤】
参考实验2.2,新建一个新的 Maven Web 开发项目
MyBatis
。在 POM.xml 文件中加入依赖包的配置。
<dependencies>
<!-- JUnit 框架 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!-- MySQL 连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- MyBatis 包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
</dependencies>
- 在项目下新建目录
src\main\resources\db\migration
,用于存放数据库 SQL 脚本文件。
注意这里 IDEA 显示的
db.migration
,并不是目录名称为db.migration
,而是一个层级目录如下所示。
resources
|- db
|- migration
- 新建2个 SQL 脚本文件。
- 创建新的库和数据库用户脚本
V001__CREATE_DB.sql
,内容如下
create database mobile_shop;
create user 'mshop'@'localhost' identified by 'hudp3ymVq5pMU47h';
create user 'mshop'@'%' identified by 'hudp3ymVq5pMU47h';
grant all on mobile_shop.* to 'mshop'@'localhost';
grant all on mobile_shop.* to 'mshop'@'%';
- 创建用户表的脚本
V002__CREATE_USER.sql
,内容如下
CREATE TABLE `ms_user` (
`user_id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY comment '用户ID',
`username` VARCHAR(50) NOT NULL comment '用户名',
`password` VARCHAR(50) NOT NULL comment '密码'
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
insert into `ms_user` (`username`,`password`) values('zhangsan','123456');
- 启动MySQL,使用 HeidiSQL 连接 MySQL,并依照序号,先后执行以上2个 SQL 脚本文件。正常执行以后,运行以下 SQL 脚本应该能够查询到一条记录。
use mobile_shop;
select * from ms_user;
- 编写以下配置文件。请注意存放的目录路径,没有该目录可以自己创建。
- 数据库连接的配置文件
db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mobile_shop?useUnicode=true&characterEncoding=UTF-8
user=mshop
pwd=hudp3ymVq5pMU47h
- MyBatis 配置文件
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引用db.properties配置文件 -->
<properties resource="db.properties"/>
<environments default="environment">
<environment id="environment">
<!-- JDBC类型:有提交和回滚的设置 -->
<transactionManager type="JDBC" />
<!-- POOLED类型:数据库连接池 -->
<!-- 配置数据库连接信息 -->
<dataSource type="POOLED">
<!-- value的值引用db.properties中的值 -->
<property name="driver" value="${driver}" />
<property name="url" value="${url}"/>
<property name="username" value="${user}" />
<property name="password" value="${pwd}" />
</dataSource>
</environment>
</environments>
<!-- 配置映射文件 -->
<mappers>
<mapper resource="mobileshop/mapper/UserDaoMapper.xml"/>
</mappers>
</configuration>
- UserDao类对应的 MyBatis 映射配置
UserDaoMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="mobileshop.dao.UserDao">
<select id="findAll" resultType="mobileshop.entity.UserEntity">
select * from ms_user
</select>
</mapper>
注意这里 IDEA 显示的
mobileshop.mapper
,并不是目录名称为mobileshop.mapper
,而是一个层级目录如下所示。
resources
|- mobileshop
|- mapper
- 编写以下3个类。请注意存放的目录路径,没有该目录可以自己创建。
- 访问用户表的 DAO 类
UserDao.java
package mobileshop.dao;
import mobileshop.entity.UserEntity;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserDao {
List<UserEntity> findAll();
}
- 装载用户信息的类
UserEntity.java
,注意观察 UserEntity 类与ms_user
表之间,属性和列的对应关系。
package mobileshop.entity;
public class UserEntity {
private Long userId;
private String username;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
- 获取 MyBatis 的 SqlSession 的类
MybatisUtils.java
package mobileshop.utils;
import java.io.InputStream;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MybatisUtils {
//获取SqlSession的方法
public static SqlSession getSqlSession(){
//SqlSessionFactoryBuilder ——> SqlSessionFactory ——> SqlSession
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//加载sqlMapConfig.xml
ClassLoader loader= MybatisUtils.class.getClassLoader();//MybatisUtil:自己写的类都可以
InputStream inStream=loader.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory=builder.build(inStream);
SqlSession session=factory.openSession();
return session;
}
}
- 编写单元测试用例,运行
testFindAll
方法,测试能否正常调用UserDao
的findAll
方法。正常情况下测试用例会通过。
package mobileshop.dao;
import mobileshop.entity.UserEntity;
import mobileshop.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class UserDaoTest {
private SqlSession session;
private UserDao userDao;
@Before
public void beforeTest(){
session=MybatisUtils.getSqlSession();
userDao=session.getMapper(UserDao.class); //生成的一个动态代理
}
@Test
public void testFindAll(){
List<UserEntity> list= userDao.findAll();
assertTrue(list.size()>0);
}
@After
public void closeSession(){
if(session!=null) {
session.commit();//提交更改
session.close();
}
}
}
【实验名称】 实验3.2 开发用户的增删查改功能
【实验目的】
- 掌握 MyBatis 框架增删查改的开发
【实验环境】
- 内存:至少4G
- 硬盘:至少空余10G
- 操作系统: 64位 Windows系统。
【实验资源】
- IDEA
- Maven 3.6
【实验要求】
- 在
UserDao
类新增以下方法。
package mobileshop.dao;
import mobileshop.entity.UserEntity;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserDao {
/**
* 查找所有用户
* @return
*/
List<UserEntity> findAll();
/**
* 按用户名查找用户
* @return
*/
UserEntity findByUserName(String username);
/**
* 按用户名更新用户密码
* @return
*/
int updatePassword(@Param("username")String username,@Param("password")String password);
/**
* 新增用户
* @param ue
* @return
*/
int save(UserEntity ue);
/**
* 根据传入的用户名删除用户
* @param username
* @return
*/
int deleteByUsername(String username);
}
- 测试用例修改如下,该测试用例会测试
UserDao
新增的所有方法。
package mobileshop.dao;
import mobileshop.entity.UserEntity;
import mobileshop.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class UserDaoTest {
private SqlSession session;
private UserDao userDao;
@Before
public void beforeTest(){
session=MybatisUtils.getSqlSession();
userDao=session.getMapper(UserDao.class); //生成的一个动态代理
}
@Test
public void testFindAll(){
List<UserEntity> list= userDao.findAll();
assertTrue(list.size()>0);
}
@Test
/**
* 另一种方法运行findAll
*/
public void testFindAll2(){
List<UserEntity> list= session.selectList("findAll");
assertTrue(list.size()>0);
}
@Test
/**
* 测试 findByUserName 功能
*/
public void testFindByUserName(){
String username="zhangsan";
UserEntity ue=userDao.findByUserName(username);
assertEquals(username,ue.getUsername());
}
@Test
/**
* 另一种方法调用 findByUserName 功能
*/
public void testFindByUserName2(){
String username="zhangsan";
UserEntity ue=session.selectOne("findByUserName",username);
assertEquals(username,ue.getUsername());
}
@Test
/**
* 测试 updatePassword 功能
*/
public void testUpdatePassword(){
int rs=userDao.updatePassword("zhangsan","123456");
assertEquals(1,rs);
}
@Test
/**
* 另一种方法调用 updatePassword 功能
*/
public void testUpdatePassword2(){
Map<String,String> map=new HashMap<>();
map.put("username","zhangsan");
map.put("password","123456");
int rs=session.update("updatePassword",map);
assertEquals(1,rs);
}
@Test
/**
* 测试 save 功能
*/
public void testSave(){
UserEntity u=new UserEntity();
u.setUsername("lisi");
u.setPassword("135790");
int rs=userDao.save(u);
assertEquals(1,rs);
}
@Test
/**
* 另一种方法调用 save 功能
*/
public void testSave2(){
UserEntity u=new UserEntity();
u.setUsername("lisi");
u.setPassword("135790");
int rs=session.insert("save",u);
assertEquals(1,rs);
}
@Test
/**
* 测试 deleteByUsername 功能
*/
public void testDeleteByUsername(){
UserEntity u=new UserEntity();
u.setUsername("wangwu");
u.setPassword("135790");
userDao.save(u);
int rs=userDao.deleteByUsername("wangwu");
assertEquals(1,rs);
}
@Test
/**
* 另一种方法调用 deleteByUsername 功能
*/
public void testDeleteByUsername2(){
UserEntity u=new UserEntity();
u.setUsername("wangwu");
u.setPassword("135790");
userDao.save(u);
int rs=session.delete("deleteByUsername","wangwu");
assertEquals(1,rs);
}
@After
public void closeSession(){
if(session!=null) {
session.commit();//提交更改
session.close();
}
}
}
- 请你根据
UserDao
新增的方法,完善UserDaoMapper.xml
,并且能够让UserDaoTest
所有测试通过。
【实验名称】 实验3.3 集成 MyBatis 框架到 Web 项目
【实验目的】
- 掌握 MyBatis 框架在Web项目中的开发
【实验环境】
- 内存:至少4G
- 硬盘:至少空余10G
- 操作系统: 64位 Windows系统。
【实验资源】
- IDEA
- Maven 3.6
【实验要求】
结合实验2.2和实验3.2,完善真实访问数据库的登录功能。
新建 Maven 项目,项目目录结构如下:
以下为代码提示:
- LoginController.java
package mobileshop.controller;
import mobileshop.entity.UserEntity;
import mobileshop.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
@Autowired
private UserService userService;
@RequestMapping(value = "/login")
public String login(){
return "login";
}
@RequestMapping(value = "/signin")
public String signIn(String username, String password){
//请完善代码
}
}
- UserDao.java
package mobileshop.dao;
import mobileshop.entity.UserEntity;
public interface UserDao {
UserEntity findByUserName(String username);
}
- UserEntity.java
package mobileshop.entity;
public class UserEntity {
private Long userId;
private String username;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
- UserService.java
package mobileshop.service;
import mobileshop.entity.UserEntity;
public interface UserService {
boolean validUserPwd(UserEntity ue);
UserEntity getUserByUsername(String username);
}
- UserServiceImpl.java
package mobileshop.service;
import mobileshop.dao.UserDao;
import mobileshop.entity.UserEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Override
public boolean validUserPwd(UserEntity ue) {
//请完善代码。
}
@Override
public UserEntity getUserByUsername(String username) {
return userDao.findByUserName(username);
}
}
Application.java 同实验2.2
UserDaoMapper.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="mobileshop.dao.UserDao">
<select id="findByUserName" parameterType="string"
resultType="mobileshop.entity.UserEntity">
select * from ms_user where username=#{username}
</select>
</mapper>
db.properties 同实验3.1
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
<!--配置注解扫描-->
<context:component-scan base-package="mobileshop.controller,mobileshop.service"/>
<!-- SpringMVC注解支持 -->
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/html/" />
<property name="suffix" value=".html" />
</bean>
<util:properties id="jdbc" location="classpath:db.properties"/>
<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="#{jdbc.driver}"/>
<property name="url" value="#{jdbc.url}"/>
<property name="username" value="#{jdbc.user}"/>
<property name="password" value="#{jdbc.pwd}"/>
</bean>
<!-- 配置SqlSessionFactoryBean -->
<!-- 可以定义一些属性来指定Mybatis框架的配置信息 -->
<bean id="ssf" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据源,注入连接信息 -->
<property name="dataSource" ref="dbcp"/>
<!-- 用于指定sql定义文件的位置(加classpath从src下找) -->
<property name="mapperLocations"
value="classpath:mobileshop/mapper/*.xml"/>
</bean>
<!-- 配置MapperScannerConfigurer -->
<!-- 按指定包扫描接口,批量生成接口实现对象,id为接口名首字母小写 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定扫描 mobileshop.dao 包下所有接口 -->
<property name="basePackage"
value="mobileshop.dao"/>
<!-- 注入sqlSessionFactory(此句可不写,自动注入sqlSessionFactory) -->
<property name="sqlSessionFactory" ref="ssf"/>
</bean>
</beans>
- web.xml 同实验2.2