初学SpringBoot+mybatis
首先在项目中选择Settings,找到Plugins,搜索spring assistant,这时候应该显示的为空。点击下面的按钮Browse repositories,弹出后选择spring assistant,点击安装就好。
安装好后,重启下Intellij(具体要不要重启,我也不知道),开始新建项目。
创建项目的流程稍后再补。。。。。。。
项目目录结构
先来看一下最近写的demo的目录结构,如下:
CorsConfig: 是用来解决web端跨域问题的,自行百度(忘记哪抄的了…);
domain:用来对应数据库表格的对象;
mapper:对应数据库操作的sql语句;
service:不是很清楚,后续补充;
controler:提供对外访问的接口路劲与传入参数;
application:项目的入口;
mybatis.mapper:用xml的方式写了数据库的操作语句。
接着来看一下主要的这几个类:
一、mapper
1、mapper是一个接口,一种是用注解在方法上写sql语句的方式,例如:
import com.familyTree.shi.domain.FamilyTreeModule;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface FTMapper {
/**
* 查询所有成员信息
* @return
*/
@Select("SELECT * FROM family_tree")
List<FamilyTreeModule> findAll();
/**
* 分页查询
* @param startRow
* @return
*/
@Select("SELECT * FROM family_tree limit #{startRow},20")
List<FamilyTreeModule> findByPage(int startRow);
/**
* 查询总共记录数
* @return
*/
@Select("SELECT COUNT(*) FROM family_tree")
Long findCount();
/**
* 通过姓名查找成员
* @param name
* @return
*/
@Select("SELECT * FROM family_tree WHERE name LIKE \"%\"#{name}\"%\"")
List<FamilyTreeModule> findByName(String name);
}
2、操作数据库的sql语句也可以用xml的方式写入,例如
import com.familyTree.shi.domain.FamilyTreeModule;
import java.util.List;
import java.util.Map;
public interface FT2Mapper {
List<FamilyTreeModule> findByCondition(Map<String, String> map);
int findByConditionCount(Map<String, String> map);
List<FamilyTreeModule> findAll();
}
其中接收多参数的方式,是以map的形式接受的参数,当然也可以用对象的方式接收多参数。
对应的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" >
<!--你接口的包名是com.abc.dao,接口名是NameMapper.java,那么你的mapper.xml的namespace应该是com.abc.dao.NameMapper-->
<mapper namespace="com.familyTree.shi.mapper.FT2Mapper" >
<!--resultMap对应的是表与实体类的映射 - type 数据库表对应的实体类,别名或完整类名都可以-->
<resultMap id="BaseResultMap" type="com.familyTree.shi.domain.FamilyTreeModule" >
<!-- 结果集的主键 -->
<id column="primy_key" property="primy_key" jdbcType="INTEGER" />
<!-- 普通的列 -column 是数据库中字段, property是实体类中字段-->
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="father" property="father" jdbcType="VARCHAR" />
<result column="father_id" property="father_id" jdbcType="INTEGER" />
<result column="generation" property="generation" jdbcType="INTEGER" />
<result column="no" property="no" jdbcType="INTEGER" />
<result column="wife" property="wife" jdbcType="VARCHAR" />
<result column="next_generation" property="next_generation" jdbcType="VARCHAR" />
<result column="story" property="story" jdbcType="INTEGER" />
<result column="remark" property="remark" jdbcType="VARCHAR" />
</resultMap>
<sql id="Base_Column_List">
primy_key,id,name,father,father_id,generation,no,wife,next_generation,story,remark
</sql>
<!--查找符合条件的数据-->
<select id="findByCondition" parameterType="java.util.Map" resultMap="BaseResultMap">
SELECT * FROM family_tree WHERE 1=1
<include refid="conditions"/>
<!--此处传入的类型为string,limit转为int则将#改为$-->
LIMIT ${startRow},20
</select>
<!--查找符合条件的数据条数-->
<select id="findByConditionCount" parameterType="java.util.Map" resultType="java.lang.Integer">
SELECT COUNT(*) FROM family_tree WHERE 1=1
<include refid="conditions"/>
</select>
<!--数据筛查条件 被其他sql引用-->
<sql id="conditions">
<if test="id != null and id != ''">
AND id=#{id}
</if>
<if test="name != null and name != ''">
AND name=#{name}
</if>
<if test="fatherId != null and fatherId != ''">
AND father_id=#{fatherId}
</if>
<if test="fatherName != null and fatherName != ''">
AND father=#{fatherName}
</if>
<if test="generation != null and generation != ''">
AND generation=#{generation}
</if>
</sql>
<!--parameterType(输入类型)、resultType(输出类型)-->
<select id="findAll" resultMap="BaseResultMap">
SELECT * FROM family_tree
</select>
</mapper>
上面的注释也算清楚,自行查阅。
这里有一个问题点,困扰了我半天,这里也提出来:由于多参数查询中的参数是以
Map<String,String>
的方式传入的,当执行sql语句的limit #{startRow},20的时候出了问题,startRow貌似必须为int类型才可以实现,这里纠结了半天,准备用对象的形式传入多参数的时候,找到了一个方法,便是将一直用的#{xx} 改为 ${xx} 即可解决当前的问题,如上例所示。
这里还出现过一个错误,当时写完FTMapper的文件后,忘记修改后缀为.xml,导致接口出问题,一直报错(第一次写项目,坑死了要,不注意就是问题多)。
到此两种sql数据库的操作方式就写完了。
二、service
service就直接上代码吧:
import com.familyTree.shi.domain.FamilyTreeModule;
import com.familyTree.shi.mapper.FT2Mapper;
import com.familyTree.shi.mapper.FTMapper;
import com.familyTree.shi.module.PagingModule;
import com.familyTree.shi.module.ResultModule;
import com.familyTree.shi.service.FTService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class FTServiceImpl implements FTService {
@Autowired
FTMapper ftMapper;
@Autowired
FT2Mapper ft2Mapper;
@Override
public List<FamilyTreeModule> findAll() {
return ft2Mapper.findAll();
}
@Override
public List<FamilyTreeModule> findByPage(int startRow) {
return ftMapper.findByPage(startRow);
}
/**
* 依据条件查询数据
* @param map 条件
* @return
*/
public ResultModule<PagingModule<List<FamilyTreeModule>>> findByCondition(Map<String, String> map){
ResultModule<PagingModule<List<FamilyTreeModule>>> resultModule = new ResultModule<>();
resultModule.setCode("200");
resultModule.setMsg("请求成功");
PagingModule<List<FamilyTreeModule>> pagingModule = new PagingModule<>();
pagingModule.setTotalCount(findByConditionCount(map));
pagingModule.setData(ft2Mapper.findByCondition(map));
resultModule.setData(pagingModule);
return resultModule;
}
/**
* 依据条件查询数据总条数
* @param map 条件
* @return
*/
public int findByConditionCount(Map<String, String> map){
return ft2Mapper.findByConditionCount(map);
}
@Override
public Long findCount() {
return ftMapper.findCount();
}
@Override
public List<FamilyTreeModule> findByName(String name) {
return ftMapper.findByName(name);
}
}
service等以后有了新的理解再说吧,现在不清晰诶。
三、controller
直接看代码:
import com.familyTree.shi.domain.FamilyTreeModule;
import com.familyTree.shi.module.PagingModule;
import com.familyTree.shi.module.ResultModule;
import com.familyTree.shi.service.impl.FTServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/ft")
public class FTController {
@Autowired
private FTServiceImpl ftService;
@RequestMapping("/findAll")
@ResponseBody
public List<FamilyTreeModule> findAll() {
return ftService.findAll();
}
@RequestMapping("/findByPage")
@ResponseBody
public ResultModule<PagingModule<List<FamilyTreeModule>>> findByPage(@RequestParam("page") int page){
return getFTResultModule(page);
}
@RequestMapping("/findByCondition")
@ResponseBody
public ResultModule<PagingModule<List<FamilyTreeModule>>> findByCondition(@RequestParam Map<String, String> map){
return ftService.findByCondition(map);
}
/**
* 获取家谱分页信息
* @param currentPage 查询页码
* @return
*/
ResultModule<PagingModule<List<FamilyTreeModule>>> getFTResultModule(int currentPage){
ResultModule<PagingModule<List<FamilyTreeModule>>> resultModule = new ResultModule<>();
resultModule.setCode("200");
resultModule.setMsg("请求成功");
PagingModule<List<FamilyTreeModule>> pagingModule = new PagingModule<>();
pagingModule.setCurrentPage(currentPage);
pagingModule.setPageSize(20);
pagingModule.setTotalCount(ftService.findCount());
pagingModule.setData(ftService.findByPage(currentPage*20));
resultModule.setData(pagingModule);
return resultModule;
}
@RequestMapping("/findCount")
@ResponseBody
public Long findCount() {
return ftService.findCount();
}
@RequestMapping("/findByName")
@ResponseBody
public List<FamilyTreeModule> findByName(@RequestParam("name") String name) {
return ftService.findByName(name);
}
}
使用了@RequestMapping的注解,接口即可用get又可用post调用,更多的注解,自行查阅。
有了controller后,启动项目,即可调用接口,例如:
localhost:8090/ft/findAll 来查询数据库。
这里的传入参数写了两种,一种是单个参数传入,另一种是map的形式传入,当然还可以直接用对象传参数,直接将传入的参数写为一个对象即可。
四、application
为了使用xml查询数据库,我们还需要在application中写入一个注解(至于这个注解是否能写到其他地方,我还不知道啊),看下代码:
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(basePackages="com.familyTree.shi.mapper")
public class ShiApplication {
public static void main(String[] args) {
SpringApplication.run(ShiApplication.class, args);
}
}
@MapperScan的注解路径对应了我们创建的mapper接口文件的路径。
五、application.yml
最后看一下这个配置文件,我这里都是一些简单的配置,看一下就好:
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/family_tree
username: root
password:
driver-class-name: com.mysql.jdbc.Driver
mybatis:
type-aliases-package: com.familyTree.shi.domain
mapper-locations: classpath:myBatis/mapper/*.xml
server:
port: 8090
servlet:
context-path: /
url对应了我创建的数据库
username 和 password对应了数据库的登录用户名与密码
type-aliases-package对应了与数据库表对应的对象路径
mapper-location对应了数据库操作的mapper文件
post配置了访问的端口号
至此,该准备的已经都准备好了,运行项目后,调用接口,则会返回相应的数据。
第一次写项目(demo,离项目还远,,,),也没少折腾,特此记录一下。
在此感谢下我司后台大神,最近写这点东西也没少问他问题,哈哈,感觉快烦了,不过还好我人缘好。