maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>1.5.5.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
application.yml配置文件
server:
port: 9999
logging:
level:
com.test.mapper: debug #打印sql,这里的路径为mapper包的路径
spring:
application:
name: mybatis-test
datasource:
driver: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.1.250:3306/mybatis-test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useInformationSchema=true&autoReconnect=true&failOverReadOnly=false
username: root
password: 1234
mybatis:
mapper-locations: classpath:mapping/*Mapper.xml #使用mapper配置文件时必须要配置,如果使用mybatis注解的话此配置不需要
创建实体类
/**
* 这里用到了@Data注解,需要引入lombok包
*/
@Data
public class User implements Serializable {
private Long id;
private String userName;
private String password;
}
创建mapper类
这里的mapper类必须和配置文件打印sql日志的包一致,即com.test.mapper。
只要使用@Mapper注解后,在系统启动后,会为该接口使用动态代理的方式生成实现类
/**
* 如果参数有多个,需要用@Param注解标识出来
*/
@Mapper
public interface UserMapper {
int insert(User user);
int update(User user);
List<User> findAll();
int delete(Long id);
List<User> find(@Param("uname")String userName,@Param("pwd")String password);
}
mapper文件
mapper文件的路径需要和application配置文件中的mapper文件定义保持一致
<?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">
<!--namespace参数为对应的mapper类的全路径-->
<mapper namespace="com.msxf.activity.test.mapper.UserMapper">
<!--resultMap定义数据库表字段和Java对象属性映射关系,如果是多表操作或者数据库字段和Java属性字段不一致时必须配置-->
<resultMap id="userMap" type="com.msxf.activity.test.enty.User">
<id column="id" property="id"/>
<result column="user_name" property="userName"/>
<result column="password" property="password"/>
</resultMap>
<insert id="insert" parameterType="com.msxf.activity.test.enty.User">
insert into user(user_name,password) values (#{userName},#{password})
</insert>
<update id="update" parameterType="com.msxf.activity.test.enty.User">
update user set user_name = #{userName},password = #{password} where id = #{id}
</update>
<delete id="delete" parameterType="long">
delete from user where id = #{id}
</delete>
<select id="findAll" resultMap="userMap">
select * from user
</select>
<select id="find" resultMap="userMap">
<!--#{uname}必须和mapper类中的注解@Param参数一致-->
select * from user where user_name=#{uname} and password=#{pwd}
</select>
</mapper>
service controller类
@Service
@Transactional
public class UserService {
//这里建议用resource,如果用@Autowired注入,idea会报找不到对应的bean的错
@Resource
private UserMapper userMapper;
public int insert(User user){
return userMapper.insert(user);
}
public int update(User user){
return userMapper.update(user);
}
public int delete(Long id){
return userMapper.delete(id);
}
public List<User> findAll(){
return userMapper.findAll();
}
}
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@RequestMapping("insert")
public ResponseData insertUser(@RequestBody User user){
ResponseData result = new ResponseData();
int insert = userService.insert(user);
result.setData(insert);
return result;
}
@RequestMapping("update")
public ResponseData updateUser(@RequestBody User user){
ResponseData result = new ResponseData();
int update = userService.update(user);
result.setData(update);
return result;
}
@RequestMapping("delete")
public ResponseData deleteUser(@RequestParam("id") Long id){
ResponseData result = new ResponseData();
int delete = userService.delete(id);
result.setData(delete);
return result;
}
@RequestMapping("findAll")
public ResponseData findAllUser(){
ResponseData result = new ResponseData();
List<User> all = userService.findAll();
result.setData(all);
return result;
}
}
springboot启动类
@SpringBootApplication
@MapperScan("com.test.mybatis")
@EnableSwagger2
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
基于注解的mapper类
注解有如下2种:
- 在mapper类的方法上使用@insert、@update、@select、@delete
- 优点:简单方便
- 缺点:sql语句需要动态拼接时无法实现
- 在mapper类的方法上使用@InsertProvider、@UpdateProvider、@SelectProvider和@DeleteProvider
- 优点:可动态拼接sql语句,甚至比xml文件更灵活
- 缺点:稍微不第一种方式复杂点
注意:这2种方式只是在组装sql时才有差别,其他的完全一致,即在@select中写完sql,还可以在下面写@Results,而使用@SelectProvider后
还是可以在下面继续使用注解@Results
在mapper类的方法上直接写sql
@Mapper
public interface UserMapper {
@Insert("insert into user(user_name,password) values (#{userName},#{password})")
int insert(User user);
@Update("update user set user_name = #{userName},password = #{password} where id = #{id}")
int update(User user);
@Select({"select * from user",})
@Results(id = "userMap",value = {
@Result(column = "user_name",property = "userName"),
@Result(column = "password",property = "password")
})
List<User> findAll();
@Delete("delete from user where id = #{id}")
int delete(Long id);
}
在mapper类的方法上指定sql语句拼接类,在类中实现sql语句的编写
需求:将客户端请求过来的数据保存到一个表中,请求数据会指明数据应该保存到哪个表中,请求的数据可能是表中字段的一个子集,
请求格式为:{“datas”:{“user_name”:“zhangsan”,“password”:“123456”},“tableName”:“t_user”}
@Mapper
public interface MyEntityMapper {
@InsertProvider(type = MyEntityProvider.class, method = "save")
@Options(keyColumn = "id", useGeneratedKeys = true)
void save(MyEntity entity);
@UpdateProvider(type = MyEntityProvider.class,method = "update")
int update(MyEntity entity);
@SelectProvider(type = MyEntityProvider.class,method = "findOne")
Map<String,Object> findOne(MyEntity entity);
@SelectProvider(type = MyEntityProvider.class,method = "findAll")
List<MyEntity> findAll(MyEntity entity);
//有多个参数时,需要使用@Param注解
@SelectProvider(type = MyEntityProvider.class,method = "findByUserNameAndPassword")
MyEntity findByUserNameAndPassword(@Param("uname")String userName,@Param("pwd") String password);
}
//MyEntityProvider.java
public class MyEntityProvider {
public String save(MyEntity entity){
SQL sql = new SQL();
sql.INSERT_INTO(entity.getTableName());//组装 insert into tableName
String [] fileds = new String[entity.getDatas().size()];
String [] values = new String[entity.getDatas().size()];
int i=0;
//key为数据库字段 value为要保存的值
Map<String, Object> fieldAndValues = entity.getDatas();
Iterator<Map.Entry<String, Object>> it = fieldAndValues.entrySet().iterator();
while(it.hasNext()){
Map.Entry<String, Object> next = it.next();
String key = next.getKey();
fileds[i] = key;
values[i] = "#{datas."+key+"}";
i++;
}
sql.INTO_COLUMNS(fileds); //组装tableName后的字段列表
sql.INTO_VALUES(values); //组装values后的占位符
return sql.toString();
}
public String update(MyEntity entity){
SQL sql = new SQL();
sql.UPDATE(entity.getTableName()); //组装update tableName
Map<String, Object> fieldAndValues = entity.getDatas();
Iterator<Map.Entry<String, Object>> it = fieldAndValues.entrySet().iterator();
while(it.hasNext()){
Map.Entry<String, Object> next = it.next();
String key = next.getKey();
String values = "#{datas."+key+"}";
String set = key+"="+values;
sql.SET(set);//动态拼接 set xx=yy
}
sql.WHERE("id=#{datas.id}");//拼接where后的条件
return sql.toString();
}
public String findOne(MyEntity entity){
SQL sql = new SQL();
sql.SELECT("*");//select *
sql.FROM(entity.getTableName());//from tableName
sql.WHERE("id=#{datas.id}");//where
return sql.toString();
}
//注意,这里一定要使用@param注解,不然会报找不到字段的异常
public String findByUserNameAndPassword(@Param("uname")String userName,@Param("pwd") String password){
SQL sql = new SQL();
sql.SELECT("*");
sql.FROM(entity.getTableName());
sql.WHERE("user_name=${uname} and password=${pwd}");
return sql.toString();
}
}
注意,如果使用基于注解的mapper的话,需要注意如下2点:
- 在application.yaml的配置文件中,不需要mybatis.mapper-locations=classpath:mapping/*Mapper.xml配置
- 在springboot启动类中,需要添加@MapperScan(“mapper包名”),指引spring加载对应的mapper类,当然如果启动类所在的包在mapper包外的话,可以不用指定
一个最简单的springboot+mybatis的整合就完成了。