-- 创建用户表
CREATE TABLE tb_user(id int primary key auto_increment,username varchar(20) unique,password varchar(32)
);-- 添加数据
INSERT INTO tb_user(username,password) values('zhangsan','123'),('lisi','234');SELECT * FROM tb_user;
public class User {private Integer id;private String username;private String password;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}
}
这里有mybatis驱动和mysql驱动程序的依赖,mysql驱动的版本根据自己电脑上mysql版本决定
org.mybatis mybatis 3.5.5 mysql mysql-connector-java 8.0.31
mysql8.0以上版本要加cj
xml里面&是特殊字符要转义使用&
在mybatis接口方法里面有多个参数的话要加上@Param注解做映射将sql语句里面的#{}参数占位符内的名称和@Param()内的参数相对应
public interface UserMapper {/*** 根据用户名和密码查询用户对象* @param username* @param password* @return*/@Select("select * from tb_user where username = #{username} and password = #{password}")User select(@Param("username") String username,@Param("password") String password);/*** 根据用户名查询用户对象* @param username* @return*/@Select("select * from tb_user where username = #{username}")User selectByUsername(String username);/*** 添加用户* @param user*/@Insert("insert into tb_user values(null,#{username},#{password})")void add(User user);
}
定义如下的表单,action里面的路径要加上虚拟目录
接收登录界面传来的数据,这里使用Parameter通过键来获取值
String username = request.getParameter("username");String password = request.getParameter("password");
调用mybatis
获取sqlsessionFactory对象
(通过mybatis配置文件的输入流构建一个sqlsessionFactory对象)
有点像对着施工图纸完成一座工厂,一座专门用于产出sqlsession的工厂
String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
获取sqlsession对象
像是从工厂里面获取一个产品
SqlSession sqlSession = sqlSessionFactory.openSession();
获取Mapper对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
调用方法
User user = userMapper.select(username, password);
释放资源
sqlSession.close();
汇总代码:
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1. 接收用户名和密码String username = request.getParameter("username");String password = request.getParameter("password");//2. 调用MyBatis完成查询//2.1 获取SqlSessionFactory对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2.2 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.3 获取MapperUserMapper userMapper = sqlSession.getMapper(UserMapper.class);//2.4 调用方法User user = userMapper.select(username, password);//2.5 释放资源sqlSession.close();//获取字符输出流,并设置content typeresponse.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();//3. 判断user释放为nullif(user != null){// 登陆成功writer.write("登陆成功");}else {// 登陆失败writer.write("登陆失败");}}
判断user是否为null
根据查询的不同结果使用response返回不同的响应数据,这里返回的始终所以需要设置字符集为utf-8
//获取字符输出流,并设置content typeresponse.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();//3. 判断user释放为nullif(user != null){// 登陆成功writer.write("登陆成功");}else {// 登陆失败writer.write("登陆失败");}
这里成功使用数据库里面的账号登陆成功输出如下
失败登陆也有如下
定义mapper映射sql语句
在上面mapper接口实现类里面有了
创建一个新的RegisterServlet
和上面的流程机器相似,这里放全代码,以后有机会在来看两眼
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1. 接收用户数据String username = request.getParameter("username");String password = request.getParameter("password");//封装用户对象User user = new User();user.setUsername(username);user.setPassword(password);//2. 调用mapper 根据用户名查询用户对象//2.1 获取SqlSessionFactory对象/* String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);*/SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();//2.2 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.3 获取MapperUserMapper userMapper = sqlSession.getMapper(UserMapper.class);//2.4 调用方法User u = userMapper.selectByUsername(username);//3. 判断用户对象释放为nullif( u == null){// 用户名不存在,添加用户userMapper.add(user);// 提交事务sqlSession.commit();// 释放资源sqlSession.close();}else {// 用户名存在,给出提示信息response.setContentType("text/html;charset=utf-8");response.getWriter().write("用户名已存在");}}
成功输出如下
在LoginServlet和RegisterServlet创建了两次sqlsessionfactory对象,代码重复量极大。
sqlsessionfactory对象都绑定了一个连接池,多个工厂有多个连接池,资源消耗极大。
所以要优化sqlsessionfactory的创建代码
创建工具类
public class SqlSessionFactoryUtils {private static SqlSessionFactory sqlSessionFactory;static {//静态代码块会随着类的加载而自动执行,且只执行一次try {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}public static SqlSessionFactory getSqlSessionFactory(){return sqlSessionFactory;}
}
这里不把sqlsession对象的创建也放进去是因为
最后Servlet里面创建工厂时直接调用方法返回值就可以了
//2.1 获取SqlSessionFactory对象/* String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);*/SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();