前兩篇我們已經學習了JDBC的執行流程,我們也嘗試了抽取公共方法的方式,減少代碼冗餘和複雜度,但是還是很不滿意,那麼今天我們就學習一下Mybatis,看看他是怎麼封裝,怎麼運行,怎麼實現的。學習之前,我們先來體驗一把,就好比你買了一輛跑車,肯定是先飈幾下,然後好奇它是怎麼運作的,每個組件之間又是怎麼協作的,再其次就要考慮怎麼去改裝它,所以我們今天的任務就是先結合Springboot把Mybatis運行起來,看看效果。
我們看定義配置文件,主要是數據的配置和 mybatis的簡單配置,後期mybatis的複雜配置會一一道來
# 配置服務器信息
server:
port: 8080
# 配置數據庫相關信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://192.168.31.33:3306/test?useUnicode=true&characterEncoding=utf-8
# 配置mybatis
mybatis:
# 設置別稱
type-aliases-package: com.lwl.mybatis.day**
# 配置mapper文件
mapper-locations: classpath:mapper/**/*.xml
我們再定義一個Role類,來實現數據庫映射,BaseModel類在之前已經有複用了,如果不清楚可以查看前一篇
/**
* @description: 角色信息
* @author :lwl
* @date :2020/6/25 11:12
* @version: 1.0.0
*/
@Data
@Accessors(chain = true)
public class Role extends BaseModel {
private String name;
private String remark;
@Override
public String toString() {
return "Role{" +
"name='" + name + '\'' +
", remark='" + remark + '\'' +
"} " + super.toString();
}
}
有了角色類之後,我們要定義接口,及它的實現類,都是比較簡單的增刪改查
import java.util.List;
public interface IRoleService {
int insert(Role role);
int update(Role role);
int delOne(long id);
Role findOne(long id);
List<Role> list();
}
@Service
public class RoleServiceImpl implements IRoleService {
@Resource
private RoleMapper roleMapper;
@Override
public int insert(Role role) {
return roleMapper.insert(role);
}
@Override
public int update(Role role) {
return roleMapper.update(role);
}
@Override
public int delOne(long id) {
return roleMapper.delOne(id);
}
@Override
public Role findOne(long id) {
return roleMapper.findOne(id);
}
@Override
public List<Role> list() {
return roleMapper.list();
}
}
Role的接口實現類中有一個RoleMapper接口類,這個類就是會操作數據庫的關鍵,是通過代理模式,具體我們後期慢慢講
public interface RoleMapper {
int insert(Role role);
int update(Role role);
int delOne(long id);
Role findOne(long id);
List<Role> list();
}
代碼都已經寫完了,我們就要再寫一個sql語句的mapper.xml文件,將我們要運行的sql寫在裏面,通過註解的方式也可以實現,不過爲了後期維護和優化,複雜的sql建議還是寫在mapper.xml中,比如動態SQL、多表級聯查詢。
<?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.lwl.mybatis.day2.mapper.RoleMapper">
<resultMap id="BaseResultMap" type="com.lwl.mybatis.day2.domain.Role">
<id column="id" property="id"/>
<result column="create_user" property="createUser"/>
<result column="create_time" property="createTime"/>
<result column="modify_user" property="modifyUser"/>
<result column="modify_time" property="modifyTime"/>
<result column="name" property="name"/>
<result column="remark" property="remark"/>
</resultMap>
<insert id="insert" parameterType="com.lwl.mybatis.day2.domain.Role">
insert into role (name, remark, create_time) value (#{name}, #{remark}, now())
</insert>
<delete id="delOne" parameterType="long">
delete from role where id = #{id}
</delete>
<select id="findOne" parameterType="long" resultMap="BaseResultMap">
select * from role where id = #{id}
</select>
<select id="list" resultMap="BaseResultMap">
select * from role
</select>
<update id="update" parameterType="Role">
update role set name = #{name} , remark = #{remark}, modify_time = now()
where id = #{id}
</update>
</mapper>
好了,一切準備就緒了,我們再寫一個測試類,讓他們運行起來,看看效果
package com.lwl.mybatis.day2;
import com.lwl.mybatis.day2.domain.Role;
import com.lwl.mybatis.day2.service.IRoleService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
public class RoleTest {
@Autowired
private IRoleService roleService;
@Test
public void addTest() {
Arrays.stream(new int[]{1, 2, 3, 4}).forEach(r->{
Role role = new Role();
role.setName("lwl"+r).setRemark("哈哈哈哈哈 => " + r);
roleService.insert(role);
});
/**
* 運行結果:
* 2020-06-26 12:10:17 | DEBUG | main | com.lwl.mybatis.day2.mapper.RoleMapper.insert | ==>
* Preparing: insert into role (name, remark, create_time) value (?, ?, now())
*
* 2020-06-26 12:10:17 | DEBUG | HikariPool-1 housekeeper | com.zaxxer.hikari.pool.HikariPool |
* HikariPool-1 - Pool stats (total=1, active=1, idle=0, waiting=0)
*
* 2020-06-26 12:10:17 | DEBUG | main | com.lwl.mybatis.day2.mapper.RoleMapper.insert | ==>
* Parameters: lwl1(String), 哈哈哈哈哈 => 1(String)
* 2020-06-26 12:10:17 | DEBUG | main | com.lwl.mybatis.day2.mapper.RoleMapper.insert | <==
*
* Updates: 1
*/
}
@Test
public void delOne() {
int i = roleService.delOne(2);
System.out.println("運行結果:" + (i!=0));
}
@Test
public void update() {
Role role = new Role();
role.setName("噢噢噢噢").setRemark("12311415").setId(3L);
int i = roleService.update(role);
System.out.println("運行結果:" + (i!=0));
}
@Test
public void findOneTest() {
Role one = roleService.findOne(1);
System.out.println(Optional.ofNullable(one).toString());
}
@Test
public void list() {
List<Role> list = roleService.list();
System.out.println("運行結果:");
list.forEach(System.out::println);
/**
* Role{name='lwl1', remark='哈哈哈哈哈 => 1'}
* BaseModel(id=5, createUser=null,createTime=Fri Jun 26 12:10:16 CST 2020, modifyUser=null,modifyTime=null)
* Role{name='lwl2', remark='哈哈哈哈哈 => 2'}
* BaseModel(id=6, createUser=null,createTime=Fri Jun 26 12:10:16 CST 2020, modifyUser=null,modifyTime=null)
* Role{name='lwl3', remark='哈哈哈哈哈 => 3'}
* BaseModel(id=7, createUser=null,createTime=Fri Jun 26 12:10:16 CST 2020, modifyUser=null,modifyTime=null)
* Role{name='lwl4', remark='哈哈哈哈哈 => 4'}
* BaseModel(id=8, createUser=null,createTime=Fri Jun 26 12:10:16 CST 2020, modifyUser=null,modifyTime=null)
*
*/
}
}
如果運行過程中出現找不到RoleMapper這類的時候,請在啓動類上加上mapper的掃描註解,其中@MapperScan 掃描包的範圍不能太大,太大的話會到期其他類被多次注入,這樣又會出去其他問題,比如測試類中的 private IRoleService roleService; 會出現多個
@SpringBootApplication
@MapperScan("com.lwl.mybatis.day2.mapper")
public class LwlMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(LwlMybatisApplication.class, args);
}
}