Spring整合Mybatis(XML配置开发)
1.Spring主配置文件 applicationContext.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--Spring 读取Mybatis的配置文件-->
<import resource="spring-mybatis.xml"/>
<!--整合事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
<!-- 事务配置增强 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--propagation事务的传播特性,REQUIRED没有事务就创建一个,有就加入-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- AOP配置 -->
<aop:config>
<!--切入点(方法通配符)-->
<aop:pointcut id="txPointCut" expression="execution(* com.zdb.mapper.*.*(..))"/>
<!--通知-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
</beans>
2.Spring整合 Mybatis相关配置文件 spring-mybatis.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置Spring自动扫描包 -->
<context:component-scan base-package="com.zdb" />
<!-- 引入配置文件 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean>
<!-- 配置druid连接池 和mybatis-config.xml 中的数据源不可重复定义-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 driverClassName、url、user、password -->
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapper.xml文件 和mybatis-config.xml 中的<mappers>标签作用相同,不可重复定义 -->
<property name="mapperLocations" value="classpath:com/zdb/mapper/*.xml"/>
<!--引入mybatis-config.xml-->
<property name="configLocation" value="classpath:config/mybatis-config.xml"/>
</bean>
<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zdb.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
</beans>
3.Mybatis主配置文件 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?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?-->
<properties resource="properties/jdbc.properties"/>
<!--默认配置-->
<settings>
<setting name="cacheEnabled" value="true"/><!--所有映射器中配置缓存的全局开关-->
<setting name="lazyLoadingEnabled" value="true"/><!--延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。在特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态 -->
<setting name="multipleResultSetsEnabled" value="true"/><!--是否允许单一语句返回多结果集(需要兼容驱动)-->
<setting name="useColumnLabel" value="true"/><!--使用列标签代替列名。不同的驱动会有不同的表现,具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果-->
<setting name="useGeneratedKeys" value="false"/><!--允许JDBC 支持自动生成主键,需要驱动兼容。如果设置为 true,则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)-->
<setting name="autoMappingBehavior" value="PARTIAL"/><!--指定 MyBatis 应如何自动映射列到字段或属性。NONE 表示取消自动映射。PARTIAL 表示只会自动映射,没有定义嵌套结果集和映射结果集。FULL 会自动映射任意复杂的结果集(无论是否嵌套)-->
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/><!--指定自动映射当中未知列(或未知属性类型)时的行为。 默认是不处理,只有当日志级别达到 WARN 级别或者以下,才会显示相关日志,如果处理失败会抛出 SqlSessionException 异常-->
<setting name="defaultExecutorType" value="SIMPLE"/><!--配置默认的执行器。SIMPLE 是普通的执行器;REUSE 会重用预处理语句(prepared statements);BATCH 执行器将重用语句并执行批量更新 -->
<setting name="defaultStatementTimeout" value="25"/><!--设置超时时间,它决定驱动等待数据库响应的秒数-->
<setting name="defaultFetchSize" value="100"/><!--设置数据库驱动程序默认返回的条数限制,此参数可以重新设置-->
<setting name="safeRowBoundsEnabled" value="false"/><!--允许在嵌套语句中使用分页(RowBounds)。如果允许,设置 false-->
<setting name="mapUnderscoreToCamelCase" value="false"/><!--是否开启自动驼峰命名规则映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射-->
<setting name="localCacheScope" value="SESSION"/><!--MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速联复嵌套査询。默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlScssion 的不同调用将不会共享数据-->
<setting name="jdbcTypeForNull" value="OTHER"/><!--当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER-->
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/><!--指定哪个对象的方法触发一次延迟加载-->
</settings>
<!--定义别名 在接口映射的 *Mapper.xml中使用-->
<typeAliases>
<typeAlias type="com.zdb.domain.User" alias="user"/>
</typeAliases>
<!--自定义类型处理器-->
<typeHandlers>
<typeHandler handler="com.zdb.handler.DateTypeHandler"></typeHandler>
</typeHandlers>
<!--引入分页工具-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
<property name="offsetAsPageNum" value="false"/>
<property name="rowBoundsWithCount" value="false"/>
<property name="pageSizeZero" value="true"/>
<property name="reasonable" value="true"/>
<property name="supportMethodsArguments" value="false"/>
<property name="returnPageInfo" value="none"/>
</plugin>
</plugins>
<!--配置数据源环境-->
<environments default="development"><!--默认使用环境-->
<environment id="development"><!--配置一个开发环境:development-->
<!--配置事务管理器-->
<transactionManager type="JDBC"></transactionManager><!--配置事务管理器:JDBC-->
<dataSource type="POOLED"><!--配置数据源连接类型:POOLED连接池、UNPOOLED非连接池,使用时打开不使用时关闭每次需要重新开启、JNDI-->
<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>
<!--加载映射文件方法
1.类路径资源 resource 引用
<mapper resource="com/zdb/mapper/UserMapper.xml"/>
2.绝对位置资源定位符 url 引用
<mapper url="E:\JAVAProject\SpringMybatis\src\main\resources\com\zdb\mapper\UserMapper.xml"/>
3.映射器接口完全限定名 class 引用
<mapper class="com.zdb.builder.UserMapper"/>
4.包下的映射器接口实现全部注册为映射器
<package name = "com.zdb.builder"/>
-->
<!-- 和sqlSessionFactory 的属性配置<property name="mapperLocations" value="classpath:com/zdb/mapper/*.xml"/> 作用相同不可重复定义-->
<!--<mappers>
<mapper resource="com/zdb/mapper/UserMapper.xml"/>
</mappers>-->
</configuration>
4.Mapper接口映射的XML 接口名称.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的映射命名空间(mapper接口类的全包名)-->
<mapper namespace="com.zdb.mapper.UserMapper.xml">
<insert id="save" parameterType="user">
insert into user values (#{id},#{username},#{password})
</insert>
<update id="updateUser" parameterType="user">
update user set username=#{username},password=#{password} where id=#{id}
</update>
<delete id="deleteById" parameterType="int">
delete from user a where a.id=#{value}
</delete>
<select id="findById" resultType="user" parameterType="int">
select * from user where id=#{value}
</select>
<select id="findAll" resultType="user" >
select * from user
</select>
</mapper>
5.Mapper接口
public interface UserMapper {
public int save(User user) throws IOException;
public int updateUser(User user) throws IOException;
public int deleteById(int id) throws IOException;
public int findById(int id) throws IOException;
public List<User> findAll() throws IOException;
}
6.其他配置文件
jdbc.properties
#MySQL
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/testMybatis?useUnicode=true&characterEncoding=utf8&userSSL=false&serverTimezone=GMT%2B8
jdbc.username=root
jdbc.password=123456
log4j.properties
log4j.rootLogger=debug, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=5
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
7.测试类
普通测试
public class Test {
private UserMapper mapper;
@Before
public void before() throws IOException {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
mapper = ctx.getBean("userMapper",UserMapper.class);
}
@Test
public void testFindAll() throws IOException {
List<User> all = mapper.findAll();
for (User user : all) {
System.out.println(user);
}
}
}
Junit测试(自动注入对象)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class JunitTest {
@Autowired
private UserMapper userMapper;
@Test
public void testFindAll() throws IOException {
List<User> all = userMapper.findAll();
for (User user : all) {
System.out.println(user);
}
}
}
Spring整合Mybatis(注解开发)
两种启用此配置文件的方式(为了区分主配置,使用第一种方式)
1.在Spring的主配置类中进行@Import(MybatisConfig.class)注解导入
2.在本类上添加@Configuration 注解
Spring配置类代码
//定义该类为Spring配置类
@Configuration
//开启切面
@EnableAspectJAutoProxy
//读取包下定义的Bean
@ComponentScan("com.zdb")
//导入其他配置类
@Import({MybatisConfig.class,JdbcConfig.class})
//导入properties文件
@PropertySource("classpath:jdbc.properties")
//开启Spring事务管理 (在需要管理的类、接口或方法上添加 @Transactional 注解)
@EnableTransactionManagement
public class SpringConfig {
}
数据源相关配置类代码
public class JdbcConfig {
@Value("jdbc.driver")
private String driver;
@Value("jdbc.url")
private String url;
@Value("jdbc.username")
private String username;
@Value("jdbc.password")
private String password;
//数据源配置
@Bean
public DataSource dataSource(){
DruidDataSource dataSource=new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUserName(username);
dataSource.setPassword(password);
return dataSource;
}
//事务管理器
@Bean
public PlatformTransactionManager transactionManager(DataSource datasource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(datasource);
return dataSourceTransactionManager;
}
}
Mybatis相关配置类代码
/**
* @Author: zhoudb
* @Description: 创建 Mybatis 的配置类
* @Param: 提前交给Spring装配好的 dataSource (参数自动注入)
* @return: sqlSessionFactory工厂对象
*/
public class MybatisConfig {
//创建 sqlSessionFactory 的Bean对象
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setTypeAliasesPackage("实体类全包名");
sqlSessionFactory.setDataSource(dataSource);
return sqlSessionFactory;
}
/* 配置 Mapper 映射 相当于Mybatis主配置文件中的以下代码
<mappers>
<!--加载映射文件方法
1.类路径资源 resource 引用(xml配置开发使用)
<mapper resource="com/zdb/mapper/UserMapper.xml"/>
2.绝对位置资源定位符 url 引用(xml配置开发使用)
<mapper url="E:\JAVAProject\SpringMybatis\src\main\resources\com\zdb\mapper\UserMapper.xml"/>
3.映射器Mapper接口完全限定名 class 引用(注解开发使用)
<mapper class="com.zdb.mapper.UserMapper"/>
4.包下的映射器接口实现全部注册为映射器(注解开发使用)
<package name = "com.zdb.mapper"/>
-->
<package name = "com.zdb.mapper"/>
</mappers>
* */
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("需要Mybatis动态代理实现的接口全包名");
return mapperScannerConfigurer;
}
}
mapper接口
public interface UserMapper {
@Insert("insert into user(id,username,password) values (#{id},#{username},#{password})")
public int save(User user) throws IOException;
@Update("update user set username=#{username},password=#{password} where id=#{id}")
public int updateUser(User user) throws IOException;
@Delete("delete from user a where a.id=#{value}")
public int deleteById(int id) throws IOException;
@Select("select * from user where id=#{value}")
public User findById(int id) throws IOException;
@Select("select * from user")
public List<User> findAll() throws IOException;
}
普通测试
public class Test {
private UserMapper mapper;
@Before
public void before() throws IOException {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
mapper = ctx.getBean("userMapper",UserMapper.class);
}
@Test
public void testFindAll() throws IOException {
List<User> all = mapper.findAll();
for (User user : all) {
System.out.println(user);
}
}
}
Junit测试(自动注入对象)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class JunitTest {
@Autowired
private UserService userService;
//注入有异常提示,但是可以使用 userMapper
@Autowired
private UserMapper userMapper;
@Test
public void testFindAll1() throws IOException {
List<User> all = userMapper.findAll();
for (User user: all) {
System.out.println(user);
}
}
@Test
public void testFindAll2() throws IOException {
List<User> all = userService.findAll();
for (User user: all) {
System.out.println(user);
}
}
}