1.导入我们的mybatis的启动器
<!--版本根据自己的需求进行引入-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
2.启动的配置项
①在properties中的配置
#以下是数据库的四大配置
#数据库连接地址
spring.datasource.url=jdbc\:sqlserver\://127.0.0.1\:1433;database\=Xs
#数据库的用户名
spring.datasource.username=test
#数据库的密码
spring.datasource.password=test
#数据库的驱动
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
②在yml中的配置
*注意:配置了别名,但是在springBoot项目中,我们把项目打成jar包后,使用java -jar进行启动,别名就失效了,建议在xml中还是使用完全限定名(包名+类名)
mybatis:
typeAliasesPackage: com.dh.entity
③在类中的配置:
@SpringBootApplication
@ComponentScan
@EnableAutoConfiguration
@MapperScan("com.dh.dao")
@EnableTransactionManagement(proxyTargetClass = true)
public class BootApplication {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
//@ConfigurationProperties以spring.datasource为前缀的值全部对应注入到相关属性中
//@Value的话只能逐个注入,并且使用相当于el表达式的形式取值@Value("${test}")
public DruidDataSource dataSource() {
return new DruidDataSource();
}
@Bean
public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
//扫描配置文件,分页插件放在这里面的
sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//扫描classpath下面的所有xml文件
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mybatis/*.xml"));
return sqlSessionFactoryBean.getObject();
}
//配置事务管理器
@Bean
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
④下面是mybatis-config.xml的配置(其实不用这个直接配置成bean也可以)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 开启驼峰命名的映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="useGeneratedKeys" value="true"/>
<!-- 开启二级缓存全局配置 -->
<!-- <setting name="cacheEnabled" value="true"/> -->
</settings>
<typeAliases>
<package name="com.dh.entity"/>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="page" value="pageNum"/>
</plugin>
</plugins>
</configuration>
⑤如果不想用xml配置分页插件的话,那么我们就用bean的方式
import java.util.Properties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.github.pagehelper.PageHelper;
//一定要打上@Configuration标签,告诉spring这是一个配置类,在启动的时候就必须加装
@Configuration
public class MybatisConfig {
@Bean
public PageHelper pageHelper() {
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("helperDialect", "mysql");
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);
return pageHelper;
}
}
3.在使用过程中需要注意的事项:
①mapper层设置参数名称
//Mabatise的mapper层,如果需要传入多个参数,而不是一个对象,那么久必须使用@Param对其进行命名,因为在xml中使用的只是一个占位符
public List<CheckImageDataFault> findAll(@Param(value = "checkImageDataID") Long CheckImageDataID,@Param(value = "imageIndex") Long ImageIndex, @Param(value = "ids") List<Integer> ids);
②xml中的使用
<!-- 这是和上面mapper层方法对应的Xml -->
<!-- 需要注意的是,如果是用in的话,那么这个值得个数不能超过2000个 -->
<select id="findAll" resultType="com.dh.entity.CheckImageDataFault">
select
CheckImageDataFaultID,CheckImageDataID,ImageIndex,FaultWidth,FaultHeight,FaultType,AlarmLevel,IsRight,
Coord_X as coordx,Coord_Y as coordy from CheckImageDataFault where
CheckImageDataID=#{checkImageDataID} and ImageIndex in
<foreach collection="ids" index="index" item="item" open="("
separator="," close=")">
#{item}
</foreach>
</select>
③大于小于等符号的使用
<!--在xml中使用大于小于的时候不能直接写"<"或者是">"这类副号,因为在xml中这两个副号是用来判断一个节点的开始或者是结束的,&会被解析成一个字符实体-->
<!--第一种方式,使用<![CDATA[>=]]>将我们的比较符包起来,这样告诉xml解析的时候,是直接解析内容-->
<if test="beginDateTime!=null">
and r.CheckTime <![CDATA[>=]]>#{beginDateTime}
</if>
<if test="endDateTime!=null">
and r.CheckTime <![CDATA[<=]]>#{endDateTime}
</if>
<!--第二种方式使用-->
<,<=,>,>=,&,',"
依次对应的是:< <= > >= & ' "
④mybatis返回主键:
方式一
<!--使用useGeneratedKeys属性设置为true,再设置一下主键再实体类中对应的属性-->
<insert id="insertLocoMileage" useGeneratedKeys="true" keyProperty="id" parameterType="com.dh.entity.LocoMileage">
insert into
LocoMileage(groupid,locomileage,recordtime,remark) values
{#{groupid},#{locomileage},#{recordtime},#{remark}}
</insert>
方式二:
//insert语句本身是无返回的,加上selectKey标签之后,可以使其在插入之后返回主键
<insert id="insertLocoMileage" parameterType="com.dh.entity.LocoMileage">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
select LAST_INSERT_ID()
</selectKey>
insert into
LocoMileage(groupid,locomileage,recordtime,remark) values
{#{groupid},#{locomileage},#{recordtime},#{remark}}
</insert>
4.mybatis中使用分页插件:
/**
* 在service层进行使用分页插件
*/
@Override
public PageInfo<CheckValueFault> findCheckValueFaults(BaseQuery query) {
//直接在调用dao层或者mapper层的时候使用PageHelper.startPage(第一个参数是当前页数,第二个参数是,当前显示多少条)
PageHelper.startPage(query.getPageNo(), query.getPageSize());
List<CheckValueFault> checkValueFaults = dao.findAllCheckValueFault(query);
//此处使用java8的新特性,流式变成
checkValueFaults.stream().forEach(checkValueFault -> {
if (checkValueFault.getRecheckuser() != null) {
User user = userDao.getUserById((long) checkValueFault.getRecheckuser());
checkValueFault.setUserName(user.getUserName());
}
});
PageInfo<CheckValueFault> pageInfo = new PageInfo<CheckValueFault>(checkValueFaults);
return pageInfo;
}
5.事务使用注意事项:
在开发过程中,之前遇到了一个问题。在存放订单信息的时候,包含两个内容,一个是订单头信息,一个是订单体信息,并且两个部分是分开存在数据库中的(相当于是两张表,一张存头信息,一张存体信息)。那么:在实际情况中,那就必须是,头信息和体信息要不就同时成功和或者是同时失败的。然后就理所当然的打上了@Transactional(propagation=Propagation.REQUIRED)这个标签,以为就可以成功的做到异常的捕获了。但是没有想到的是,并没有成功。
①在默认情况下,spring会对unchecked异常进行实物回滚;如果是checked异常则不回滚。(java中,将派生与Error或者RuntimeException的异常称为unchecked异常{空指针,1/0},其他集成自java.lang.Exception的异常统称为checked异常{IOException,TimeoutException})
所以注解应该改为:@Transactional(propagation=Propagation.REQUIRED,rollbackFor = Exception.class)
还有几种方式会导致事务失效的详情见:事务失效原因