[置顶] java ssm框架学习——mybatis--3

时间:2021-10-26 21:56:51

1.  多对一(一对一)关联查询

 

1.1. 方式一:通过继承关系进行一对一关联查询

1.1.1.   java类关系配置

public class UserOrder extends Order {
private Integer id;
private String username;
private String password;
private String sex;

1.1.2.   xml配置

<!-- 多对一 自动映射 -->
<select id="selectUserOrder" resultType="com.example.mybatis.domain.UserOrder">
    select u.*, o.oid
    oid,o.goodsname,o.goodsprice from
    t_user u left join t_order o on
    u.id=o.uid;
</select>

 

1.1.3.   测试代码

//自动映射方式查询
@Test
public void testManyToOne2() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<UserOrder> selectUserOrder = userMapper.selectUserOrder();
    for (UserOrder user : selectUserOrder) {
        System.out.println(user.toString());
    }
}

1.2. 方式二:通过持有引用进行一对一关联查询

1.1.4.   Order bean类封装

public class Order {
private Integer id;
private String goodsname;
private String goodsprice;
private User user;

1.1.5.   Xml配置

<select id="getOrderInfo" resultMap="orderResultMap">
    select
    t_order.*,t_user.username,t_user.sex from
    t_order,t_user where
    t_order.uid=t_user.id
</select>
<resultMap type="order" id="orderResultMap">
    <id property="id" column="id" />
    <result column="goodsname" property="goodsname" />
    <result column="goodsprice" property="goodsprice" />
    <association property="user" javaType="com.example.mybatis.domain.User">
        <id column="uid" property="id" />
        <result column="username" property="username" />
        <result column="sex" property="sex" />
    </association>
</resultMap>

1.1.6.   测试

@Test
public void testManyToOne() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 
    List<Order> userByIds = userMapper.getOrderInfo();
    for (Order order : userByIds) {
        System.out.println(order);
    }
}

 

2.   一对多关联查询

2.1. bean配置

public class User {
private Integer id;
private String username;
private String sex;
private String password;
//用户中要有orderList
List<Order> orderList;

2.2. xml中配置

<select id="getUserOrderList" resultMap="userResultMap">
select u.*, o.id
oid,o.goodsname,o.goodsprice from
t_user u left join t_order o on
u.id=o.uid ;
</select>
 
<resultMap type="user" id="userResultMap">
    <id column="id" property="id" />
    <result column="username" property="username" />
    <result column="password" property="password" />
    <result column="sex" property="sex" />
    <collection property="orderList" ofType="com.example.mybatis.domain.Order">
        <!-- 这里需要格外注意 定义id时要进行区分,要么起个别名,要么定义表的时候,id名称不一样 -->
        <id column="oid" property="id" />
        <result column="goodsname" property="goodsname" />
        <result column="goodsprice" property="goodsprice" />
    </collection>
</resultMap>

2.3. 代码测试

@Test
public void testOnetoMany() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<User> userOrderList = userMapper.getUserOrderList();
    for (User user : userOrderList) {
        List<Order> orderList = user.getOrderList();
        System.out.println(user+"---");
    }
}

3.   延迟加载

需要查询关联信息时,使用mybatis延迟加载特性可有效的减少数据库压力,
首次查询只查询主要信息,关联信息等用户获取时再加载。

 

3.1. 配置信息

lazyLoadingEnabled
 全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。
aggressiveLazyLoading
当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。

3.2. 配置方式

<!-- 全局配置参数 -->
<settings>
    <!-- 延迟加载总开关 -->
    <setting name="lazyLoadingEnabled" value="true" />  
    <!-- 设置按需加载 -->
    <setting name="aggressiveLazyLoading" value="false" />
</settings>

3.3. 代码测试

<!-- 1延迟加载 先查询user 再查询user中的订单信息 -->
<select id="selectLazyUser" resultMap="lazyUserResultMap">
    select * from t_user
</select>
<!-- 2 resultMap -->
<resultMap type="User" id="lazyUserResultMap">
    <id column="id" property="id" />
    <result column="username" property="username" />
    <result column="sex" property="sex" />
    <result column="age" property="age" />
    <!-- select 查询订单信息 column="id" 传递的id参数 -->
    <collection property="orderList" ofType="Order" select="selectLasyOrder"
        column="id">
        <!-- 进行映射 -->
        <id column="oid" property="oid" />
        <result column="goodsname" property="goodsname" />
        <result column="goodsprice" property="goodsprice" />
    </collection>
