目录
一.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);