无论是自己搭也好,用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¬e=233333333
http://127.0.0.1:8080/save/?userName=test2&sex=2¬e=hhhhhhhhhhhh
http://127.0.0.1:8080/update/?userName=test&sex=2¬e=哈哈哈哈哈哈哈
http://127.0.0.1:8080/query/1
常见问题
- 增删改查见
生成dao对应的xml
- 分页一般用Mybatis的拦截器。相较于SpringMVC,在拦截器上增加注解@Component,让SpringBoot扫描Bean即可,无需再在.xml里面指定拦截器