NiceLeeのBlog 用爱发电 bilibili~

SpringBoot 踩坑记录(九)- Mybatis 整合笔记

2019-05-20
nIceLee

阅读:


        无论是自己搭也好,用Mybatis 或Hibernate也好,本质上只是一个工具,用来‘擦除’那些繁琐的重复的try…catch…finally…,让开发变得更高效更简洁(Spring AOP牛b。
        当人们发觉这东西好用,更多人用了后,如何用这个东西反而变得比其它更重要。要说这些东西没出现之前就没有解决办法么,当然不。
        相信以前走类似的路子的肯定有,也一定有过自己做插件直接自动批量生成SQL数据库业务代码的,而且还不少,效率并不一定比现在低。
        但是随着新人不断涌入,有些东西门槛更低,更易上手,交付起来也不见得慢,于是便成了主流(开源大法好。
        这似乎看上去是对新手友好,其实该补的课早晚还是要补。当菜鸟变成老菜鸟,当更新更好的工具出现,老菜鸟如果不能有深度的挖掘学习,思考与新菜鸟相比的优势时,除了一堆过时的东西,大概就只剩下经验了吧。
        以下纪录SpringBoot 整合Mybatis的笔记(闲话太多

数据库建表

以Mysql为数据源为例,假设在数据库site建了一个表:

create table t_user(
   id INT(12) NOT NULL AUTO_INCREMENT,
   user_name VARCHAR(60) NOT NULL,
   sex int(3) NOT NULL default 1 check (sex in(1,2)),
   note varchar(256) null,
   PRIMARY KEY (id)
);

ALTER TABLE t_user ADD UNIQUE user_name (user_name);

pom.xml引入依赖

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.0.1</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

application.properties设置

数据库设置,以及mybatis指定mapper.xml和别名扫描路径等

# 数据库
spring.datasource.url=jdbc:mysql://localhost:3306/site?serverTimezone=UTC
spring.datasource.username=xxx
spring.datasource.password=xxx
# mybatis mapper.xml 路径
mybatis.mapper-locations=classpath:mapping/*.xml
mybatis.type-aliases-package=top.nicelee.site.pojo
#mybatis.config-location=
# 调试 top.nicelee.site.dao.UserDao
logging.level.top.nicelee.site.dao.UserDao=DEBUG

SpringBoot设置dao接口扫描配置

@Configuration //该注解表示配置
public class WebConfig {
	...    
	/**
	 * 设置Mybatis 扫描装配
	 * @return
	 */
	@Bean
	public MapperScannerConfigurer mapperScannerConfig() {
		MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
		mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
		mapperScannerConfigurer.setBasePackage("top.nicelee.site.dao"); // 指定扫描包 top.nicelee.*.dao
		mapperScannerConfigurer.setAnnotationClass(Repository.class); // 制定扫描特定的注解类
		return mapperScannerConfigurer;
	}
}

生成pojo

@Alias(value = "user")
public class User {	
	Long id = null;
	String userName = null;
	Integer sex = null;
	String note = null;
	/* Setter + Getter */
}

生成dao接口

package top.nicelee.site.dao;
import top.nicelee.site.pojo.User;
@Repository // 也可以是@Mapper,看个人喜好
public interface UserDao {	
	public User getUserById(Long id);
	public List<User> getUserAll();
	public int insertUser(User user);
	public int updateUser(User user);
	public int saveUser(User user);
	public int deleteUser(Long id);
}

生成dao对应的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="top.nicelee.site.dao.UserDao">
	<select id="getUserAll" resultType="user"> 
		select id, user_name as userName, sex, note from t_user
	</select>
	<select id="getUserById" resultType="user" parameterType="long"> 
		select id, user_name as userName, sex, note from t_user where id= #{id}
	</select>	
	<insert id="insertUser" parameterType="user" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
	  insert into t_user (user_name, sex, note)
	  values (#{userName}, #{sex}, #{note})
	</insert>	
	<update id="updateUser" parameterType="user">
	    update t_user
		<set>
			<if test="id != null and userName != null">
				user_name = #{userName},
			</if>
			<if test="sex != null">
				sex = #{sex},
			</if>
			<if test="note != null">
				note = #{note},
			</if>
		</set>
		<where>
			<if test="id != null">
				id = #{id}
			</if>
			<if test="id == null">
				user_name = #{userName}
			</if>
		</where>
	</update>
	<delete id="deleteUser" parameterType="long">
	  delete from t_user where id = #{id}
	</delete>
	
	<insert id="saveUser" parameterType="user" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
	  insert into t_user
		<trim prefix="(" suffix=")" suffixOverrides=",">
		user_name, 
		<if test="sex != null">sex,</if>
		<if test="note != null">note,</if>
		</trim>
	    <trim prefix="values (" suffix=")" suffixOverrides=",">
	    #{userName},
	    <if test="sex != null">#{sex},</if>
	    <if test="note != null">#{note},</if>
	    </trim>
	  ON DUPLICATE KEY UPDATE
	  <trim prefix="" suffix="" suffixOverrides=",">
		<if test="sex != null">sex = #{sex},</if>
		<if test="note != null">note = #{note},</if>
		</trim>
	</insert>
</mapper>

测试

至此,SpringBoot已经能够生成动态的代理类来实现UserDao这个接口了,只需要通过@Autowired 或获取Bean就直接可以使用(Spring IoC牛p

@Controller
public class UserController {
	@Autowired
	UserDao userDao;	
	@RequestMapping("query/{id}")
	@ResponseBody
	public User index(@PathVariable Long id) {
		return userDao.getUserById(id);
	}	
	@RequestMapping("query")
	@ResponseBody
	public List<User> query() {
		return userDao.getUserAll();
	}	
	@RequestMapping("insert")
	@ResponseBody
	public String insert(User user) {
		int result = userDao.insertUser(user);
		return "insert请求生效: " + result;
	}	
	@RequestMapping("delete/{id}")
	@ResponseBody
	public String delete(@PathVariable Long id) {
		int result = userDao.deleteUser(id);
		return "delete请求生效: " + result;
	}	
	@RequestMapping("update")
	@ResponseBody
	public String update(User user) {

		int result = userDao.updateUser(user);
		return "update请求生效: " + result;
	}	
	@RequestMapping("save")
	@ResponseBody
	public String save(User user) {
		int result = userDao.saveUser(user);
		return "save请求生效: " + result;
	}
}

测试路径( 不是RESTful风格
http://127.0.0.1:8080/query/
http://127.0.0.1:8080/insert/?userName=test&sex=2&note=233333333
http://127.0.0.1:8080/save/?userName=test2&sex=2&note=hhhhhhhhhhhh
http://127.0.0.1:8080/update/?userName=test&sex=2&note=哈哈哈哈哈哈哈
http://127.0.0.1:8080/query/1

常见问题

  • 增删改查见生成dao对应的xml
  • 分页一般用Mybatis的拦截器。相较于SpringMVC,在拦截器上增加注解@Component,让SpringBoot扫描Bean即可,无需再在.xml里面指定拦截器

内容
隐藏