文章目录
前言
目前大部分的 Java 互联网项目,都是用 Spring MVC + Spring + MyBatis 搭建平台的。
使用 Spring IoC 可以有效的管理各类的 Java 资源,达到即插即拔的功能;通过 Spring AOP 框架,数据库事务可以委托给 Spring 管理,消除很大一部分的事务代码,配合 MyBatis 的高灵活、可配置、可优化 SQL 等特性,完全可以构建高性能的大型网站。
毫无疑问,MyBatis 和 Spring 两大框架已经成了 Java 互联网技术主流框架组合,它们经受住了大数据量和大批量请求的考验,在互联网系统中得到了广泛的应用。使用 MyBatis-Spring 使得业务层和模型层得到了更好的分离,与此同时,在 Spring 环境中使用 MyBatis 也更加简单,节省了不少代码,甚至可以不用 SqlSessionFactory、 SqlSession 等对象,因为 MyBatis-Spring 为我们封装了它们。
摘自:《Java EE 互联网轻量级框架整合开发》
资源下载
链接: https://pan.baidu.com/s/1dW_k20Gbr0tnTIjgAjjRvw
提取码: g826
第二个项目使用了注解实现
1.建立项目
在IDEA中建立web项目:MybatisAndSpring
创建如图所示的文件
2.编写数据库配置文件db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8
jdbc.username=用户名
jdbc.password=密码
jdbc.url里面的数据库名根据自己的改
3.编写 Spring 配置文件applicationContext
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--向 Spring 容器注册4 个BeanPostProcessor(这四个名字太长不写了),能识别注解好用注解开发Spring-->
<context:annotation-config />
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!--配置连接数据库数据源,数据库配置在db.properties-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置XML扫描文件-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="typeAliasesPackage" value="pojo" />
<!-- 加载 MyBatis 的配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/CategoryMapper.xml"/>
</bean>
<!-- DAO 接口 -->
<bean id="categoryDAO" class="dao.CategoryDAOImpl">
<property name="sqlSessionFactory" ref="sqlSession"/>
</bean>
</beans>
<context:annotation-config />
能使用注解开发spring“context:property-placeholder”
配置是用于读取工程中的静态属性文件,然后在其他配置中使用时,就可以采用 “${属性名}” 的方式获取该属性文件中的配置参数值。
4.编写 MyBatis 配置文件mybatis-config.xml
有了 Spring 托管数据源,在 MyBatis 配置文件中仅仅需要关注性能化配置,比如延迟加载和缓存。
不再需要编写连接数据库和映射文件。
我这个项目啥都没写,就设置了别名。很真实
<!--设置别名-->
<typeAliases>
<package name="pojo"/>
</typeAliases>
5.编写Category
package pojo;
public class Category {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Category [id=" + id + ", name=" + name + "]";
}
}
5.编写CategoryMapper
<?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="dao.CategoryDAO">
<insert id="add" parameterType="Category" >
insert into category_ ( name ) values (#{name})
</insert>
<delete id="delete" parameterType="Category" >
delete from category_ where id= #{id}
</delete>
<select id="get" parameterType="_int" resultType="Category">
select * from category_ where id= #{id}
</select>
<update id="update" parameterType="Category" >
update category_ set name=#{name} where id=#{id}
</update>
<select id="list" resultType="Category">
select * from category_
</select>
</mapper>
- 在该配置中,输出参数的映射为 “Category”,是因为在mybatis-config.xml中配置了别名
6.编写DAO层
接口CategoryDAO:
package dao;
import pojo.Category;
import java.util.List;
public interface CategoryDAO {
int add(Category category);
int delete(int id);
Category get(int id);
int update(Category category);
List<Category> list();
int count();
}
实现接口CategoryDAO:
package dao;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import pojo.Category;
import java.util.List;
public class CategoryDAOImpl extends SqlSessionDaoSupport implements CategoryDAO
{
@Override
public int add(Category category) {
return 0;
}
@Override
public int delete(int id) {
// 继承 SqlSessionDaoSupport 类,通过 this.getSqlSession() 得到 sqlSession
SqlSession sqlSession = this.getSqlSession();
return sqlSession.delete("dao.CategoryDAO.delete", id);
}
@Override
public Category get(int id) {
// 继承 SqlSessionDaoSupport 类,通过 this.getSqlSession() 得到 sqlSession
SqlSession sqlSession = this.getSqlSession();
return sqlSession.selectOne("dao.CategoryDAO.get", id);
}
@Override
public int update(Category category) {
// 继承 SqlSessionDaoSupport 类,通过 this.getSqlSession() 得到 sqlSession
SqlSession sqlSession = this.getSqlSession();
return sqlSession.update("dao.CategoryDAO.update",category);
}
@Override
public List<Category> list() {
// 继承 SqlSessionDaoSupport 类,通过 this.getSqlSession() 得到 sqlSession
SqlSession sqlSession = this.getSqlSession();
return sqlSession.selectList("dao.CategoryDAO.list");
}
@Override
public int count() {
return 0;
}
}
- UserDAOImpl 不仅实现了 UserDAO 接口,而且继承了 SqlSessionDaoSupport 类。
- SqlSessionDaoSupport 类是 MyBatis 与 Spring 整合的 jar 包中提供的,在该类中已经包含了 sqlSessionFactory 对象作为其成员变量,而且对外提供 get 和 set 方法,方便 Spring 从外部注入 sqlSessionFactory 对象。
- UserDAOImpl 类要成功获取 sqlSessionFactory 对象,还需要在 Spring 配置文件 applicationContext.xml 中添加 userDAO 的 bean 配置,将其中定义的 sqlSessionFactory 对象当做参数注入进去,这样 UserDAOImpl 继承 SqlSessionDaoSupport 类才会起到作用:
也就是applicationContest.xml中的:
<!-- DAO 接口 -->
<bean id="userDAO" class="cn.wmyskxz.dao.UserDAOImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
- 注意: DAO 实现类继承了 SqlSessionDaoSupport 父类后,就无须自己定义获取 SqlSession 会话实例类方法了,该父类会默认加载数据源信息并提供获取 SqlSession 类的方法。
7.编写测试类MybatisTest
import java.util.List;
import dao.CategoryDAO;
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 pojo.Category;
//使用Spring注解方式测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= "file:src/main/resources/applicationContext.xml")
public class MybatisTest
{
@Autowired
//拿到注入的categoryDAO对象
private CategoryDAO categoryDAO;
@Test
public void testAdd()
{
Category category = new Category();
//向category_中添加category3
category.setName("category3");
//调用add方法的时候,会自动去找Category.xml里id="add"的sql语句。
categoryDAO.add(category);
}
@Test
public void testList()
{
System.out.println(categoryDAO);
List<Category> cs= categoryDAO.list();
for (Category c : cs) {
System.out.println(c.getName());
}
}
}
注解的作用:
-
@RunWith就是一个运行器
-
@RunWith(JUnit4.class)就是指用JUnit4来运行
-
@RunWith(SpringJUnit4ClassRunner.class),让测试运行于Spring测试环境
-
@RunWith(Suite.class)的话就是一套测试集合
-
@ContextConfiguration Spring整合JUnit4测试时,使用注解引入多个配置文件
-
单个文件
@ContextConfiguration(Locations=“classpath:applicationContext.xml”)
@ContextConfiguration(classes = SimpleConfiguration.class) -
多个文件时,可用
@ContextConfiguration(locations = { “classpath:spring1.xml”, “classpath:spring2.xml” })
8.运行
dao.CategoryDAOImpl@4678a2eb
category1
category2
category3
9.动态代理 + 注解实现
上面的实例程序并没有使用 Mapper 动态代理和注解来完成,下面我们就来试试如何用动态代理和注解:
9.1.编写mybatis-config.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--向 Spring 容器注册4 个BeanPostProcessor(这四个名字太长不写了),能识别注解好用注解开发Spring-->
<context:annotation-config />
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!--配置连接数据库数据源,数据库配置在db.properties-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置XML扫描文件-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="typeAliasesPackage" value="pojo" />
<!-- 加载 MyBatis 的配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- Mapper 扫描器 -->
<!--使用这个我们获取的不再是 categoryDAO 对象,而是定义的 Mapper 代理对象 CategoryMapper:-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--扫描包mapper下的mapper-->
<property name="basePackage" value="mapper"/>
</bean>
</beans>
- 在 applicationContext.xml 配置文件中配置的 mapper 批量扫描器类,会从 mapper 包中扫描出 Mapper 接口,自动创建代理对象并且在 Spring 容器中注入。自动扫描出来的 Mapper 的 bean 的 id 为 mapper 类名(首字母小写),所以这里获取的就是名为 “categoryMapper” 的 mapper 代理对象。
- 可以手动getBean()来得到categoryMapper,也可以不写自动得到
9.2.包mapper中建立接口CategoryMapper
package mapper;
import org.apache.ibatis.annotations.Select;
import pojo.Category;
import java.util.List;
public interface CategoryMapper
{
@Select("select * from category_")
List<Category> list();
}
9.3.编写测试类
import java.util.List;
import mapper.CategoryMapper;
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 pojo.Category;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= "file:src/main/resources/applicationContext.xml")
public class MybatisTest
{
@Autowired
private CategoryMapper categoryMapper;
@Test
public void testList()
{
System.out.println(categoryMapper);
List<Category> cs= categoryMapper.list();
for (Category c : cs) {
System.out.println(c.getName());
}
}
}
9.4.运行:
org.apache.ibatis.binding.MapperProxy@4879f0f2
category1
category2
category3
9.5.项目结构:
要简单了很多