一、springboot整合
1.maven依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>3.3.9</version>
</dependency
2.在application.yml中添加DataSource配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*.xml #注意:一定要对应mapper映射xml文件的所在路径
type-aliases-package: com.example.demo.mybatis # 注意:对应实体类的路径
3.启动类中添加对mapper包扫描
@SpringBootApplication
@MapperScan("com.shanheyongmu.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4.Mapper
public interface UserMapper {
@Select("SELECT * FROM users")
@Results({
@Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
@Result(property = "nickName", column = "nick_name")
})
List<UserEntity> getAll();
@Select("SELECT * FROM users WHERE id = #{id}")
@Results({
@Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
@Result(property = "nickName", column = "nick_name")
})
UserEntity getOne(Long id);
@Insert("INSERT INTO users(userName,passWord,user_sex) VALUES(#{userName}, #{passWord}, #{userSex})")
void insert(UserEntity user);
@Update("UPDATE users SET userName=#{userName},nick_name=#{nickName} WHERE id =#{id}")
void update(UserEntity user);
@Delete("DELETE FROM users WHERE id =#{id}")
void delete(Long id);
}
正常情况下,我们设置表的主键自增,然后:
@Insert("insert into miaosha_order (user_id, goods_id, order_id)values(#{userId}, #{goodsId}, #{orderId})") public int insertMiaoshaOrder(MiaoshaOrder miaoshaOrder);
可以直接插入,秒杀订单标的id字段用的是数据库自增长策略
但是,如何获在插入后,获取id的值呢,如果通过查询获取id,用@SelectKey注解:
select last_insert_id() 取到最后生成的主键,自动放到pojo的id属性!!!!!
// before:在执行插入语句之前,我们设置为flase,既after(在插入这个语句之后,执行select last_insert_id()函数) //mysql执行函数用select //@SelectKey用来获取插入后的记录id @SelectKey(statement = "select last_insert_id()" ,keyProperty = "id",keyColumn = "id",resultType = long.class,before = false) public long insert(OrderInfo orderInfo);
5.使用
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
public void testInsert() throws Exception {
Integer i = userMapper.insert(new UserEntity("aa", "a123456", UserSexEnum.MAN));
}
}
二、API/注解详解
1.传参
①@Param
@Insert("INSERT INTO T_USER(NAME, PASSWORD, PHONE) VALUES(#{name}, #{password}, #{phone})")
int insert(@Param("name") String name, @Param("password") String password, @Param("phone") String phone);
@Param
中定义了name
对应了sql中的#{name}
, password
对应了sql中的#{password}
, phone
对应了sql中的 #{phone}
。
②使用Map
通过Map对象来传递参数:
@Insert("INSERT INTO T_USER(NAME, PASSWORD, PHONE) VALUES(" +
"#{name, jdbcType=VARCHAR}, #{password, jdbcType=VARCHAR}, #{phone, jdbcType=VARCHAR})")
int insertByMap(Map<String, Object> map);
对于Insert语句中需要的参数,我们只需要在map中填入同名的内容即可,具体如下面代码所示:
Map<String, Object> map = new HashMap<>();
map.put("name","王五");
map.put("password","23423");
map.put("phone", "13400000000");
userMapper.insertByMap(map);
③使用对象
如果我们使用普通的java对象作为查询条件的参数:
@Insert("INSERT INTO T_USER(NAME, PASSWORD, PHONE) VALUES(#{name}, #{password}, #{phone})")
int insertByUser(User user);
只需要语句中的#{name}
、#{age}
就分别对应了User
对象中的name
和age
属性。
User u = new User();
u.setName("赵六");
u.setPassword("12312312");
u.setPhone("13888888888");
userMapper.insertByUser(u);
2.Results结果集
@Result 修饰返回的结果集,关联实体类属性和数据库字段一一对应,如果实体类属性和数据库属性名保持一致,就不需要这个属性来修饰。这个注解相当于XML配置文件中的<ResultMap>。
①场景一:关联实体类属性和数据库字段 一 一对应
@Select("select *from Demo where id=#{id}")
public Demo selectById(int id);
②场景二:关联实体类属性部分属性和数据库字段不对应
Demo类:
private int id;
private String name;
private Date updateTime;
数据库表信息:
id int
name varchar
update_time datetime
查询语句:
@Select("select *from Demo where id=#{id}")
@Results({
@Result(property="updateTime",column="update_time")
})
public Demo selectById2(int id);
③场景三:在上面的基础上,性别是枚举类型
Demo类:
private int id;
private String name;
private Date updateTime;
private SexEnum sexEnum;
Enum类:
public enum SexEnum {
MAN, WOMAN
}
数据库表信息:
CREATE TABLE `demo` (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(100) DEFAULT NULL,
update_time datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
sex_enum enum('MAN','WOMAN') DEFAULT NULL,
PRIMARY KEY (`id`)
);
查询语句:
@Select("select *from Demo where id=#{id}")
@Results({
@Result(property="updateTime",column="update_time"),
@Result(property="sexEnum",column="sex_enum",javaType=SexEnum.class)
})
public Demo selectById2(int id);
3.provider动态sql
对于创建动态的查的语言。MyBatis提供了多个注解如:@InsertProvider,@UpdateProvider,@DeleteProvider和@SelectProvider,这些都是建立动态语言和让MyBatis执行这些语言。
①示例:
/**
* 查询语句.使用SQL
* @param demo
* @return
*/
public String select6(final Demo demo){
return new SQL(){{
SELECT("id,name,email");
FROM("demo");
if(demo.getName() != null){
WHERE("name=#{name}");
}
if(demo.getEmail() != null){
WHERE("email=#{email}");
}
}}.toString();
}
@SelectProvider(type=DemoSqlProvider.class,method="select6")
public List<Demo> select6(Demo demo);
②相关API
SELECT
FROM
LEFT_OUTER_JOIN
INNER_JOIN
WHERE
OR
AND
GROUP_BY
HAVING
三、tk.mybatis
Tkmybatis是在mybatis框架的基础上提供了很多工具,让开发更加高效。
Mapper
继承tkMabatis
的Mapper
接口
public interface CustomerMapper extends Mapper<Customer> {
}
这样,mapper就有tkMabatis提供的一些工具方法: