先前参考这位大佬的文章写项目出了很多问题,经过不断修改之后终于项目得以平稳运行了。
以下是我的踩坑记录以及对应的de解决方案(不过有一个问题是解决了但是我不懂深层次理由,对此有理解的友友希望可以帮我解答。)
首先上出现最多最严重以及我没理解报错原理的一个问题。
大概就是我已经定义了sqlsessionFactory的bean,但项目无法识别出来无法创建sqlsessionFactory对象。
解决的方案仅仅是删掉以下代码,大家可以对比一下,上面是正确的,下面是最初我错误的那一版。
classpath*:mybatis/mapper-user.xml
不一致的部分是两版不同,初版是通过mapper-user.xml文件加载SQL语句,而第二版是存在一个userMapper的接口类来加载SQL语句。让人在意的是标了红色不一致的这行代码。
查了一下说法是:
mybatis-config.xml
文件,然后依赖注入进Spring
容器里spring容器里引入mybatis-config,mybatis-config里有Mapper映射文件地址就直接获取了。
但我运行的时候出现了严重的问题
删除这一行并且添加:
通过MapperScannerConfigurer来扫描Dao包里面的mapper接口,动态的将mapper接口进行实例化;
2、并将sqlSessionFactory注入到mapper实例中并自动创建sqlsession。
运行成功!
按理说我原本的配置了config.xml文件,它应该能能够索引到,但是不知道为什么无法创建sqlsession对象还报错没有相关的bean。
接下来是整个项目的流程。
创建项目没啥好说的。
主要是项目结构不要出错,接下来我们先要明确需求——完成登录和注册两个功能,那么就需要登录方法和查询用户的SQL语句和注册方法。
pom文件所需要的依赖:
org.springframework spring-webmvc 4.3.7.RELEASE org.springframework spring-jdbc 4.3.7.RELEASE org.springframework spring-aspects 4.3.7.RELEASE org.mybatis mybatis 3.4.2 org.mybatis mybatis-spring 1.3.1 c3p0 c3p0 0.9.1.2 mysql mysql-connector-java 8.0.28 jstl jstl 1.2 javax.servlet javax.servlet-api 3.0.1 provided junit junit 4.12 com.fasterxml.jackson.core jackson-core 2.9.6 com.fasterxml.jackson.core jackson-annotations 2.9.6 com.fasterxml.jackson.core jackson-databind 2.9.6
准备好tomcat,这里选用的是tomcat8版本,pom文件依赖的版本根据自己实际情况更改。
准备好这些之后,我们要在源文件夹写入相关的类和实现业务。
如果Java文件夹不是蓝色的,前往项目结构-模块,选中自己的项目,在src目录下找到Java目录,选中Java目录然后点击原码,Java就变蓝了,同理resource文件如果没有资源目录标识也是选中resource目录然后点击有跟源码同一栏的Recourse即可。
接下来是准备好实体类在pojo(domain)或者你自己实体类的包下面。
创建实体类步骤很简单,就是访问数据库所需要的字段、关于字段的有参无参构造和getset方法以及根据需要要不要生成toString();
大致这个样子。
一般内容如下;
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/你要连接的数据库名称 jdbc.username=你数据库的用户名 jdbc.password=你访问数据库的密码
为了能方便加载驱动,我们在spring-context.xml文件里面配置bean来获取properties文件的内容
我用的是c3p0,德鲁伊的要用德鲁伊的class。
配置成功你的properties文件应该会变橙色:
login功能对应查找select
注册功能对应增加insert
我们可以在dao层自己创建一个mapper接口类来放置这下SQL语句。如下图所示:
@Mapper
@Component
public interface UserMapper {
//增加用户
@Insert("insert into user (username,password,name) values (#{username},#{password},#{name})")
void insert(@Param("username") String username, @Param("password") String password, @Param("name") String name);
//查询用户
@Select("select * from user where username = #{username} and password=#{password}")
User findAll(@Param("username") String username, @Param("password") String password);
}
也可以编写一个mapper.xml文件,甚至这个文件更好,可以动态抽取SQL语句,大致内容如下:
select * from user
之后就是老流程dao-service-serviceImpl。
@Mapper
@Component
public interface UserMapper {
//增加用户
@Insert("insert into user (username,password,name) values (#{username},#{password},#{name})")
void insert(@Param("username") String username, @Param("password") String password, @Param("name") String name);
//查询用户
@Select("select * from user where username = #{username} and password=#{password}")
User findAll(@Param("username") String username, @Param("password") String password);
}
需要写一个封装类名字自定义来封装我们的数据!千万不能忘记!
package com.test.bean; import org.springframework.stereotype.Component; import java.io.Serializable; /** * 用于封装后端返回前端数据对象 */ @Component public class ResultInfo implements Serializable { private boolean flag;//后端返回结果正常为true,发生异常返回false private Object data;//后端返回结果数据对象 private String errorMsg;//发生异常的错误消息 //无参构造方法 public ResultInfo() { } public ResultInfo(boolean flag) { this.flag = flag; } /** * 有参构造方法 * @param flag * @param errorMsg */ public ResultInfo(boolean flag, String errorMsg) { this.flag = flag; this.errorMsg = errorMsg; } /** * 有参构造方法 * @param flag * @param data * @param errorMsg */ public ResultInfo(boolean flag, Object data, String errorMsg) { this.flag = flag; this.data = data; this.errorMsg = errorMsg; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } }
之后就是编写控制类controller来实现我们的需求。
需要注意的是在我自己后端测试的时候是get方式,需要提交前端是则是post,要理解两种方式的区别。
package com.test.controller;
import com.test.bean.ResultInfo;
import com.test.bean.User;
import com.test.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
@Controller
@RequestMapping(value = "user")
public class DispatcherController {
@Resource
private UserService userService;
@Resource
private ResultInfo resultInfo;
@RequestMapping(value = "/login" ,method = RequestMethod.POST)
@ResponseBody
public ResultInfo login(User user) {
User userAll = userService.findAll(user.getUsername(),user.getPassword(),user.getName());
if (userAll != null ) {
resultInfo.setFlag(true);
resultInfo.setErrorMsg("登录成功");
} else {
resultInfo.setFlag(false);
resultInfo.setErrorMsg("账户名或密码错误");
}
return resultInfo;
}
@RequestMapping(value = "/register" ,method = RequestMethod.POST)
@ResponseBody
public ResultInfo register(String username, String password, String email,String name) {
User name1 = userService.findName(username);
if (name1 != null) {
resultInfo.setFlag(false);
resultInfo.setErrorMsg("用户名已存在");
} else {
userService.insert(username, password, email,name);
resultInfo.setFlag(true);
resultInfo.setErrorMsg("注册成功");
}
return resultInfo;
}
}
监听器和拦截器留在下章说,之前因为拦截器逻辑设计有点问题——比如我设置了一个未登录用户会自动跳转登录用户,正常来说应该是跳转首页,直接变成了一刀切,就无法完成我的注册需求了。