Mybatis和Spring的整合可以使用XML的方式和全注解的方式
一、使用XML的方式
- 导入相关的jar包(Mybatis,Spring以及数据库,日志),如图所示
- 整个架构分包:domain,mapper(相当于dao),service,test
- domain
package com._520it.domain; import java.io.Serializable; import org.apache.ibatis.type.Alias; //起别名 @Alias("user") //要实现缓存必须给对象实现序列化接口 public class User implements Serializable{ private static final long serialVersionUID = 1L; private Long id; private String name; private String email; private Integer age; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String toString() { return "User [id=" + id + ", name=" + name + ", email=" + email + ", age=" + age + "]"; } }
- mapper
package com._520it.mapper; import java.util.List; public interface UserMapper<T> { void save(T u); void delete(Long id); void update(T u); T get(Long id); List<T> list(); }
<?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._520it.mapper.UserMapper"> <cache type="ehcache"/> <resultMap type="com._520it.domain.User" id="select_mapping"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="email" property="email"/> <result column="age" property="age"/> </resultMap> <insert id="save" keyColumn="id" keyProperty="id" useGeneratedKeys="true" > insert into user(name,email,age) values(#{name},#{email},#{age}); </insert> <update id="update"> update user set name=#{name},email=#{email},age=#{age} where id=#{id}; </update> <delete id="delete"> delete from user where id=#{id}; </delete> <select id="get" resultMap="select_mapping"> select * from user where id=#{id}; </select> <select id="list" resultMap="select_mapping"> select * from user </select> </mapper>
- service
package com._520it.service; import java.util.List; public interface IUservice<T> { void save(T u); void delete(Long id); void update(T u); T get(Long id); List<T> list(); }
package com._520it.service; import java.util.List; import com._520it.domain.User; import com._520it.mapper.UserMapper; public class UserServiceImpl implements IUservice<User>{ private UserMapper<User> mapper; public void setMapper(UserMapper<User> mapper) { this.mapper = mapper; } public void save(User u) { //模拟出错 //int i=1/0; mapper.save(u); } public void delete(Long id) { mapper.delete(id); } public void update(User u) { mapper.update(u); } public User get(Long id) { return mapper.get(id); } public List<User> list() { return mapper.list(); } }
- test
package com._520it.test; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com._520it.domain.User; import com._520it.service.IUservice; /* * 添加RunWith标签 * 1.告诉JUnit,测试开始的时候启动spring容器,结束的时候关闭spring容器 * 2.将当前的测试类也交给spring容器管理 */ @RunWith(SpringJUnit4ClassRunner.class) /* * 告诉spring从什么地方加载配置文件,默认情况下使用相对路径加载,也可使用classpath前缀 * 在ContextConfiguration标签中也可以不写配置文件地址,满足两个条件 * 1.配置文件和测试类在同一目录 * 2.配置文件名形式:测试类-content.xml * */ @ContextConfiguration public class UserServiceTest { //Autowired:将spring创建好的容器的引用赋给该字段 @Autowired private IUservice<User> service; User u=new User(); @Test public void testSave(){ u.setName("金毛狮王"); service.save(u); } @Test public void testUpdate(){ u=service.get(20L); u.setName("谢逊"); service.update(u); } @Test public void testList(){ System.out.println(service.list()); } @Test public void testDelete(){ service.delete(20L); } }
<?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 引入数据库配置文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 配置数据库 --> <!-- destroy-method=close:当数据库连接不使用的时候,把该连接重新放到连接池中下次使用 --> <bean id="dataSource" class=" com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="driverClassName" value="${db.driverClassName}"/> <property name="url" value="${db.url}"/> <property name="username" value="${db.username}"/> <property name="password" value="${db.password}"/> </bean> <!-- 配置SqlSessionFactory --> <bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 只要用的是Resource来接收属性的,都可以用classpath前缀 --> <!-- 在一个应用中可以有多个类加载器,不同的类加载器不能互相访问 classpath*:在不同的类加载器中加载文件 --> <property name="configLocation" value="classpath:mybatis-cfg.xml"/> <property name="mapperLocations" value="classpath:com/_520it/mapper/*.xml"/> <property name="dataSource" ref="dataSource"/> <!-- 映射对象的别名,如果有多个映射对象在不同的包中,value中的包名用;分割 --> <property name="typeAliasesPackage" value="com._520it.domain"/> </bean> <!-- 抽象出一个公共的mapper,如果有多个mapper接口的话,可以直接继承 --> <bean id="baseMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true"></bean> <!-- 配置mapper,用来生产UserMapper对象 --> <bean id="mapper" parent="baseMapper"> <!-- 给MapperFactoryBean一个用到的mapper接口 --> <property name="mapperInterface" value="com._520it.mapper.UserMapper"/> </bean> <bean id="userService" class="com._520it.service.UserServiceImpl"> <property name="mapper" ref="mapper"></property> </bean> <!-- 配置事务管理器 --> <bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置AOP --> <aop:config> <!-- 切点 --> <aop:pointcut expression="execution(* com._520it.*service.*(..))" id="crudPC"/> <!-- 配置事务切面(属性+切点) --> <aop:advisor advice-ref="txAdvice" pointcut-ref="crudPC"/> </aop:config> <!-- 配置事务属性 --> <tx:advice id="txAdvice" transaction-manager="tx"> <tx:attributes> <tx:method name="get*" read-only="true"/> <tx:method name="list" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> </beans>
- mybatis的配置文件
日志配置<?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"> <!-- mybatis的配置文件 --> <configuration> <!-- 引入数据库配置文件 --> <properties resource="db.properties"/> <!-- 配置Mybatis的默认运行模式 --> <settings> <!-- 配置延迟加载 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 按需加载,用到的话就加载 --> <setting name="aggressiveLazyLoading" value="false"/> <!-- 设置哪些方法被延迟加载 --> <setting name="lazyLoadTriggerMethods" value="clone"/> <!-- Mybatis的自带缓存,默认开启(true) --> <setting name="cacheEnabled" value="true"/> </settings> <!-- 为Mapper里的类型添加别名 ,即paramterMap--> <typeAliases> <typeAlias type="org.mybatis.caches.ehcache.EhcacheCache" alias="ehcache"/> </typeAliases> <!-- mybatis的数据库连接环境 --> <environments default="default"> <!-- 默认的环境 --> <environment id="default"> <!-- mybatis的事务管理器,使用的jdbc的事务 --> <transactionManager type="JDBC"/> <!-- mybatis的数据库连接池,type属性值大写 --> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> </configuration>
# Global logging configuration log4j.rootLogger=ERROR, stdout # MyBatis logging configuration... #\u628A\u540E\u9762\u7684\u5305\u4FEE\u6539\u4E3A\u8981\u76D1\u63A7\u7684mapper\u6240\u5728\u7684\u5305(\u5305\u53CA\u5176\u5B50\u5305\u7684\u6240\u6709mapper\u7684\u8FD0\u884C\u8FC7\u7A0B\u4E2D\u7684sql\u548C\u53C2\u6570) log4j.logger.com._520it=TRACE # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
二、使用全注解配置
- 全注解和XML配置的不同之处
@Service public class UserServiceImpl implements IUservice<User>{ @Autowired private UserMapper<User> mapper;
<?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- ----------------------------------------------------------------------- --> <!-- 开启注解方式 --> <context:annotation-config/> <!-- 扫描带有标签的包 --> <context:component-scan base-package="com._520it.service"/> <!-- 引入数据库配置文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- ----------------------------------------------------------------------- --> <!-- 配置数据库 --> <!-- destroy-method=close:当数据库连接不使用的时候,把该连接重新放到连接池中下次使用 --> <bean id="dataSource" class=" com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="driverClassName" value="${db.driverClassName}"/> <property name="url" value="${db.url}"/> <property name="username" value="${db.username}"/> <property name="password" value="${db.password}"/> </bean> <!-- 配置SqlSessionFactory --> <bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 只要用的是Resource来接收属性的,都可以用classpath前缀 --> <!-- 在一个应用中可以有多个类加载器,不同的类加载器不能互相访问 classpath*:在不同的类加载器中加载文件 --> <property name="configLocation" value="classpath:mybatis-cfg.xml"/> <property name="mapperLocations" value="classpath:com/_520it/mapper/*.xml"/> <property name="dataSource" ref="dataSource"/> <!-- 映射对象的别名,如果有多个映射对象在不同的包中,value中的包名用;分割 --> <property name="typeAliasesPackage" value="com._520it.domain"/> </bean> <!-- ----------------------------------------------------------------------- --> <!-- 配置自动扫描mapper --> <!-- MapperScannerConfigurer能够 1.扫描传入的包中的mapper接口, 2.将这些mapper实例化成对象 3.将这些对象交给spring管理 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com._520it.mapper"></property> </bean> <!-- ----------------------------------------------------------------------- --> <!-- 配置事务管理器 --> <bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置AOP --> <aop:config> <!-- 切点 --> <aop:pointcut expression="execution(* com._520it.*service.*(..))" id="crudPC"/> <!-- 配置事务切面(属性+切点) --> <aop:advisor advice-ref="txAdvice" pointcut-ref="crudPC"/> </aop:config> <!-- 配置事务属性 --> <tx:advice id="txAdvice" transaction-manager="tx"> <tx:attributes> <tx:method name="get*" read-only="true"/> <tx:method name="list" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> </beans>
三、第一次写CSD博客,没想到格式处理这么困难,心好累!!