MyBatis关联查询&Spring整合

目录

 

一.MyBatis关联查询

1.1 一对一关联

1.1.1 方式一 使用resultType

1.1.2 方法二 使用resultMap

1.2 一对多关联

二.Mybatis整合spring

2.1 整合思路

2.2 整合步骤

2.3 整合dao开发

2.3.1 传统Dao开发

2.3.2 Mapper代理模式开发Dao


一.MyBatis关联查询

1.1 一对一关联

1.1.1 方式一 使用resultType

需求:查询订单关联该订单所属的用户信息

①新建OrderUser的pojo,继承自Order。

public class OrderUser extends Order {
	
	private String username;// 用户姓名
	private String address;// 地址
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "OrderUser [username=" + username + ", address=" + address + ", getId()=" + getId() + ", getUserId()="
				+ getUserId() + ", getNumber()=" + getNumber() + ", getCreatetime()=" + getCreatetime() + ", getNote()="
				+ getNote() + "]";
	}
	
}

②修改order的映射文件,新增查询方法getOrderUser。

<!-- 一对一关联查询,使用resultType -->
	<select id="getOrderUser" resultType="orderuser">
		SELECT
		  o.`id`,
		  o.`user_id` userId,
		  o.`number`,
		  o.`createtime`,
		  o.`note`,
		  u.`username`,
		  u.`address`
		FROM `order` o
		LEFT JOIN `user` u
		ON u.id = o.`user_id`
	</select>

1.1.2 方法二 使用resultMap

①改造order的pojo

public class Order {
	private Integer id;

	private Integer userId;

	private String number;

	private Date createtime;

	private String note;
	
	private User user;
	
	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number == null ? null : number.trim();
	}

	public Date getCreatetime() {
		return createtime;
	}

	public void setCreatetime(Date createtime) {
		this.createtime = createtime;
	}

	public String getNote() {
		return note;
	}

	public void setNote(String note) {
		this.note = note == null ? null : note.trim();
	}

	@Override
	public String toString() {
		return "Order [id=" + id + ", userId=" + userId + ", number=" + number + ", createtime=" + createtime
				+ ", note=" + note + "]";
	}

②修改order的映射文件

<!-- 一对一关联查询-resultMap -->
	<resultMap type="order" id="order_user_map">
		<!-- id标签用于绑定主键 -->
		<id property="id" column="id"/>
		<!-- 使用result绑定普通字段 -->
		<result property="userId" column="user_id"/>
		<result property="number" column="number"/>
		<result property="createtime" column="createtime"/>
		<result property="note" column="note"/>
		
		<!-- association:配置一对一关联
			 property:绑定的用户属性
			 javaType:属性数据类型,支持别名
		-->
		<association property="user" javaType="mybatis.pojo.User">
			<id property="id" column="user_id"/>
			
			<result property="username" column="username"/>
			<result property="address" column="address"/>
			<result property="sex" column="sex"/>
		</association>
	</resultMap>
	<!-- 一对一关联查询-使用resultMap -->
	<select id="getOrderUser2" resultMap="order_user_map">
		SELECT
		  o.`id`,
		  o.`user_id`,
		  o.`number`,
		  o.`createtime`,
		  o.`note`,
		  u.`username`,
		  u.`address`,
		  u.`sex`
		FROM `order` o
		LEFT JOIN `user` u
		ON u.id = o.`user_id`
	</select>

1.2 一对多关联

需求:查询用户关联该用户的订单信息

①改造user的pojo

②修改user的映射文件

<!-- 一对多关联查询 -->
	<resultMap type="user" id="user_order_map">
		<id property="id" column="id" />
		<result property="username" column="username" />
		<result property="birthday" column="birthday" />
		<result property="address" column="address" />
		<result property="sex" column="sex" />
		<result property="uuid2" column="uuid2" />
		
		<!-- collection:配置一对多关系
			 property:用户下的order属性
			 ofType:property的数据类型,支持别名
		-->
		<collection property="orders" ofType="order">
			<!-- id标签用于绑定主键 -->
			<id property="id" column="oid"/>
			<!-- 使用result绑定普通字段 -->
			<result property="userId" column="id"/>
			<result property="number" column="number"/>
			<result property="createtime" column="createtime"/>
		</collection>

	</resultMap>
	<!-- 一对多关联查询 -->
	<select id="getUserOrder" resultMap="user_order_map">
		SELECT
		u.`id`,
		u.`username`,
		u.`birthday`,
		u.`sex`,
		u.`address`,
		u.`uuid2`,
		o.`id` oid,
		o.`number`,
		o.`createtime`
		FROM `user` u
		LEFT JOIN `order` o
		ON o.`user_id` = u.`id`
	</select>

二.Mybatis整合spring

2.1 整合思路

  • SqlSessionFactory对象应该放到spring容器中作为单例存在。
  • 传统dao的开发方式中,应该从spring容器中获得sqlsession对象。
  • Mapper代理形式中,应该从spring容器中直接获得mapper的代理对象。
  • 数据库的连接以及数据库连接池事务管理都交给spring容器来完成。

