SpringBoot2.X整合Mybatis+Thymeleaf實現增刪改查(XML版)


在SpringBoot2.0整合mybatis的基礎上,繼續來整合XML版的mybatis,沒有看多注解版可以翻翻我之前發的文章,不過沒看過也不影響XML版本的整合。注解版的整合使用場景個人理解就是比較簡單的單表查詢,當涉及到多表和比較的復雜的SQL語句時就會顯得注解寫SQL比較長,專業術語就是冗余,而在XML版的可以解決這個問題,所以我們在實際開發過程中要根據場景的需求來選擇合適版本mybatis整合

Demo實現的效果如下

在已有SpringBoot2.X整合Mybatis實現增刪改查(注解版)的基礎上,利用單元測試完成增刪改查,同時利用layui后台布局+layui的table組件實現頁面查詢所有學生的數據渲染,可以說是簡單地搭建了一個學生管理系統的布局

Demo整合思路及步驟

整合思路
  1. 實現mybatis的Mapper接口的增刪查改方法,並通過單元測試這四個方法
  2. 增刪查改的方法通過單測后,繼續編寫Service,ServiceImpl和Controller層的業務邏輯
  3. 整合SpringBoot官方推薦的thymeleaf整合layUI
  4. 封裝符合layui組件數據格式的VO對象,並序列化JSON對象輸出到頁面,頁面獲取JSON對象后渲染數據顯示
Demo目錄結構

pom.xml
		<!--SpringBoot 官方推薦的模板引擎-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--SpringBoot Web依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mybatis依賴-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>
        <!--mysql驅動依賴-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

Demo中總共需要引入thymeleaf,web,mybatis,mysql,lombok這五個依賴,lombok是簡化JavaBean書寫的,其他的在具體文件中都有詳細的注釋,放心使用,目的就是簡化和對新手友好

domain層
@Data
@NoArgsConstructor
public class Student {
    private Integer id;
    private String name;
    private Integer age;
}
mapper層
@Mapper
public interface StudentMapper {
	//查詢所有學生
    List<Student> findAllStudent();
	//添加學生
    Integer insertStudent(Student student);
	//更新學生
    Integer updateStudent(Student student);
     //根據ID刪除學生
    Integer deleteStudentById(Integer id);
}

這里需要提醒一下,注意@mapper注解是用來告知mybatis掃描哪個接口來構建SqlSessionFactory,因為我這里只有一個StudentMapper接口,所以我在StudentMapper接口使用@Mapper也可以實現mapper掃描功能,但當XXXMapper接口有多個時候,建議在SpringBoot啟動類使用@MapperScan告知具體的包名,一勞永逸防止出錯

Resources.mapper包下StudentMapper.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="com.luojay.mybatisxml.mapper.StudentMapper">
    <select id="findAllStudent"  resultType="com.luojay.mybatisxml.domain.Student">
        select * from student;
    </select>
    <insert id="insertStudent" parameterType="com.luojay.mybatisxml.domain.Student">
        insert into student(name,age)values(#{name},#{age});
    </insert>
    <update id="updateStudent" parameterType="com.luojay.mybatisxml.domain.Student">
        update student set name=#{name} where id=#{id};
    </update>
    <delete id="deleteStudentById" parameterType="Integer">
        delete from student where id=#{id};
    </delete>
</mapper>
Mapper.xml存放位置注意事項

StudentMapper.xml其實可以放在上面的mapper包,讓SpringBoot啟動的時候就連同StudentMapper接口類一起掃描,但是會帶來一個潛在的問題,Maven在項目打包的時候會將java目錄下的xml資源忽略掉,所以如果StudentMapper.xml放在包下,需要在pom.xml文件中再添加如下配置,避免Maven打包時自動忽略掉XML文件

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
    </resources>
</build>

如果mapper.xml不放在Java目錄下的,還可以放在類路徑下自定義的包,不過需要在配置文件中指定掃描的文件夾位置,本文就是采用這種方式,具體的配置方式如下

#mybatis配置信息
mybatis:
  # 映射文件的路徑
  mapper-locations: classpath:mapper/*.xml
  # 類型別名包配置,只能指定具體的包,多個配置可以使用英文逗號隔開
mapper單元測試
@SpringBootTest
@Transactional
class StudentMapperTest {
    @Autowired
    private StudentMapper studentMapper;
    @Rollback
    @Test
    void findAllStudent() {
        List<Student> studentList = studentMapper.findAllStudent();
        for (Student student:studentList){
            System.out.println(student);
        }
    }
    @Rollback
    @Test
    public void insertStudent(){
        Student student = new Student();
        student.setName("簡書CodeLuoJay");
        student.setAge(23);
        Integer rowResult = studentMapper.insertStudent(student);
        Assertions.assertEquals(1,rowResult);//junit5的新斷言
    }
    @Rollback
    @Test
    public void updateStudent(){
        Student student = new Student();
        student.setId(8);
        student.setName("博客園CodeLuoJay");
        student.setAge(23);
        Integer rowResult = studentMapper.updateStudent(student);
        Assertions.assertEquals(1,rowResult);
    }
    @Rollback
    @Test
    public void deleteStudent(){
        Integer rowResult = studentMapper.deleteStudentById(5);
    }
}

寫完Mapper接口,我一般都會寫一個Mapper的測試類,測試通過后再往service和controller層繼續寫下去,這樣可以快速檢測前面的編碼的邏輯是否正確,新版的Junit5單元測試中不用再寫Runwith(SpringRunner.class),只要寫這個@SpringBootTest 注解即可實現和junit4一樣的效果,@Transactional與@Rollback 注解配合使用,是在測試的時候不污染數據庫,當測試通過后不會往數據庫添加數據,如果需要往數據庫添加數據可以去掉這兩個注解

service層
public interface StudentService {
    /***
     * 查詢所有學生
     * @return
     */
    List<Student> findAllStudent();
}

