作用于Dao层上的数据库操作框架,底层用的JDBC,是JDBC的改进升级版。
MyBatis相比JDBC:
无需自行管理Connection、statement的关闭。
读取数据库字段更为简便,直接返回对象集合。
配置信息解耦,存放与xml文件中,修改配置时无需重新编译程序。
spring.datasource.driver-class-name= com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test
spring.datasource.username=root
spring.datasource.password=123456
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl //展示sql具体操作日志,打印到STDOUT
@Mapper //自动生成Mapper接口的实现类对象,并交给IOC容器管理
public interface UserMapper {
@Select("select * from user")
List<User> getUsers();
@Delete("delete from user where uid =#{id}")
public int deleteById(Integer id );
@Options(useGeneratedKeys = true,keyProperty = "uid") //获取插入结果中数据库自动生成的主键
@Insert("insert into user values(#{uid},#{name},#{password},#{birthday},#{salary})")//这里指User对象中的uid...
public int insertInto(User user);
@Update("update user set name=#{name},password=#{password},birthday=#{birthday},salary=#{salary} where uid=#{uid}")
public int updateUser(User user);
}
其中#{}占位符生成预编译sql,${}占位符生成拼接sql,存在注入安全问题。
需要注意在select时,实体类的属性需要与数据库中的字段名相同,如果不同可以通过以下几种方式解决:
在sql查询时有时仅按uid进行查询,有时通过uid、name同时进行查询,Mybatis在XML文件中提供了where、if标签进行动态查询。
if标签:如果满足test中的判断条件,会将if标签内的sql语句拼接到查询sql中。
where标签:自动判断where后面是否有拼接的字段并识别去除多余的and和or,如果where后没有字段了则sql语句为select* from user;
set标签:去除set关键字后多余的逗号
<select id="getUser" resultType="com.yi.mybatis_demo.domain.User">
select * from user
<where>
<if test="uid!=0">
uid=#{uid}
if>
<if test="name!=null">
and name=#{name}
if>
where>
select>
<update id="updateUser">
update user
<set>
<if test="name!=null">name=#{name},if>
<if test="password!=null">password=#{password},if>
<if test="birthday!=null">birthday=#{birthday},if>
<if test="salary!=0">salary=#{salary}if>
set>
where
uid=#{uid}
update>
foreach标签可以遍历集合中的元素,并将元素拼接成sql语句
foreach属性
collection:遍历的集合
separator:拼接时的分隔符
open/close:添加开始和结束的字符
item:依次遍历出来的元素/项
Mapper方法:
public int deleteByList(List<Integer>Ids);
//XML: delete from user where uid in (item1,item2...)
<delete id="deleteByList">
delete from user
where uid in
<foreach collection="Ids" separator="," open="(" close=")" item="id">
#{id}
foreach>
delete>
sql标签:将常用sql语句使用id变量保存
include标签:引用sql标签保存的sql语句
<sql id="selectCommon">
select name,password from user
sql>
<select id="getAccount">
<include refid="selectCommon"/>
where uid=#{uid}
select>
加入@Transactional即可开启事务自动提交。
@Transactional注解默认只会回滚RuntimeException,如果要选择回滚所有异常需要配置Rollbackfor属性
@Transactional(rollbackFor = Exception.class)
事务传播配置:
在带有@Transactional的A方法中调用带有@Transactional的B方法,是创建新的事物还是加入到原来的事物中?
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
Propagation.REQUIRED(默认) :需要事物,如果调用者已经存在事物则加入到之前的事物中,如果没有则创建新的事物。
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
Propagation.REQUIRES_NEW:创建新的事物
应用场景:删除时无论成功/失败都需要记录日志,记录日志应该新开一个事物
Mybatis默认连接池为hikari(追光者),可以将其切换成druid实现。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.19</version>
</dependency>
spring.datasource.driver-class-name= com.mysql.cj.jdbc.Driver
在每次构建实体类时都需要进行定义get/set方法、重新toString方法等等,这样定义的类会非常的冗长,lombok框架可以通过注解进行着一系列操作。
@Getter/Setter 为所有属性设置get/set方法
@ToString 设置易读的toString方法
@EqualsAndHashCode 根据类中非静态字段重写equals方法与hashCode方法
@Data =@Getter+@Setter+@ToString+@EqualsAndHashCode
@NoArgsConstructor 提供默认无参构造
@AllArgsConstructor 根据非静态字段提供有参构造
在pom.xml中加入
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
public class User {
private Integer uid;
private String username;
private String password;
public User(Integer uid, String username, String password) {
this.uid = uid;
this.username = username;
this.password = password;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
@AllArgsConstructor
@Setter
@Getter
@ToString
public class User {
private Integer uid;
private String username;
private String password;
}
或者使用@Data注解(=@Getter+@Setter+@ToString+@EqualsAndHashCode)
@AllArgsConstructor
@Data
public class User {
private Integer uid;
private String username;
private String password;
}