目的
刚学完Mybatis,用一些小项目来巩固练习。
练习1
题目描述
做一个密码验证界面,只需要一点点html和Servlet知识,整个项目使用MVC设计模式,三个包,Entity,Service,Dao。数据库有一张名为user的表,有主键Id,用户名name,密码password。
步骤
准备
1.建表
CREATE TABLE Users(
`id` INT,
`name` VARCHAR(24),
`password` VARCHAR(24),
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO users (`id`,`name`,`password`) VALUES (1,'szw','whh');
2.建立目录结构
建一个j2ee的Maven项目,并且建立如下图的目录结构。
构建Mybatis框架
1.Maven导包
在maven库里搜索Mybatis,选择用的多的版本就好。导入后记得刷新,保证导入。
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
2.mybatis-config.xml
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
environments(环境配置),用于配置默认事务处理机制(默认是JDBC),数据库连接池(默认是POOLED),还有关于连接数据库的配置。可以使用properties文件的形式配置。environments可以配置多套,根据id选择一套。为了练习,配置混用propertis文件和直接配置。
<environments default="user">
<environment id="user">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name='username' value="${username}"/>
<property name="password" value="${password}"/>
<property name="url" value="jdbc:mysql://localhost:3306/share?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
</dataSource>
</environment>
</environments>
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/share?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=root
typeAliases(类型别名),在一些Mybatis配置文件中,有些需要写类的全限定名,但这太复杂,可以通过配置typeAliases来简化。
<typeAliases>
<!--alias的值不区分大小写,一般首字母小写-->
<typeAlias type="com.Entity.User" alias="user"></typeAlias>
</typeAliases>
mappers(映射器),用来绑定所有的Mapper.xml。我的理解,Mybatis-congfig.xml是派出所,而Mapper.xml是个人,每个人的出生都需要报备,这样才能给身份证明。重点注意resource值的书写。
<mappers>
<!--每一个userMapper.xml都需要注册-->
<!--有很多种形式-->
<mapper resource="com/DAO/UserMapper.xml"/>
</mappers>
3.userMapper.xml
配置mapper,配置nameplace来绑定Dao接口。
写Sql语句,为了练习,我们将实体类的变量名与数据库的设置的不同,使用结果集的映射来实现目的。问题:写一个方法,参数是map类型,map里有name和password,返回值为name和password为给定值的User对象。
<?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">
<!--命名空间是为了定位,对应一个Dao接口-->
<mapper namespace="com.DAO.Dao">
<resultMap id="res" type="User">
<result property="pwd" column="password"></result>
</resultMap>
<select id="selecteUser" parameterType="map" resultMap="res">
select * from users where name = #{name} AND password = #{password};
</select>
</mapper>
4.MybatisUtil
SqlSessionFactoryBuilder
这个类是用来生成SqlSessionFactory的,这就是个纯纯的工具人,他会根据Mybatis-config.xml
文件来配置相关参数,然后生成SqlSessionFactory。
SqlSessionFactory
这个比较重要,可以生产SqlSession,我是这样理解的SqlSessionFactory相当于蚂蚁里的蚁后,只有一只,负责生产工兵蚁为她干活,SqlSession就相当于工兵蚁。
SqlSession
出生就是为了完成任务的,可以有好多只,完成就死掉。根据以上模型,就知道这三个对象怎么处理,SqlSessionFactoryBuilder在工具类里被创建,生成SqlSessionFactory,而SqlSession在调用方法时被创建(Service层),用完及时close。
package com.Util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
InputStream inputStream = null;
try {
String resource = "mybatis-config.xml";
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
页面与Servlet
1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<div class="center">
<form action="/DomSharing_war/Login" method="post">
<input type="text" placeholder="请输入用户名" name="username"><br>
<input type="password" placeholder="请输入密码" name="password"><br>
<input type="submit" value="登录">
</form>
<form action="/DomSharing_war/register.html" method="post">
<input type="submit" value="注册">
</form>
</div>
<body>
</body>
</html>
2.servlet
package com.Web;
import com.Service.ServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/Login")
public class Login extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServiceImpl sImpl = new ServiceImpl();
String name = req.getParameter("username");
String password = req.getParameter("password");
Map<String,String> map = new HashMap<String,String>();
map.put("name","szw");
map.put("password","whh");
int result = sImpl.chackPassword(map);
switch (result){
case 1:System.out.println("密码正确"); resp.sendRedirect("success.html"); break;
case 2:System.out.println("用户名不存在");resp.sendRedirect("notFind.html"); break;
case 3:System.out.println("密码错误"); resp.sendRedirect("wrongPassword.html"); break;
}
}
}