</resultMap>
<!-- 延迟查询 -->
<select id="selectLasyOrder" resultType="Order" parameterType="int">
    select * from t_order where
    uid=#{id}
</select>

4.   查询缓存

4.1. 一级缓存

一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,
第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了
测试:使用同一个sqlSession查询id相同的两个对象,比较对象地址是否一致
**注意:如果在sqlsession中执行了更新数据库的操作缓存会清空**

4.2. 二级缓存

Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namesspace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

4.3. 应用场景

电商类网站,频繁查询操作网站

4.4. 配置方式

1.SqlMapConfig.xml中配置全局缓存
<setting name="cacheEnabled" value="true"/>
2.在具体的mapping.xml中配置
<cache />标签
3.注意,需要将进行二级缓存的对象进行序列化操作
4.如果要禁用缓存,具体的查询操作中使用useCache="false" 或者使用flushCache刷新二级缓存

4.5. 了解ehcache 方式配置二级缓存

导入ehcache jar包
配置ehcache.xml
在<Cache>标签中表明type
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

 

5.   MyBatis整合Spring

 

5.1.  导入jar包

5.2. 配置MyBatis核心配置文件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>
    <typeAliases>
        <!-- 定义单个类的别名 -->
        <!-- <typeAlias type="com.example.batis.domain.User" alias="user" /> -->
        <package name="com.example.mybatis.domain" />
    </typeAliases>
    <mappers>
        <mapper resource="com/example/mybatis/domain/User.xml" />
    </mappers>
</configuration>

5.3. 第一种方式:Dao及实现类方式

5.3.1.1.         配置applicationContext.xml

<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" />
<!-- 定义数据源的bean -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close">
    <property name="driverClass" value="${db.driver}" />
    <property name="jdbcUrl" value="${db.url}" />
    <property name="user" value="${db.user}" />
    <property name="password" value="${db.password}" />
</bean>
<!-- 整合Sql会话工厂归spring管理 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 指定mybatis核心配置文件 -->
    <property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
    <!-- 指定会话工厂使用的数据源 -->
    <property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="userDao" class="com.example.mybatis.dao.impl.UserDaoImpl">
    <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>

5.3.1.2.         创建dao接口,编写实现类

public interface UserDao {
public List<User> selectUserById(int id);
}
//集成
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
    @Override
    public List<User> selectUserById(int id) {
        SqlSession sqlSession = this.getSqlSession();
        List<User> selectList = sqlSession
                .selectList("test.selectUserById", id);
        return selectList;
    }
}

 

5.3.1.3.         测试Spring整合dao方式是否成功

@Test
public void testQueryList() {
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
            "applicationContext.xml");
    UserDao userDao = (UserDao) applicationContext.getBean("userDao");
    List<User> selectUserById = userDao.selectUserById(1);
    for (User user : selectUserById) {
        System.out.println(user.toString());
    }
}

5.4. 第二种方式:Dao动态代理方式

5.4.1.1.         配置Spring核心配置文件applicationContext.xml

<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" />
<!-- 定义数据源的bean -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close">
    <property name="driverClass" value="${db.driver}" />
    <property name="jdbcUrl" value="${db.url}" />
    <property name="user" value="${db.user}" />
    <property name="password" value="${db.password}" />
</bean>
<!-- 整合Sql会话工厂归spring管理 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 指定mybatis核心配置文件 -->
    <property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
    <!-- 指定会话工厂使用的数据源 -->
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置mapper类所在的包,通过spring自动扫描,就不需要再重新配置单个的mapper了 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.example.mybatis.dao"></property>
</bean>

 

5.4.1.2.         配置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">
<configuration>
    <typeAliases>
        <!-- 定义所有bean的别名 类的大小写都可以 -->
        <package name="xxxx" />
    </typeAliases>
</configuration>

 

5.4.1.3.          整合测试

@Test
public void testQueryList() {
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
            "applicationContext.xml");
    UserMapper userMapper = (UserMapper) applicationContext
            .getBean(UserMapper.class);
    List<User> selectUserById = userMapper.selectUser();
    for (User user : selectUserById) {
        System.out.println(user.toString());
    }
}

6.   逆向工程

6.1. 使用逆向过程类生成pojo和mapper

6.2. 将pojo类和mapper放置到项目中

6.3. 常用代码

示例查询
mapper.selectByExample(example);
根据主键进行查询
selectByPrimaryKey(1);
多条件查询
TUserExample example = new TUserExample();
Criteria createCriteria = example.createCriteria();
createCriteria.andUsernameLike("%六%");