mybatis使用教程:http://www.mybatis.cn/2182.html
一、使用mybatis-Maven
导入依赖
<!--mybatis 依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<!-- mysql驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--junit 单元测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- PageHelper 分页插件: plugin配置插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
</dependency>
配置文件
db.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
mybatis-config.xml
<?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>
<!--导入其他配置文件 -->
<properties resource="db.properties"></properties>
<!-- 全局配置 -->
<settings>
<!-- 开启mybatis日志 -->
<setting name="logImpl" value="SLF4J"/>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
<!-- <!– 开启延迟加载 –>
<setting name="lazyLoadingEnabled" value="true"/>
<!– 什么方法都不触发延迟加载 –>
<setting name="lazyLoadTriggerMethods" value=""/>-->
<!-- 开启驼峰命名 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 别名 -->
<typeAliases>
<!-- 为该包下的所有类配置别名,别名省略包名,和类名相同 -->
<package name="com.xl.xml.pojo"/>
</typeAliases>
<!-- 插件配置-->
<plugins>
<!-- 配置分页查询插件-->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 设置数据库类型-->
<property name="helperDialect" value="mysql"/>
</plugin>
</plugins>
<!-- 配置环境 -->
<environments default="mysql">
<environment id="mysql">
<!-- 事务类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 注册映射文件 -->
<mappers>
<package name="com.xl.xml.mapper"/>
</mappers>
</configuration>
properties(属性)
属性值定义。properties标签中可以定义属性值,也可以引入外部配置文件。无论是内部定义还是外部引入,都可以使用${name}获取值。
<properties resource="db.properties"></properties>
typeAliases(别名)
- 为一个类配置别名
<typeAliases>
<typeAlias type="全类名" alias="别名"></typeAlias>
</typeAliases>
- 为一个所有包下的所有类配置别名
<typeAliases>
<package name="包名"></package>
</typeAliases>
environments(环境)
<environments default="mysql">
<environment id="mysql">
<!-- 事务类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
mappers(映射器)
- 使用相对路径注册映射文件
<mappers>
<mapper resource="com/xl/mapper/UserMapper.xml"/>
</mappers>
- 使用绝对路径注册映射文件
<mappers>
<mapper url="file:///C:\Users\resources\com\xl\mapper\UserMapper.xml"/>
</mappers>
- 注册持久层接口
<mappers>
<mapper class="com.xl.mapper.UserMapper"/>
</mappers>
- 注册一个包下的所有持久层接口
<mappers>
<package name="com.xl.mapper"/>
</mappers>
settings(全局配置参数)
配置MyBatis运行时的一些行为的,例如缓存、延迟加载、命名规则等一系列控制性参数。后期我们会使用该标签配置缓存和延迟加载等。
<settings>
<setting name="属性名" value="属性值 "/>
</settings>
属性名 | 属性值 | 作用 |
---|---|---|
cacheEnabled | true | 开启二级缓存(POJO可序列化, 映射文件添加 标签) |
注解方式在接口添加 @CacheNamespace(blocking=true) | ||
lazyLoadingEnabled | true | 开启延迟加载( 在 association/collection 中添加fetchType属性) |
lazyLoadTriggerMethods | 方法名 | 该属性指定对象的什么方法触发延迟加载(空字符串) |
plugins(插件)
配置MyBatis插件的。插件可以增强MyBatis功能,比如进行sql增强,打印日志,异常处理等。后期我们会使用该标签配置分页插件。
- 分页插件
<!-- 插件配置-->
<plugins>
<!-- 配置分页查询插件-->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 设置数据库类型-->
<property name="helperDialect" value="mysql"/>
</plugin>
</plugins>
使用mybatis
接口配置
接口参数相关
占位符 | 含义 |
---|---|
#{} | 占位符, |
${} | 占位符, |
顺序传参
Sql中的参数使用arg0,arg1…或param1,param2…表示参数的顺序。此方法可读性较低,在开发中不建议使用。
@Param传参
在接口方法的参数列表中通过@Param定义参数名称,在Sql语句中通过注解中所定义的参数名称指定参数位置。此方式参数比较直观的,推荐使用。
List<User> findByUsernameLike(@Param("username")String username);
POJO传参
自定义POJO类,该类的属性就是要传递的参数,在SQL语句中绑定参数时使用POJO的属性名作为参数名即可。此方式推荐使用。
Map传参
如果不想自定义POJO,可以使用Map作为传递参数的载体,在SQL语句中绑定参数时使用Map的Key作为参数名即可。此方法推荐使用。
①、mapper.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="com.xl.xml.mapper.xxxMapper">
<!-- 语句 -->
</mapper>
属性名 | 值 |
---|---|
namespace | 接口的全名。 |
id | 接口方法的方法名 |
resultType | 接口方法的返回值类 |
resultMap | 自定义返回映射关系 |
parameterType | 接口方法的参数类 |
基本语句
insert
<!-- 新增用户+主键回填-->
<insert id="add" parameterType="com.xl.pojo.User">
<!-- keyProperty:主键属性名,keyColumn:主键列名,resultType:主键类型,order:执行时机 -->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID();
</selectKey>
insert into
user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#
{address})
</insert>
select
<select id="findAll" resultMap="BaseResultMap">
select id, name, sex, address
from user
</select>
update
<update id="update">
update user
set name = #{name},
sex = #{sex},
address=#{address}
where id = #{id}
</update>
delete
<delete id="delete">
delete
from user
where id = #{id}
</delete>
resultMap语句
<!-- id:自定义映射名 type:自定义映射的对象类型 -->
<resultMap id="teacherMapper" type="com.xl.pojo.Teacher">
<!-- id定义主键列 property:POJO属性名 column:数据库列名 -->
<id property="id" column="tid"></id>
<!-- result定义普通列 property:POJO属性名 column:数据库列名 -->
<result property="teacherName" column="tname"></result>
</resultMap>
一对一映射
- 关联查询
<resultMap id="studentMapper" type="com.xl.pojo.Student">
<!-- 主键列 -->
<id property="sid" column="sid"></id>
<!-- 普通列 -->
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<!-- 一对一对象列 property:属性名 column:关联列名 javaType:对象类型-->
<association property="classes" column="classId" javaType="com.xl.pojo.Classes">
<!-- 关联对象主键列 -->
<id property="cid" column="cid"></id>
<!-- 关联对象普通列 -->
<result property="className"column="className"></result>
</association>
</resultMap>
--------------------------------------------------------------------
<!-- 多表查询,级联查询学生和其班级 -->
<select id="findAll" resultMap="studentMapper">
select * from student left join classes on student.classId = classes.cid;
</select>
- 分解式查询
setting设置开启延迟加载:在 association/collection>中添加fetchType属性设置加载方式。lazy:延迟加载;eager:立即加载。
#########################################################
<select id="findByCid" resultType="com.xl.pojo.Classes" parameterType="int">
select * from classes where cid = ${cid}
</select>
#########################################################
<resultMap id="MyStudentMapper" type="com.xl.pojo.Student">
<id property="sid" column="sid"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<association property="classes"
javaType="com.xl.pojo.Classes"
select="com.xl.mapper.ClassesMapper.findByCid"
column="classId">
</association>
</resultMap>
--------------------------------------------------------------------
<select id="findAll" resultMap="MyStudentMapper">
select *
from student
</select>
一对多映射
- 关联查询
<resultMap id="classesMapper" type="com.xl.pojo.Classes">
<id property="cid" column="cid"></id>
<result property="className" column="className"></result>
<!-- 集合列 property:属性名 column:关联列名 ofType:集合的泛型 -->
<collection property="studentList" column="classId" ofType="com.xl.pojo.Student">
<id property="sid" column="sid"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
</collection>
</resultMap>
--------------------------------------------------------------------
<!-- 多表查询,级联查询班级和它的学生 -->
<select id="findAll" resultMap="classesMapper">
select * from classes left join student on classes.cid = student.classId;
</select>
- 分解式查询
setting设置开启延迟加载:在 association/collection>中添加fetchType属性设置加载方式。lazy:延迟加载;eager:立即加载。
#########################################################
<select id="findByClassId" resultType="com.xl.pojo.Student" parameterType="int">
select * from student where classId =${classId}
</select>
#########################################################
<!-- 自定义映射关系 -->
<resultMap id="MyClassesMapper" type="com.xl.pojo.Classes">
<id property="cid" column="cid"></id>
<result property="className" column="className"></result>
<!-- select:从表查询调用的方法 column:调用方法时传入的参数字段 -->
<collection property="studentList"
ofType="com.xl.pojo.Student"
select="com.xl.mapper.StudentMapper.findByClassId"
column="cid">
</collection>
</resultMap>
--------------------------------------------------------------------
<select id="findAll" resultMap="MyClassesMapper">
select * from classes
</select>
动态sql
特殊字符
符号 | 实体 |
---|---|
< | & lt; |
> | & gt; |
& | & amp; |
‘ | & apos; |
“ | & quot; |
if
标签内的Sql片段在满足条件后才会添加,用法为: 。if中的条件不能使用&&/||,而应该使用and/or;if中的条件可以直接通过属性名获取参数POJO的属性值,并且该值可以调用方法。
<if test="username != null and username.length() != 0">
and username like #{username}
</if>
where
可以代替sql中的where 1=1 和第一个and,
<where>
<if test="username != null and username.length() != 0">
username like #{username}
</if>
<if test="sex != null and sex.length() != 0">
and sex = #{sex}
</if>
</where>
set
标签用在update语句中。借助 ,可以只对有具体值的字段进行更新。 会自动添加set关键字,并去掉最后一个if语句中多余的逗号。
<set>
<if test="username != null and username.length() > 0">
username = #{username},
</if>
<if test="sex != null and sex.length() > 0">
sex = #{sex},
</if>
</set>
choose+when+otherwise
这些标签表示多条件分支,类似JAVA中的 switch…case 。 类似switch , 类似 case , 类似 default
<choose>
<when test="username.length() < 5">
username like #{username}
</when>
<when test="username.length() < 10">
username = #{username}
</when>
<otherwise>
id = 1
</otherwise>
</choose>
foreach
类似JAVA中的for循环,可以遍历集合或数组。
属性 | 含义 |
---|---|
collection | 遍历的对象类型 |
open | 开始的sql语句 |
close | 结束的sql语句 |
separator | 遍历每项间的分隔符 |
item | 表示本次遍历获取的元素,遍历List、Set、数组时表示每项元素,遍历map时表示键值对的值。 |
index | 遍历List、数组时表示遍历的索引,遍历map时表示键值对的键。 |
<foreach open="id in(" close=")" separator="," collection="array" item="id">
#{id}
</foreach>
其他语句
sql&include
- 定义sql片段
<sql id="selectAllField">
select tid as id,tname as teacherName
</sql>
- 使用定义sql片段
<select id="findAll" resultType="com.xl.pojo.Teacher">
<include refid="selectAllField"></include>
from teacher;
</select>
②、interface注解配置
基本注解
@Select
public interface UserMapper {
@Select("select * from user")
List<User> findAll();
}
@Insert
// 主键回填
public interface UserMapper {
@SelectKey(keyColumn = "id",
keyProperty ="id",
resultType = int.class,before = false,
statement = "SELECT LAST_INSERT_ID()")
@Insert("insert into user(username,sex,address) values(#{username},#{sex},#{address})")
void add(User user);
}
@Update
public interface UserMapper {
@Update("update user set username = #{username},sex=#{sex},address=#{address} where id = {id}")
void update(User user);
}
@Delete
public interface UserMapper {
@Delete("delete from user where id = #{id}")
void delete(int id);
}
resultMap注解
- 定义
@Results(id = "userDiyMapper" ,value = {
@Result(id = true,property = "id",column = "id"),
@Result(property = "username",column = "username1"),
@Result(property = "sex",column = "sex1"),
@Result(property = "address",column = "address1"),
})
- 使用
@ResultMap("userDiyMapper")
一对一
@Results(id = "studentMapper",value = {
@Result(id = true,property = "sid",column = "sid"),
@Result(property = "name",column = "name"),
@Result(property = "age",column = "age"),
@Result(property = "sex",column = "sex"),
/**
* property:属性名
* column:调用从表方法时传入的参数列
* one:表示该属性是一个对象
* select:调用的从表方法
* fetchType:加载方式
*/
@Result(property = "classes",column = "classId",
one = @One(select = "com.xl.mapper.ClassesMapper.findByCid",
fetchType =FetchType.EAGER))
})
一对多
@Results(id = "classMapper", value = {
@Result(id = true, property = "cid", column = "cid"),
@Result(property = "className", column = "className"),
// many:表示该属性是一个集合
@Result(property = "studentList", column = "cid",
many = @Many(select = "com.xl.mapper.StudentMapper.findByClassId",
fetchType = FetchType.LAZY))
})
动态sql注解
使用脚本标签
// 根据任意条件查询
@Select("<script>" +
" select * from user\n" +
" <where>\n" +
" <if test=\"username != null and username.length() != 0\">\n" +
" username like #{username}\n" +
" </if>\n" +
" <if test=\"sex != null and sex.length() != 0\">\n" +
" and sex = #{sex}\n" +
" </if>\n" +
" <if test=\"address != null and address.length() != 0\">\n" +
" and address = #{address}\n" +
" </if>\n" +
" </where>" +
"</script>")
List<User> findByCondition(User user);
在方法中构建动态Sql
在MyBatis中有 @SelectProvider 、 @UpdateProvider 、 @DeleteProvider 、@InsertProvider 注解。当使用这些注解时将不在注解中直接编写SQL,而是调用某个类的方法来生成SQL。
- 编写sql
// 生成根据任意条件查询的Sql语句
public String findByConditionSql(User user){
StringBuffer sb = new StringBuffer("select * from user where 1=1");
if (user.getUsername() != null && user.getUsername().length() != 0){
sb.append(" and username like #{username} ");
}
if (user.getSex() != null && user.getSex().length() != 0){
sb.append(" and sex = #{sex} ");
}
if (user.getAddress() != null && user.getAddress().length() != 0){
sb.append(" and address = #{address}");
}
return sb.toString();
}
- 使用sql
@SelectProvider(type = sql类.class,method = "方法名")
测试使用
①、session创建\销毁
private SqlSession session;
private InputStream is;
@Before
public void before(){
try {
// (1)读取核心配置文件
is = Resources.getResourceAsStream("mybatis-config.xml");
// (2)创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// (3)SqlSessionFactoryBuilder对象获取SqlSessionFactory对象
SqlSessionFactory factory = builder.build(is);
// (4)SqlSessionFactory对象获取SqlSession对象
session = factory.openSession();
} catch (IOException e) {
e.printStackTrace();
}
}
@After
public void after(){
session.close();
is.close();
}
②、分页插件使用
// (1)查询前设置分页参数,参数一:页数,从1开始。参数二:每页条数
PageHelper.startPage(1, 3);
// (2)正常查询
List<User> all = userMapper.findAll();
// (3)创建页面对象,创建时将查询结果传入构造方法
PageInfo pageInfo = new PageInfo(all);
// (4)打印页面对象的属性
System.out.println("结果集:"+pageInfo.getList());
System.out.println("总条数:"+pageInfo.getTotal());
System.out.println("总页数"+pageInfo.getPages());
System.out.println("当前页"+pageInfo.getPageNum());
System.out.println("每页条数"+pageInfo.getSize());
③、接口的使用
// 创建接口代理对象
xxxMapper xxxMapper = session.getMapper(xxxMapper.class);
// 新增、更新、删除事务的提交(手动提交)
session.commit();
二、使用mybatis-Spring
导入依赖
<!--mybatis 依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<!-- spring集成 mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<!-- mysql 驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--spring -集成 jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<!--druid 数据库连接池依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!--logback 日志框架-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<!-- 事务管理 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<!--切面相关依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
配置文件
xml版本
db.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
applicationContext.xml
tx:method 中的属性:
属性名 | 作用 |
---|---|
name | 指定配置的方法。 * 表示所有方法, find* 表示所有以find开头的方法。 |
read-only | 只读事务,建议在查询中开启只读事务。 |
timeout | 指定超时时间。 |
rollback-for | 指定某个异常事务回滚,默认所有异常回滚。 |
no-rollback-for | 指定某个异常不回滚,默认所有异常回滚。 |
propagation | 事务的传播行为。 |
isolation | 事务的隔离级别。 |
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 包扫描 -->
<context:component-scan base-package="com.xl.xmlAndAnnotation"></context:component-scan>
<!-- 读取配置文件 -->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<!-- 创建druid数据源对象 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- Spring创建封装过的SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 该对象可以自动扫描持久层接口,并为接口创建代理对象 -->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 配置扫描的接口包 -->
<property name="basePackage" value="com.xl.xmlAndAnnotation.mapper"></property>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 进行事务相关配置 -->
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut id="pointcut" expression="execution(* com.xl.tx.service.*.*(..))"/>
<!-- 配置通知 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
</aop:config>
</beans>
注解版本
@Configuration
@ComponentScan({
"com.xl.annotation.service", "com.xl.annotation.advice"}) //IOC +AOP
@EnableAspectJAutoProxy //AOP
@EnableTransactionManagement // TX
@PropertySource({
"classpath:db.properties", "classpath:param.properties"}) // DI
//@Import(MybatisConfig.class)
public class SpringConfigAll {
//数据源
@Bean("dataSource")
public DataSource getDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
druidDataSource.setUrl("jdbc:mysql://localhost:3306/spring");
druidDataSource.setUsername("root");
druidDataSource.setPassword("root");
return druidDataSource;
}
// SqlSessionFactoryBean
@Bean("sqlSessionFactory")
public SqlSessionFactoryBean getSqlSession(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
// 映射包扫描
@Bean("mapperScanner")
public MapperScannerConfigurer getMapperScanner() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.xl.annotation.mapper");
return mapperScannerConfigurer;
}
//事务管理器
@Bean("transactionManager")
public DataSourceTransactionManager getTransactionManager(DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
}
注解+xml版本
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--############################## IOC ##############################-->
<!-- 注入service -->
<context:component-scan base-package="com.xl.xmlAndAnnotation.service"></context:component-scan>
<!--################################ AOP #################################-->
<!-- 通知对象 -->
<bean id="myAspectJAdvice" class="com.xl.xmlAndAnnotation.advice.MyAspectAdvice"></bean>
<!-- 开启注解支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!--################################ mybatis #################################-->
<!-- 读取配置文件 -->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<!-- 创建druid数据源对象 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- Spring创建封装过的SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 该对象可以自动扫描持久层接口,并为接口创建代理对象 -->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 配置扫描的接口包 -->
<property name="basePackage" value="com.xl.xmlAndAnnotation.mapper"></property>
</bean>
<!--################################ TX #################################-->
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 注册事务注解驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>
使用mybatis
①、开启事务(注解)
- 作用在类上:该类的所有public方法将都具有该类型的事务属性
// 作用于类上时,该类的所有public方法将都具有该类型的事务属性
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
public class AccountService {
}
- 作用在方法上:该方法将都具有该类型的事务属性
@service
public class AccountService {
@Autowired
private AccountMapper accountMapper;
// 作用于方法上时,该方法将都具有该类型的事务属性
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public void transfer(int id1, int id2, double price) {
// account1修改余额
Account account1 = accountMapper.findById(id1);
account1.setBalance(account1.getBalance() - price);
accountMapper.update(account1);
int i = 1 / 0; // 模拟转账出错
// account2修改余额
Account account2 = accountMapper.findById(id2);
account2.setBalance(account2.getBalance() + price);
accountMapper.update(account2);
}
}
三 、使用mybatis-Springboot
导入依赖
<!-- mybatis集成依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<!-- mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
配置文件
# 数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:///student?serverTimezone=UTC
username: root
password: root
# mybatis配置
mybatis:
# 映射文件位置
mapper-locations: mapper/*Mapper.xml
# 别名
type-aliases-package: com.xl.pojo
使用mybatis
@Mapper
@Mapper
public interface StudentMapper {
List<Student> findAll();
}