2.2 整合步骤

  • 创建一个java工程。
  • 导入jar包。
  • mybatis的配置文件sqlmapConfig.xml
  • 编写Spring的配置文件
    • 数据库连接及连接池
    • sqlsessionFactory对象,配置到spring容器中
    • 编写Spring的配置文件
  • 复制jdbc.properties配置文件到新工程
  • 复制log4j.properties配置文件到新工程

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

   <!-- 加载配置文件 -->
   <context:property-placeholder location="classpath:jdbc.properties" />

	<!-- 数据库连接池 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<!-- 连接池的最大数据库连接数 -->
		<property name="maxActive" value="10" />
		<!-- 最大空闲数 -->
		<property name="maxIdle" value="5" />
	</bean>
	
	<!-- SqlSessionFactory配置 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<!-- 加载mybatis核心配置文件 -->
		<property name="configLocation" value="classpath:SqlMapConfig.xml" />
		<!-- 别名包扫描 -->
		<property name="typeAliasesPackage" value="mybatis.pojo" />
	</bean>
	
	<!-- 传统Dao配置 -->
	<bean class="mybatis.dao.impl.UserDaoImpl">
		<property name="sqlSessionFactory" ref="sqlSessionFactory" />
	</bean>
	
	<!-- 动态代理配置方式:第一种 -->
	<!-- <bean id="baseMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true" lazy-init="true">
      <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean> -->
 	<!-- 配置一个接口 -->
    <!-- <bean parent="baseMapper">
      <property name="mapperInterface" value="mybatis.mapper.UserMapper" />
    </bean> -->
    
    <!-- 动态代理,第二种方式:包扫描(推荐): -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    	<!-- basePackage多个包用","分隔 -->
    	<!-- <property name="basePackage" value="mybatis.mapper" /> -->
    	<property name="basePackage" value="com.itheima.ssm.mapper" />
    </bean>
</beans>

SqlMapConfig.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>
	<mappers>
		<mapper resource="mybatis/user.xml"/>
	</mappers>
</configuration>

2.3 整合dao开发

2.3.1 传统Dao开发

  • 复制user.xml到新工程,并修改,只留下要测试的三个方法
  • 在SqlMapConfig.xml加载user.xml
  • 复制UserDao接口到新工程,并修改,只留下要测试的三个方法
  • 编写UserDaoImpl实现类,关键是继承SqlSessionDaoSupport
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {

	@Override
	public User getUserById(Integer id) {
		SqlSession sqlSession = super.getSqlSession();
		//查询用户
		User user = sqlSession.selectOne("user.getUserById", id);
		
		//不能关闭SqlSession
		//sqlSession.close();
		return user;
	}

	@Override
	public List<User> getUserByUserName(String name) {
		SqlSession sqlSession = super.getSqlSession();
		List<User> list = sqlSession.selectList("user.getUserByName", name);
		//不能关闭SqlSession
		return list;
	}

	@Override
	public void insertUser(User user) {
		SqlSession sqlSession = super.getSqlSession();
		sqlSession.insert("user.insertUser", user);
		//不用手动提交事务,交给spring
	}
}
  • 在applicationContext.xml中配置UserDaoImpl实现类
<!-- 传统dao  -->
	<bean class="com.itheima.mybatis.dao.impl.UserDaoImpl">
		<property name="sqlSessionFactory" ref="sqlSessionFactory" />
	</bean>
  • 编写测试类,新建单完测试类
public class UserDaoTest {
	
	private ApplicationContext applicationContext;
	
	@Before
	public void init(){
		applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	}

	@Test
	public void testGetUserById() {
		UserDao userDao = applicationContext.getBean(UserDao.class);
		User user = userDao.getUserById(10);
		System.out.println(user);
	}
………省略其它方法
}

2.3.2 Mapper代理模式开发Dao

  • 复制UserMapper.xml到新工程,并修改,只留下要测试的三个方法
  • 复制UserMapper接口到新工程,并修改,只留下要测试的三个方法
  • 配置Mapper
    • 单个接口配置MapperFactoryBean
    • <!-- 动态代理Dao开发,第一种方式 -MapperFactoryBean -->
      	<bean id="baseMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true" lazy-init="true">
           	<property name="sqlSessionFactory" ref="sqlSessionFactory" />
          </bean>
          <!-- 用户动态代理扫描 -->
          <bean parent="baseMapper">
            <property name="mapperInterface" value="com.itheima.mybatis.mapper.UserMapper" />
         	</bean>
      
    • 配置包扫描器
    • <!-- 动态代理Dao开发,第二种方式,包扫描器(推荐使用) -->
      <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
         		<!-- basePackage:配置映射包装扫描,多个包时用","或";"分隔 -->
      <property name="basePackage" value="com.itheima.mybatis.mapper" />
         </bean>
      
  • 测试
  • public class UserMapperTest {
    	
    	private ApplicationContext applicationContext;
    	
    	@Before
    	public void init(){
    		applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    	}
    
    	@Test
    	public void testGetUserById() {
    		UserMapper userMapper = applicationContext.getBean(UserMapper.class);
    		User user = userMapper.getUserById(10);
    		System.out.println(user);
    

猜你喜欢

转载自blog.csdn.net/qq_30162219/article/details/87546934