IDE: IntelliJ IDEA 2020.2
零 l 写在前面
1、以初学者的视角记录笔记
2、课程链接:[链接]
3、资料链接:[笔记对应课程的配套资料],提取码:5m91
4、实操很重要!!!
5、本文主讲MyBatis
6、前文链接:
[Spring入门笔记1] [Spring入门笔记2] [Spring入门笔记3]
[MyBatis入门笔记1]
一 l 关联查询
多表查询获取的返回值怎么处理。
(一)一对一
1、使用子类来获取关联查询结果(resultType)
Orders.java(订单类)
public class Orders {
private Integer id;
private Integer user_id;
private String note;//备注
private String number;
private Date createtime;//订单的创建时间
...get/set方法、toString方法(略)
}
OrdersExt.java(订单扩展类)
public class OrdersExt extends Orders{
private String username;
private String address;
...get/set方法、toString方法(略)
}
OrderMapper.java(查询接口)
public interface OrderMapper {
public OrdersExt findOrderById(int id);
}
OrderMapper.xml(映射文件)
<?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.gyf.mapper.OrderMapper">
<select id="findOrderById" parameterType="int" resultType="ordersExt">
SELECT
o.*,u.username,u.address
FROM
orders o,user u
WHERE
o.user_id = u.id
AND o.id = #{id}
</select>
</mapper>
测试.java
public void test6() throws IOException {
OrderMapper mapper = session.getMapper(OrderMapper.class);
OrdersExt ordersExt = mapper.findOrderById(3);
System.out.println(ordersExt);
}
2、嵌套类(resultMap实现对对象中类的赋值)
Orders.java(订单类)
public class Orders {
private Integer id;
private Integer user_id;
private String note;//备注
private String number;
private Date createtime;//订单的创建时间
private User user;//定单所属的用户
...get/set方法、toString方法(略)
}
不用写订单扩展类
OrderMapper.java(查询接口)
public interface OrderMapper {
public OrdersExt findOrderById2(int id);
}
OrderMapper.xml(映射文件)
<!--如果模型里有模型,使用resultMap-->
<select id="findOrderById2" parameterType="int" resultMap="orderRslMap">
SELECT
o.*,u.username,u.address
FROM
orders o,user u
WHERE
o.user_id = u.id
AND o.id = #{id}
</select>
<resultMap id="orderRslMap" type="orders">
<!-- 往orders的模型匹配数据-->
<id column="id" property="id"></id>
<id column="note" property="note"></id>
<id column="number" property="number"></id>
<id column="createtime" property="createtime"></id>
<!-- 往orders的user匹配数据
模型里有模型,使用association来配置-->
<association property="user" javaType="user">
<id column="user_id" property="id"></id>
<id column="username" property="username"></id>
<id column="address" property="address"></id>
</association>
</resultMap>
测试.java
public void test7() throws IOException {
OrderMapper mapper = session.getMapper(OrderMapper.class);
Orders order = mapper.findOrderById(3);
System.out.println(order);
System.out.println(order.getUser());
}
3、总结
resultType:
使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。如果没有查询结果的特殊要求建议使用resultType。
resultMap:
需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的对象属性中。
resultMap可以实现延迟加载,resultType无法实现延迟加载。
(二)一对多
Orders.java(订单类)
public class Orders {
private Integer id;
private Integer user_id;
private String note; // 备注
private String number;
private Date createtime; // 订单的创建时间
private User user; // 定单所属的用户
private List<OrderDetail> orderDetails; // 一对多
...get/set方法、toString方法(略)
}
OrderMapper.java(查询接口)
public interface OrderMapper {
public OrdersExt findOrderById3(int id);
}
OrderMapper.xml(映射文件)
<resultMap id="orderRslMap3" type="orders">
<!-- 往orders的模型匹配数据-->
<id column="id" property="id"></id>
<id column="note" property="note"></id>
<id column="number" property="number"></id>
<id column="createtime" property="createtime"></id>
<!-- 往orders的user匹配数据
模型里有模型,使用association来配置 -->
<association property="user" javaType="user">
<id column="user_id" property="id"></id>
<id column="username" property="username"></id>
<id column="address" property="address"></id>
</association>
<!-- 一对多匹配: 往orders的orderdetails 匹配数据
注意:集合里类型使用ofType,而不是javaType -->
<collection property="orderDetails" ofType="orderDetail">
<id column="detail_id" property="id"></id>
<id column="items_id" property="itemsId"></id>
<id column="items_num" property="itemsNum"></id>
</collection>
</resultMap>
<select id="findOrderById3" parameterType="int" resultMap="orderRslMap3">
SELECT
o.*,
u.username,
u.address,
od.id detail_id,
od.items_id,
od.items_num
FROM
orders o,
user u,
orderdetail od
WHERE
o.user_id = u.id
AND o.id = od.orders_id
AND o.id = #{id}
</select>
测试.java
public void test8() throws IOException {
OrderMapper mapper = session.getMapper(OrderMapper.class);
Orders order = mapper.findOrderById3(3);
System.out.println(order);
System.out.println(order.getUser());
System.out.println(order.getOrderDetails());
}
(三)多对多
UserMapper.java
public interface UserMapper {
/**
* 查询用户信息及用户购买的商品信息
*/
public List<User> findUserAndOrderInfo();
}
UserMapper.xml
<mapper>
<resultMap id="userRslMap" type="user">
<!-- 1.匹配user属性() -->
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<!--2.匹配user的orderList(用户的所有订单) -->
<collection property="orderList" ofType="orders">
<id column="order_id" property="id"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 3.匹配Orders里有orderDetails(每个订单的细节) -->
<collection property="orderDetails" ofType="orderDetail">
<id column="detail_id" property="id"/>
<result column="items_id" property="itemsId"/>
<result column="items_num" property="itemsNum"/>
<!-- 4.配置定单详情的商品信息-->
<association property="items" javaType="items">
<id column="items_id" property="id"/>
<result column="name" property="name"/>
<result column="price" property="price"/>
<result column="detail" property="detail"/>
</association>
</collection>
</collection>
</resultMap>
<select id="findUserAndOrderInfo" resultMap="userRslMap">
SELECT
u.id,u.username,u.address,
o.id order_id,o.number,o.createtime,o.note,
od.id detail_id,od.items_id,od.items_num,
it.name,it.price,it.detail
FROM
user u,
orders o,
orderdetail od,
items it
WHERE
o.user_id = u.id
AND o.id = od.orders_id
AND od.items_id = it.id
</select>
</mapper>
其他省略,每个类里多加个属性而已,
User类里面有Orders类数组,
Orders类数组里有OrdersExt类数组,
OrdersExt类有Items类。
(主要是集合用collection、简单元素用association)
二 l 延时加载
延迟加载又叫懒加载,也叫按需加载。
也就是说先加载主信息,在需要的时候,再去加载从信息。
在mybatis中,resultMap标签的 association标签 和 collection标签 具有延迟加载的功能。
OrderMapper.java
public interface OrderMapper {
// 懒加载定单的用户数据
public List<Orders> findOrderAndUserByLazyloading();
}
OrderMapper.xml
<resultMap id="orderLazyloadingRslMap" type="orders">
<id column="id" property="id"/>
<result column="note" property="note"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<!--配置查询 user:返回值 select:调用方法 column:传入参数-->
<association property="user" select="com.gyf.mapper.UserMapper.findUserById" column="user_id"/>
</resultMap>
<select id="findOrderAndUserByLazyloading" resultMap="orderLazyloadingRslMap">
SELECT * FROM orders
</select>
UserMapper.java
public interface UserMapper {
public User findUserById(int id);
}
UserMapper.xml
<select id="findUserById" parameterType="int" resultType="user">
SELECT * FROM user WHERE id = #{id}
</select>
SqlMapConfig.xml(全局配置)
<configuration>
...
<!--配置允许懒加载-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
...
</configuration>
三 l 查询缓存(缓存一般都是用在查询上)
(一)Mybatis的缓存理解
Mybatis的缓存,包括一级缓存和二级缓存,一级缓存是默认使用的。二级缓存需要手动开启。
一级缓存指的就是sqlsession,在sqlsession中有一个数据区域,是map结构,这个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一个唯一值。一级缓存中的value,就是查询出的结果对象。
二级缓存指的就是同一个namespace下的mapper,二级缓存中,也有一个map结构,这个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一个唯一值。一级缓存中的value,就是查询出的结果对象。
(二)一级缓存
(三)二级缓存
session查询后需要关闭,才能写入二级缓存。
1、开启二级缓存设置
SqlMapConfig.xml
<configuration>
...
<settings>
<!--允许开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
...
</configuration>
2、告诉哪些需要开启二级缓存
UserMapper.xml
<mapper namespace="com.gyf.mapper.UserMapper">
<!-- 配置缓存
1.type不写,默认使用的是mybaits自带的缓存技术,perpetualCache(永久缓存)
2.可以改成Ehcache缓存-->
<cache/>
</mapper>
3、user序列化,实现Serializable接口
User.java
public class User implements Serializable {
...
}
【特殊操作】4、禁用指定方法的二级缓存(useCache=“false”)(默认是true)
UserMapper.xml
<select id="findUserById" parameterType="int" resultType="user" useCache="false">
SELECT * FROM user WHERE id = #{id}
</select>
【特殊操作】5、禁用指定方法刷新(清空)缓存(flushCache=“false”)(默认是true)
UserMapper.xml
<insert id="save" parameterType="user" flushCache="false">
INSERT INTO user (username,sex,birthday,address)
VALUE (#{username},#{sex},#{birthday},#{address})
</insert>
(四)整合ehcache
Mybatis本身是一个持久层框架,它不是专门的缓存框架,所以它对缓存的实现不够好,不能支持分布式。
Ehcache是一个分布式的缓存框架。
Cache是一个接口,mybatis的默认实现是PerpetualCache。如果想整合mybatis的二级缓存,那么实现Cache接口即可。
整合流程:
1、添加jar包(高亮的这两个)
2、修改使用的缓存类型
UserMapper.xml
<mapper namespace="com.gyf.mapper.UserMapper">
<!-- 配置缓存
1.type不写,默认使用的是mybaits自带的缓存技术,perpetualCache(永久缓存)
2.可以改成Ehcache缓存-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
</mapper>
3、在 src 下添加 ehcache.xml 文件
ehcache.xml
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
</ehcache>
ehcache.xml设置介绍:
属性 | 解释 |
---|---|
maxElementsInMemory | 设置基于内存的缓存中可存放的对象最大数目 |
eternal | 设置对象是否为永久的,true表示永不过期,此时将忽略 |
timeToIdleSeconds | 【默认值是false】 设置对象空闲最长时间,以秒为单位,超过这个时间,对象过期。 当对象过期时,EHCache会把它从缓存中清除。 如果此值为0,表示对象可以无限期地处于空闲状态。 |
timeToLiveSeconds | 【默认值是false】 设置对象生存最长时间,超过这个时间,对象过期。 如果此值为0,表示对象可以无限期地存在于缓存中。 该属性值必须大于或等于 timeToIdleSeconds 属性值 。 |
overflowToDisk | 设置基于内在的缓存中的对象数目达到上限后,是否把溢出的对象写到基于硬盘的缓存中。 |
diskPersistent | 【默认值是false】当jvm结束时是否持久化对象。 |
diskExpiryThreadIntervalSeconds | 指定专门用于清除过期对象的监听线程的轮询时间。 |
memoryStoreEvictionPolicy | 【默认值是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)】 当内存缓存达到最大,有新的element加入的时候,移除缓存中element的策略。 |
应用场景:
对于访问响应速度要求高,但是实时性不高的查询,可以采用二级缓存技术。
注意:
在使用二级缓存的时候,要设置一下刷新间隔(cache标签中有一个flashInterval属性)来定时刷新二级缓存,这个刷新间隔根据具体需求来设置,比如设置30分钟、60分钟等,单位为毫秒。
局限性:
Mybatis二级缓存对细粒度的数据,缓存实现不好。
可以对经常变化的 数据操作单独放到另一个namespace的mapper中。
四 l mybaties整合spring
(一)导包(高亮的是mybatis-xxx.zip里的包)(略)
(二)配置mybatis的核心配置文件(传统配置dao)
SqlMapConfig.xml(src/)(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>
<package name="com.gyf.backoffice.model"/>
</typeAliases>
<!--告诉mybatis加载映射文件-->
<mappers>
<mapper resource="com/gyf/backoffice/sqlmap/User.xml"/>
</mappers>
</configuration>
User.java(src/com.gyf.backoffice.model)
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username == null ? null : username.trim(); }
public Date getBirthday() { return birthday; }
public void setBirthday(Date birthday) { this.birthday = birthday; }
public String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex == null ? null : sex.trim(); }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address == null ? null : address.trim(); }
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
User.xml(src/com.gyf.backoffice.sqlmap)
<?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="user">
<select id="findUserById" parameterType="int" resultType="user">
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>
(三)配置spring的数据源(传统配置dao)
applicationContext.xml(src/)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
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-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<!-- 1.配置数据库,dbcp数据库连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisday1?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<!-- 最大连接 -->
<property name="maxActive" value="10"/>
<!--最大空闲数 -->
<property name="maxIdle" value="5"/>
</bean>
<!-- 2.配置会话工厂 -->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:SqlMapConfig.xml"/>
</bean>
<!-- 3.配置dao -->
<bean id="userDao" class="com.gyf.backoffice.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sessionFactory"/>
</bean>
</beans>
(四)编写UserDaoImpl(传统配置dao)
UserDao.java(src/com.gyf.backoffice.dao)
public interface UserDao {
public User findUserById(int id);
}
UserDaoImpl.java(src/com.gyf.backoffice.dao)
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{
@Override
// 方法的findUserById是实现接口
public User findUserById(int id) {
// 调用的user.findUserById是user.xml中的user命名空间下的findUserById方法
return this.getSqlSession().selectOne("user.findUserById",id);
}
}
(五)测试(传统配置dao)
Demo01.java(test/com.gyf.backoffice)
public class Demo01 {
@Test
public void test1(){
// 1.加载spring的配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.获取dao的bean
UserDao userDao = (UserDao) context.getBean("userDao");
// 3.调用dao方法
User user = userDao.findUserById(1);
// 4.输出验证
System.out.println(user);
}
}
(六)创建Mapper映射文件(Mapper工厂配置mapper)
UserDao.java(src/com.gyf.backoffice.mapper)(与dao相同)
User.xml(src/com.gyf.backoffice.mapper)(只需要改namespace)
...
<mapper namespace="com.gyf.backoffice.mapper.UserMapper">
...
</mapper>
applicationContext.xml(src/)(接在后面写)
<beans ...>
...
<!-- 4.由spring创建一个userMapper对象,使用工厂来创建 -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sessionFactory"/>
<property name="mapperInterface" value="com.gyf.backoffice.mapper.UserMapper"/>
</bean>
</beans>
SqlMapConfig.xml(src/)(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>
<package name="com.gyf.backoffice.model"/>
</typeAliases>
<!--告诉mybatis加载映射文件-->
<mappers>
<mapper resource="com/gyf/backoffice/sqlmap/User.xml"/>
<!-- 包配置只适用于mapper代理
加载映射接口和配置文件 -->
<package name="com.gyf.backoffice.mapper"/>
</mappers>
</configuration>
Demo01.java(test/com.gyf.backoffice)
public class Demo01 {
@Test
public void test2(){
// 1.加载spring的配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.获取userMapper
UserMapper userMapper = (UserMapper) context.getBean("userMapper");
// 3.调用Mapper方法
User user = userMapper.selectByPrimaryKey(1);
// 4.输出验证
System.out.println(user);
}
}
(七)用MapperScannerConfigurer批量扫描创建代理对象(最好用)
applicationContext.xml(src/)(注释掉4,接在后面写)
<beans ...>
...
<!-- 5.批量创建mapper的bean对象
内部会扫描指定包下的mapper,创建代理对象,名字就是类名,头字母改小写 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.gyf.backoffice.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
</bean>
</beans>
五 l 逆向工程
通过数据库中的单表,自动生成java代码。
Mybatis官方提供了逆向工程,可以针对单表自动生成mybatis代码(mapper.java\mapper.xml\po类)
企业开发中,逆向工程是个很常用的工具。
下载地址:[mybatis-generator-core-1.x.x-bundle.zip]
1、创建简单java项目
2、导入jar包mybatis-generator-core-1.x.x.jar和mysql-connector-java-x.x.x-bin.jar
3、在src目录下创建generator.xml文件
4、参考[官方配置介绍],照着[课程视频]配置文件
generator.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="mysqlTables" targetRuntime="MyBatis3">
<!-- 数据库配置 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatisday1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8"
userId="root"
password="123">
</jdbcConnection>
<!-- java类型解析 -->
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 位置:模型生成包名的包路径 -->
<javaModelGenerator targetPackage="com.gyf.backoffice.model" targetProject=".\src">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 位置:mybatis的映射.xml的包路径 -->
<sqlMapGenerator targetPackage="com.gyf.backoffice.mapper" targetProject=".\src">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 位置:mybatis的mapper接口生成的包路径 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.gyf.backoffice.mapper" targetProject=".\src">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 配置生成表的模型 tableName:表名 domainObjectName:类名,如果没定义自动将表名第一个字母大写 -->
<table tableName="items"/>
<table tableName="orderdetail" domainObjectName="OrderDetail"></table>
<table tableName="orders"/>
<table tableName="user"/>
</context>
</generatorConfiguration>
5、使用java类来执行逆向工程(代码是固定写法)
Main.java
public class Main {
public static void main(String[] args)throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
// 读取配置文件
File configFile = new File("src/generator.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
callback, warnings);
myBatisGenerator.generate(null);
}
}
6、运行,生成文件,放到项目中去
Example后缀的文件是用来查询的
里面有对应表的元素的限制,例如UserExample里面有如下的方法
操作实现可以看看.xml文件,就是模块化设置
7、使用方法例子:简单查询
public void test2(){
// 1.加载spring的配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.获取userMapper
UserMapper userMapper = (UserMapper) context.getBean("userMapper");
// 3.调用Mapper方法
User user = userMapper.selectByPrimaryKey(1);
// 4.输出结果
System.out.println(user);
}
8、使用方法例子:条件查询(使用Example后缀文件的方法)
public void test3(){
//1.加载spring的配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取userMapper
UserMapper userMapper = (UserMapper) context.getBean("userMapper");
UserExample example = new UserExample();
UserExample.Criteria criteria = example.createCriteria(); // 获取查询条件
criteria.andSexEqualTo("1"); // 男性
List<User> users = userMapper.selectByExample(example);
System.out.println(users);
}