Service層只寫了一個查詢所有的學生方法,跑通一個方法后,其他的增刪改的方法依葫蘆畫瓢在這里添加就好

service.Impl包
@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentMapper studentMapper;
    @Override
    public List<Student> findAllStudent() {
        return studentMapper.findAllStudent();
    }
}

StudentServiceImpl就是IOC依賴注入StudentMapper,調用StudentMapper的接口方法即可,邏輯很簡單

controlle包
@Controller
public class StudentController {
    @Autowired
    private StudentService studentService;

    // 成功輸出的所有學生結果
    @ResponseBody
    @GetMapping("/getStudents")
    public ResultVO getAllStudents(){
        List<Student> studentList = studentService.findAllStudent();
        return ResultVOUtil.success(studentList);
    }
	// 跳轉到所有學生的列表頁面
    @GetMapping("/list")
    public String index(){
        return "list";
    }
	// 模擬跳轉到后台管理員首頁
    @GetMapping("/admin")
    public String admin(){
        return "admin";
    }
}

StudentController使用@controller配合@ResponseBody 輸出JSON對象數據到頁面,不用@RestController

是因為我在這個類中定義頁面跳轉,當然也可以配置一個視圖解析器來實現頁面跳轉,但這里頁面跳轉不多,所以就偷個懶,在Controller中寫頁面跳轉。 ResultVO是封裝的視圖對象,用於返回存儲實體類對象的數據。ResultVOUtil是封裝兩個設置JSON數據的方法

vo包
@Data
public class ResultVO<T>{
    private String msg;
    private Integer code;
    private T data;//泛型數據
}

這是一個VO:ViewObject對象,封裝這個對象是為了后面輸出JSON對象與LayUI的官方的數據對應格式, 其中data封裝成泛型是為了靈活處理格式,例如List,Map,Object等對象時都可以靈活處理,這里是主要用來存儲從數據查出的List 數據

utils包
public class ResultVOUtil {
    //處理成功返回的對象數據封裝
    public static ResultVO success(Object object){
        ResultVO resultVO = new ResultVO();
        resultVO.setData(object);
        resultVO.setCode(0);
        resultVO.setMsg("success");
        return resultVO;
    }
    //處理成功返回的空對象的數據的封裝
    public static ResultVO success(){
        return success(null);
    }
    //處理錯誤返回的對象數據的封裝
    public static ResultVO error(Integer code,String message){
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(code);
        resultVO.setMsg(message);
        return resultVO;
    }
}

這是一個工具類,生成兩個方法success和error方法,其中重載一個success,data輸出為null時調用,目的是在序列化Json對象時方便調用

templates
<table class="layui-hide" id="demo"></table>
<script src="https://www.layuicdn.com/layui/layui.js" charset="utf-8"></script>
<!-- 注意:如果你直接復制所有代碼到本地,上述js路徑需要改成你本地的 -->
<script>
    layui.use('table', function(){
        var table = layui.table;

        //展示已知數據
        table.render({
            elem: '#demo'
            ,url:'/getStudents'
            ,cols: [
                    [
                        {field:'id',  title: 'id'},
                        {field:'name', title: '用戶名'}
                        ,{field:'age',  title: '年齡'}
                    ]
            ]
        });
    });
</script>

我在templates中放兩個頁面渲染,分別是后台的admin.html和list.html頁面,這兩個頁面的數據渲染都是一樣的原理,利用CDN加速在線引入CSS,JS,完成簡單頁面的渲染,輸出的格式與官方的table組件約定的數據格式一致,就能完成表格渲染。

//官方約定的數據格式
{
  "code": 0,
  "msg": "",
  "data": [{}, {}]
}

//我封裝VO后渲染輸出的JSON對象
{
    "msg": "success",
    "code": 0,//這個屬性是必須要的
    //這個就是上面封裝VO對象的內容
    "data": [
        {
            "id": 1,
            "name": "luojay",
            "age": 20
        },
        {
            "id": 2,
            "name": "bobi8344Student",
            "age": 22
        }
    ]
}

測試結果

頁面渲染內容

利用PostMan測試數據輸出沒問題,便可以進行頁面數據的組裝和渲染了

源碼下載

🔨Github: springboot-mybatis-xml

如果文章對你有幫助,請給個star!

關注我的公眾號可以獲取更多SpringBoot2.0系列內容和學習資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM