spring和mybatis的整合笔记
1、整合过程
- 导入项目所需要的jar。
从我们这里可以看出,需要spring的所有包,mybatis的所有包,连接数据库的包,另外加了一个spring和mybatis的整合包,我们为了方便加入了日志功能。
- 我们这里用了mybatis的数据库,所以我们直接就可以创建实体类与之对应就可以。t_product,t_category,t_review。
package com.domain;
public class Review {
private Integer id;
private String value;
public Review() {
}
public Review(Integer id, String value) {
this.id = id;
this.value = value;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "Review{" +
"id=" + id +
", value='" + value + '\'' +
'}';
}
}
package com.domain;
public class Product {
private Integer id;
private String productName;
private Review review;
public Product() {
}
public Product(Integer id, String productName, Review review) {
this.id = id;
this.productName = productName;
this.review = review;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Review getReview() {
return review;
}
@Override
public String toString() {
return "Product{" +
"id=" + id +
", productName='" + productName + '\'' +
", review=" + review +
'}';
}
public void setReview(Review review) {
this.review = review;
}
}
package com.domain;
import java.util.List;
public class Category {
private Integer id;
private String categoryName;
private List<Product> products;
public Category() {
}
public Category(Integer id, String categoryName, List<Product> products) {
this.id = id;
this.categoryName = categoryName;
this.products = products;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
@Override
public String toString() {
return "Category{" +
"id=" + id +
", categoryName='" + categoryName + '\'' +
", products=" + products +
'}';
}
}
- 我们开始写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:context="http://www.springframework.org/schema/context"
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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--设置包扫描-->
<context:component-scan base-package="com"/>
<!--加载数据库驱动-->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/te01?characterEncoding=UTF-8"></property>
<property name="username" value="root"></property>
<property name="password" value="12345"></property>
</bean>
<!--第一个方式配置mybatis-config.xml文件-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="mybatis/mybatis-config.xml"/>
</bean>
<!--事务的配置-->
<tx:annotation-driven/>
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.service.*.*(..))"></aop:advisor>
</aop:config>
</beans>
代码一行一行解读:
- 这里使用了包扫描,因为我们要在类上面加上注解,使用注解就要扫描包,扫描出带有注解的类。
- 加载数据库信息,我们在mybatis中是在mybatis-config.xml 中写数据库信息的,我们现在在这里写是因为我么要用一个DataSource数据源,也可以理解为applicationContext.xml的重要位置,一般重要的内容都在applicationContext.xml。
- 我们配置sqlsessionFactory,这样我们可以理解,我们现在配置需要将两个整合,那么需要将两个配置文件整合,而这一步就是整合两个,mybatis中用到了sqlsessionFactory,我们可以bean化sqlsessionFactory所以这两个连接起来了。
- 接下来是事务的配置。
- 接下来我们需要配置一个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>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!--起别名-->
<typeAliases>
<package name="com.domain"/>
</typeAliases>
<mappers>
<mapper resource="mappers/CategoryMapper.xml"></mapper>
</mappers>
</configuration>
这里只需要将我们要配置日志模块,所以要加一个setting标签。(粘贴即可)
- 我们写出Dao层的接口,因为我们要实现哪些方法。
import com.domain.Category;
import java.util.List;
public interface ICategory {
public List<Category> selectAll();
}
- 写完接口,我们下一步就可以直接写mapper文件了。
<?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.dao.ICategory">
<select id="selectAll" resultMap="CategoryMap">
SELECT * FROM t_category c, t_product p, t_review r WHERE c.`c_id` = p.`c_id` AND p.`p_id` = r.`p_id`
</select>
<resultMap id="CategoryMap" type="Category">
<id property="id" column="c_id"/>
<result property="categoryName" column="c_name"/>
<collection property="products" ofType="Product">
<id property="id" column="p_id"/>
<result property="productName" column="p_name"/>
<association property="review" javaType="Review">
<id property="id" column="r_id"/>
<result property="value" column="r_value"/>
</association>
</collection>
</resultMap>
</mapper>
- 我们刚刚使用了log,我们那么就需要配置一个log4j.properties文件
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com=DEBUG
# 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
- 写完这些后,我们就开始写业务层了,接口和实现类。
package com.service;
import com.domain.Category;
import java.util.List;
public interface ICategoryService {
public List<Category> selectAll();
}
package com.service.impl;
import com.dao.ICategory;
import com.domain.Category;
import com.service.ICategoryService;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class CategoryServiceImpl implements ICategoryService {
@Resource
private SqlSessionFactory sqlSessionFactory;
@Override
public List<Category> selectAll() {
SqlSession sqlSession = sqlSessionFactory.openSession();
ICategory category = sqlSession.getMapper(ICategory.class);
return category.selectAll();
}
}
我们可以这样理解,为什么要写service,我们在使用mybatis的时候,需要调用sqlsession,它是由别的类创建出的,方法的调用就是执行代码,我们可以写在service中,代替了测试类执行代码。从而使上层的类调用service继续向下执行。
- 写出测试类进行测试
package com.TestProject;
import com.service.ICategoryService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.annotation.Resource;
public class Test1 {
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
ICategoryService categoryService = context.getBean(ICategoryService.class);
System.out.println(categoryService.selectAll());
}
}