建立MyBatis工程及基本使用(实例)

注:本文使用的IntelliJ IDEA版本为2019.3.3,MyBatis版本为3.4.5,操作系统为Win10。

搭建步骤:

第一步:创建 maven 工程
第二步:导入坐标(pom.xml文件)
第三步:编写必要代码(实体类和持久层接口)
第四步:编写 SqlMapConfig.xml 文件
第五步:编写映射配置文件
第六步:编写测试类

工程目录结构:

各文件内容:

- pom.xml:Maven使用的jar包资源坐标配置文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>  <!-- 打包方式 -->

    <dependencies>  <!-- 依赖 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.18</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>  <!-- 作用域: 仅测试时起效 -->
        </dependency>
    </dependencies>
    <properties>
        <!-- 指定编译的JDK版本-->
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <!-- 指定编码格式 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>
View Code

- SqlMapConfig.xml: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">

<!-- mybatis的主配置文件 -->
<configuration>

    <!--
    配置properties
        方式1:在标签内部配置连接数据库信息.
        方式2:通过属性引用外部配置文件信息.(使用resource属性或url属性引入)
            resource属性: 用于指定配置文件位置, 按照类路径写法来写
            url属性: 用于指定配置文件位置, 按照URL写法来写
     -->
    <!-- 标签内部配置连接数据库信息 -->
    <!--
    <properties>
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///java_db01?serverTimezone=Asia/Shanghai"/>
        <property name="username" value="root"/>
        <property name="password" value="root8888"/>
    </properties>
    -->
    <properties resource="jdbcConfig.properties" />  <!-- 通过属性引用外部配置文件信息, resource方式 -->
    <!-- <properties url="file:///E:DocumentsIdeaProjmybatissrcmain
esourcesjdbcConfig.properties" /> -->  <!--通过属性引用外部配置文件信息, url方式 -->
    
    <!-- 配置参数 -->
    <settings>
        <setting name="cacheEnabled" value="true"/>  <!-- Mybatis二级缓存开关, 默认为true(不论是xml配置还是使用注解, 都需要此项) -->
        <setting name="lazyLoadingEnabled" value="true"/>  <!-- 开启Mybatis延时加载开关 -->
        <setting name="aggressiveLazyLoading" value="false"/>  <!-- true:积极加载,false:按需加载, 默认为false -->
    </settings>
    <typeAliases>  <!-- 用于配置映射配置文件中类的别名(如:parameterType属性和resultType属性), 只能为domain中的类配置别名 -->
        <!-- <typeAlias type="domain.User" alias="user"/> -->  <!-- typeAlias仅指定一个类的别名, type:全类名,alias:别名, 不区分大小写 -->
        <package name="domain"/>  <!-- package指定一整个包下的类的别名, 类名就是别名, 不区分大小写 -->
    </typeAliases>
    
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql环境 -->
        <environment id="mysql">
            <!-- 配置事务的类型 -->
            <transactionManager type="JDBC"/>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基本信息, 通过${}方式引用属性 (也可以直接给值) -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 指定映射文件的位置, 映射文件是指每个dao独立的配置文件 -->
    <mappers>
        <!-- <mapper resource="dao/IUserDao.xml"/> -->  <!-- 使用*.xml方式时, 需此项 -->
        <!-- <mapper class="dao.IUserDao"/> -->  <!-- 使用注解方式时, 需此项, 并需要删除*.xml文件 -->
        <package name="dao"/>  <!-- package标签用于指定dao接口所在包, 用于代替mapper resource或mapper class -->
    </mappers>

</configuration>

- jdbcConfig.properties:数据库连接配置文件

# 配置连接数据库的4个基本信息
driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql:///数据库?serverTimezone=Asia/Shanghai
username = 用户名
password = 密码

- log4j.properties:log4j需要的配置文件(直接用即可)

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m


# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m
View Code

注:假设数据库中含有user表、role表、account表和user_role(建表语句如下)

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `birthday` datetime DEFAULT NULL COMMENT '生日',
  `sex` char(1) DEFAULT NULL COMMENT '性别',
  `address` varchar(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
);

CREATE TABLE `role` (
  `ID` int(11) NOT NULL COMMENT '编号',
  `ROLE_NAME` varchar(30) DEFAULT NULL COMMENT '角色名称',
  `ROLE_DESC` varchar(60) DEFAULT NULL COMMENT '角色描述',
  PRIMARY KEY (`ID`)
);

CREATE TABLE `account` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `UID` int(11) DEFAULT NULL COMMENT '用户编号',
  `MONEY` double DEFAULT NULL COMMENT '金额',
  PRIMARY KEY (`ID`),
  FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
);

CREATE TABLE `user_role` (
  `UID` int(11) NOT NULL COMMENT '用户编号',
  `RID` int(11) NOT NULL COMMENT '角色编号',
  PRIMARY KEY  (`UID`,`RID`),
  FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),
  FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
);
View Code

实体类(JavaBean)

- User.java

public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    // 一对多关系映射: 主表实体应该包含从表实体的集合引用
    private List<Account> accounts;

    // 多对多关系映射: 主表实体应该包含从表实体的集合引用
    private List<Role> roles;

    ...  // 省略Getter、Setter和toString方法

}
View Code

- Role.java

public class Role implements Serializable {
    private Integer roleId;
    private String roleName;
    private String roleDesc;

    // 多对多关系映射: 主表实体应该包含从表实体的集合引用
    private List<User> users;

    ...  // 省略Getter、Setter和toString方法

}
View Code

- Account.java

public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private Double money;

    // 一对一关系映射: 从表实体应该包含一个主表实体的对象引用
    private User user;

    ...  // 省略Getter、Setter和toString方法

}
View Code

持久层接口

1.使用xml映射配置文件

- IUserDao.java

public interface IUserDao {

    //------------------------------------- 一对多关系映射表操作 -------------------------------------
    List<User> findAll();
    List<User> findAllLazyLoad();

    //--------------------------------------- 单一user表操作 ---------------------------------------
    List<User> findAllUser();  //

    void saveUser(User user);  //

    void updateUser(User user);  //

    void deleteUserById(Integer userId);  //

    User findUserById(Integer userId);  //

    List<User> findUserByName(String name);  // 查, 使用模糊查询like

    int findTotal();  // 查, 使用聚合函数count

    List<User> findUserByCondition(User user);  // 查, 根据条件查询

    List<User> findUserInIds(List<Integer> ids);  // 查, 查询多个Id用户
}

- IRoleDao.java

public interface IRoleDao {
    List<Role> findAll();
    List<Role> findAllRole();
}
View Code

- IAccountDao.java

public interface IAccountDao {

    List<Account> findAllAccount();
    List<Account> findAllAccountLazyLoad();
    List<Account> findAccountByUid(Integer uid);
}
View Code

2.使用注解(必须删除相应的xml映射配置文件,仅以IUserDao.java为例)

常用注解:

@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@ResultMap:实现引用@Results 定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
@SelectProvider: 实现动态 SQL 映射
@CacheNamespace:实现注解二级缓存的使用
 - IUserDao.java
@CacheNamespace(blocking=true)  // 基于注解方式实现配置二级缓存
public
interface IUserDao { //-------------------------------------一对多关系映射表操作------------------------------------- @Select("select * from user") @Results(id="userAccountMap",value={ @Result(id=true,property="id",column="id"), @Result(property="username",column="username"), @Result(property="address",column="address"), @Result(property="sex",column="sex"), @Result(property="birthday",column="birthday"), @Result(property="accounts",column="id", many=@Many( select="dao.IAccountDao.findAccountByUid", fetchType=FetchType.EAGER )) }) List<User> findAll(); @Select("select * from user") @Results(id="userAccountMapLazyLoad",value={ @Result(id=true,property="id",column="id"), @Result(property="username",column="username"), @Result(property="address",column="address"), @Result(property="sex",column="sex"), @Result(property="birthday",column="birthday"), @Result(property="accounts",column="id", many=@Many( select="dao.IAccountDao.findAccountByUid", fetchType=FetchType.LAZY )) }) List<User> findAllLazyLoad(); //---------------------------------------单一user表操作--------------------------------------- @Select("select * from user") // 使用注解方式, 则不需要配置映射文件(且必须删除*.xml文件) /* @Results(id="userMap", value = { @Result(id=true,property="userId",column="id"), @Result(property="userName",column="username"), @Result(property="userAddress",column="address"), @Result(property="userSex",column="sex"), @Result(property="userBirthday",column="birthday") }) */ List<User> findAllUser(); // @Insert("insert user (username,address,sex,birthday) values(#{username},#{address},#{sex},#{birthday})") @SelectKey(keyProperty="id",keyColumn="id",resultType=Integer.class,before=false,statement="select last_insert_id()") void saveUser(User user); // @Update("update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}") void updateUser(User user); // @Delete("delete from user where id=#{id}") void deleteUserById(Integer userId); // @Select("select * from user where id=#{uid}") // @ResultMap("userMap") // 关系映射引用 User findUserById(Integer userId); // @Select("select * from user where username like #{username} ") List<User> findUserByName(String name); // 查, 使用模糊查询like @Select("select count(*) from user") int findTotal(); // 查, 使用聚合函数count @SelectProvider(type=SqlProvider.class, method="findUserByCondition") List<User> findUserByCondition(User user); // 查, 根据条件查询 @SelectProvider(type=SqlProvider.class, method="findUserInIds") List<User> findUserInIds(@Param("ids") List<Integer> ids); // 查, 查询多个Id用户, 使用@Param注解时必须使用Map<String,Object> map接收 class SqlProvider { public String findUserByCondition(User user) { // 等价SQL语句:select * from user where username like ? and sex=?; return new SQL(){ { SELECT("*"); FROM("user"); String username = user.getUsername(); if(username!=null && username.length()>0){ WHERE("username like #{username}"); } String sex = user.getSex(); if(sex!=null && sex.length()>0){ WHERE("sex=#{sex}"); } } }.toString(); } public String findUserInIds(Map<String,Object> map) { // 等价的SQL语句: select * from user where id in (?); List<Integer> list = (List<Integer>) map.get("ids"); // 从map中获取参数 List<String> ids = list.stream().map(x -> x + "").collect(Collectors.toList()); // 将ist<Integer>类型转为List<String>类型 StringBuilder sql = new StringBuilder("select * from user where id in ("); sql.append(String.join(",", ids)); // 将ids中的元素转为字符串, 并以逗号(,)间隔开 sql.append(")"); return sql.toString(); } } }

映射配置文件(使用注解时不能存在)

- IUserDao.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">
<!-- 映射文件(映射文件的位置必须和dao接口的包结构相同) -->
<mapper namespace="dao.IUserDao">  <!-- namespace必须是dao接口的全类名-->
    <cache/>  <!-- 开启二级缓存支持 -->

<!-- 一对多关系映射表操作 -->
    <resultMap id="userAccountMap" type="User">  <!-- type:指定封装的类型(可使用typeAliases中指定的类别名) -->
        <!-- 主键字段对应 -->
        <id property="id" column="id"/>
        <!-- 非主键字段对应 -->
        <result property="username" column="username"/>
        <result property="address" column="address"/>
        <result property="sex" column="sex"/>
        <result property="birthday" column="birthday"/>
        <!-- 配置user对象中accounts集合的映射 -->
        <collection property="accounts" ofType="Account">  <!-- ofType:集合中元素的类型 -->
            <id property="id" column="aid"/>
            <result property="uid" column="uid"/>
            <result property="money" column="money"/>
        </collection>
    </resultMap>
    <select id="findAll" resultMap="userAccountMap">  <!-- id指定绑定dao中的方法, resultType指定自动封装的类, 可用别名 -->
        select u.*,a.id as aid,a.uid,a.money from user u left join account a on u.id = a.uid
    </select>

    <!-- 一对多关系映射实现延时加载-->
    <resultMap id="userAccountMapLazyLoad" type="User">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="address" column="address"/>
        <result property="sex" column="sex"/>
        <result property="birthday" column="birthday"/>
        <!-- 配置user对象中accounts集合的映射 -->
        <collection property="accounts" ofType="Account" column="id" select="dao.IAccountDao.findAccountByUid"/>
    </resultMap>
    <select id="findAllLazyLoad" resultMap="userAccountMapLazyLoad">
        select * from user
    </select>

<!-- 单一user表操作 -->
    <select id="findAllUser" resultType="User" useCache="true">  <!-- useCache:使用二级缓存-->
        select * from user;  -- 实体类属性名和数据库中字段名相同时可自动封装
        -- select id as userId,username as userName,address as userAddress,sex as userSex,birthday as userBirthday from user;  -- 不同时可用取别名的方式使自动封装
    </select>
    <!-- 若实体类属性名和数据库中字段名不同时, 也可采用配置查询结果的列名和实体类的属性名的对应关系 -->
    <!--
    <resultMap id="userMap" type="User">
        <id property="userId" column="id"/>
        <result property="userName" column="username"/>
        <result property="userAddress" column="address"/>
        <result property="userSex" column="sex"/>
        <result property="userBirthday" column="birthday"/>
    </resultMap>
    <select id="findAllUser" resultMap="userMap">
        select * from user;
    </select>
    -->

    <insert id="saveUser" parameterType="domain.User">
        -- 配置插入操作后, 获取插入数据的id, 会自动赋值到包装类User.id
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">  <!-- keyProperty:对应实体类中id, keyColumn:对应数据库中id, order:update操作后操作 -->
            select last_insert_id();
        </selectKey>
        insert user (username, birthday, sex, address) values (#{username}, #{birthday}, #{sex}, #{address});
    </insert>
    <update id="updateUser" parameterType="domain.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id};
    </update>
    <delete id="deleteUserById" parameterType="Integer">
        delete from user where id=#{id}
    </delete>
    <select id="findUserById" parameterType="Integer" resultType="domain.User">
        select * from user where id=#{id};
    </select>
    <select id="findUserByName" parameterType="String" resultType="domain.User">
        select * from user where username like #{username};
     -- select * from user where username like '_${value}%'  -- 必须固定为value, 会组合成字符串拼接, 而非占位符, 不推荐用
    </select>
    <select id="findTotal" resultType="Integer">
        select count(*) from user;
    </select>
    <select id="findUserByCondition" parameterType="user" resultType="user">
        <!--
        select * from user where 1=1
        <if test="username!=null">
            and username like #{username}
        </if>
        <if test="sex!=null">
            and sex = #{sex}
        </if>
        -->

        <!-- 可使用<where>替换where 1=1 -->
        select * from user
        <where>
            <if test="username!=null">
                and username like #{username}
            </if>
            <if test="sex!=null">
                and sex = #{sex}
            </if>
        </where>
    </select>

    <sql id="defaultUser">  <!-- 抽取重复的SQL语句 -->
       select * from user
    </sql>
    <select id="findUserInIds" parameterType="List" resultType="user">
        <!-- 等价的SQL语句: select * from user where id in (?) -->

        <!--
        <foreach>标签用于遍历集合, 其属性:
            collection: 要遍历的集合, 不需要用#{}
            open: 拼成的SQL语句开始的部分
            close: 拼成的SQL语句结束的部分
            item: 遍历集合的每个元素, 生成变量名
            sperator: 拼成的SQL语句分隔符 (一般为,)

              在使用foreach的时候最关键的也是最容易出错的就是collection属性。
          该属性是必须的,但在不同情况下,该属性的值是不同的,主要有一下3种情况:
                1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为"list"
                2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为"array"
                3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,collection的属性值应为HaspMap的key
        -->
        <include refid="defaultUser"/>  <!-- 使用重复的SQL语句 -->
        <where>
            <if test="list!=null and list.size>0">  <!-- 此处固定为list而与Dao中的ids无关 -->
                <foreach item="item" collection="list" open="and id in (" separator="," close=")">
                    #{item}
                </foreach>
            </if>
        </where>
    </select>
</mapper>

 - IRoleDao.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="dao.IRoleDao">
    <!-- 多对多关系映射: 从Role角度查询关联的所有User -->
    <resultMap id="roleUserMap" type="Role">
        <id property="roleId" column="id"/>
        <result property="roleName" column="role_name"/>
        <result property="roleDesc" column="role_desc"/>
        <collection property="users" ofType="User">
            <id property="id" column="uid"/>
            <result property="username" column="username"/>
            <result property="address" column="address"/>
            <result property="sex" column="sex"/>
            <result property="birthday" column="birthday"/>
        </collection>
    </resultMap>
    <select id="findAll" resultMap="roleUserMap">
        select * from role r
         left join user_role ur on r.id=ur.rid
         left join user u on ur.uid=u.id
    </select>

    <!-- 单表查询 -->
    <resultMap id="roleMap" type="Role">
        <id property="roleId" column="id"/>
        <result property="roleName" column="role_name"/>
        <result property="roleDesc" column="role_desc"/>
    </resultMap>
    <select id="findAllRole" resultMap="roleMap">
        select * from role;
    </select>

</mapper>
View Code

- IAccountDao.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="dao.IAccountDao">

    <resultMap id="accountMap" type="Account">
        <id property="id" column="aid"/>
        <result property="uid" column="uid"/>
        <result property="money" column="money"/>
        <!-- 一对一关系映射:配置封装user的内容-->
        <association property="user" javaType="User">  <!--  javaType: 表示自动封装的类, 类似resultType, 是必须属性 -->
            <id property="id" column="id"/>
            <result property="username" column="username"/>
            <result property="address" column="address"/>
            <result property="sex" column="sex"/>
            <result property="birthday" column="birthday"/>
        </association>
    </resultMap>
    <select id="findAllAccount" resultMap="accountMap">
        select a.id as aid,a.uid,a.money,u.* from account a,user u where u.id=a.uid
    </select>

    <!-- 一对一关系映射实现延时加载 -->
    <resultMap id="accountMapLazyLoad" type="Account">
        <id property="id" column="id"/>
        <result property="uid" column="uid"/>
        <result property="money" column="money"/>
        <!-- 一对一关系映射:配置封装user的内容 -->
        <association property="user" column="uid" javaType="User" select="dao.IUserDao.findUserById"/>
    </resultMap>
    <select id="findAllAccountLazyLoad" resultMap="accountMapLazyLoad">
        select * from account
    </select>

    <select id="findAccountByUid" parameterType="Integer" resultType="Account">
        select * from account where uid=#{uid}
    </select>
    
</mapper>
View Code

测试类

 - UserTest.java

/*
 * Mybatis一级缓存: 指的是Mybatis中SqlSession对象的缓存. (只要SqlSession对象不消失, 或者两次select查询间不执行数据库的增删改操作, 一级缓存则不会消失或清空)
 * Mybatis二级缓存: 指的是Mybatis中SqlSessionFactory对象的缓存. 由同一个SqlSessionFactory对象创建的SqlSession共享其缓存.
 *   * 二级缓存使用: SqlMapConfig.xml中配置, 在当前映射文件配置(如:IUserDao.xml), 在当前操作中配置(在select标签中)
 */
public class UserTest {
    private InputStream is;
    private SqlSession session;
    private IUserDao userDao;

    @Before  // 在测试方法自动调用
    public void init() {
        try {
            // 1.读取配置文件
            is = Resources.getResourceAsStream("SqlMapConfig.xml");
            // 2.创建SqlSessionFactory工厂
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
            // 3.使用工厂生产SqlSession对象
            session = factory.openSession();
            // 4.使用SqlSession创建Dao接口的代理对象
            userDao = session.getMapper(IUserDao.class);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @After  // 在测试方法前自动调用
    public void destroy() {
        session.commit();  // 提交事务, 查询的方法可不用

        // 释放资源
        if (session != null) {
            session.close();
        }
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //-------------------------------------一对多关系映射表操作-------------------------------------
    @Test
    public void testFindAll() {
        List<User> users = userDao.findAll();  // 使用代理对象执行方法
        for (User user : users) {
            System.out.print(user);
            System.out.println("," + user.getAccounts());
        }
    }

    /**
     * 延迟加载方式
     */
    @Test
    public void testFindAllLazyLoad() {
        List<User> users = userDao.findAllLazyLoad();
        for (User user : users) {
            System.out.print(user);
            System.out.println("," + user.getAccounts());
        }
    }

    //---------------------------------------单一user表操作---------------------------------------
    @Test
    public void testFindAllUser() {
        List<User> users = userDao.findAllUser();
        for (User user : users) {
            System.out.println(user);
        }
    }

    @Test
    public void testSaveUser() {
        User user = new User();
        user.setUsername("张三");
        user.setSex("男");
        user.setAddress("北京朝阳区");
        user.setBirthday(new Date());
        System.out.println("操作前: " + user);
        userDao.saveUser(user);  // 使用代理对象执行方法
        System.out.println("操作后: " + user);
    }

    @Test
    public void testUpdateUser() {
        User user = new User();
        user.setId(41);
        user.setUsername("田七");
        user.setSex("女");
        user.setAddress("北京顺义区");
        user.setBirthday(new Date());
        userDao.updateUser(user);
    }

    @Test
    public void testDeleteUserById() {
        userDao.deleteUserById(51);
    }

    @Test
    public void testFindUserById() {
        User user = userDao.findUserById(41);
        System.out.println(user);
    }

    @Test
    public void testFindUserByName() {
        List<User> users = userDao.findUserByName("_王%");  // 使用模糊查询, 在参数中指定占位符
        for (User user : users) {
            System.out.println(user);
        }
    }

    @Test
    public void testFindTotal() {
        int cnt = userDao.findTotal();  // 使用聚合函数count查询所有用户数
        System.out.println(cnt);
    }

    @Test
    public void testFindUserByCondition() {
        User user = new User();
        user.setUsername("_%王%");
        user.setSex("女");
        List<User> users = userDao.findUserByCondition(user);
        for (User u : users) {
            System.out.println(u);
        }
    }

    @Test
    public void testFindUserInIds() {
        List<Integer> ids = Arrays.asList(41, 42, 45);
        List<User> users = userDao.findUserInIds(ids);
        for (User u : users) {
            System.out.println(u);
        }
    }
}

 - RoleTest.java

public class RoleTest {
    private InputStream is;
    private SqlSession session;
    private IRoleDao roleDao;

    @Before  // 在测试方法自动调用
    public void init() {
        try {
            // 1.读取配置文件
            is = Resources.getResourceAsStream("SqlMapConfig.xml");
            // 2.创建SqlSessionFactory工厂
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
            // 3.使用工厂生产SqlSession对象
            session = factory.openSession();
            // 4.使用SqlSession创建Dao接口的代理对象
            roleDao = session.getMapper(IRoleDao.class);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @After  // 在测试方法前自动调用
    public void destroy() {
        session.commit();  // 提交事务

        // 释放资源
        if (session != null) {
            session.close();
        }
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    public void testFindAll() {
        List<Role> roles = roleDao.findAll();
        for (Role role : roles) {
            System.out.print(role);
            System.out.println(role.getUsers());
        }
    }

    @Test
    public void testFindAllRole() {
        List<Role> roles = roleDao.findAllRole();
        for (Role role : roles) {
            System.out.println(role);
        }
    }
    
}
View Code

- AccountTest.java

public class AccountTest {
    private InputStream is;
    private SqlSession session;
    private IAccountDao accountDao;

    @Before  // 在测试方法自动调用
    public void init() {
        try {
            // 1.读取配置文件
            is = Resources.getResourceAsStream("SqlMapConfig.xml");
            // 2.创建SqlSessionFactory工厂
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
            // 3.使用工厂生产SqlSession对象
            session = factory.openSession();
            // 4.使用SqlSession创建Dao接口的代理对象
            accountDao = session.getMapper(IAccountDao.class);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @After  // 在测试方法前自动调用
    public void destroy() {
        session.commit();  // 提交事务

        // 释放资源
        if (session != null) {
            session.close();
        }
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    public void testFindAllAccount() {
        List<Account> accounts = accountDao.findAllAccount();
        for (Account account : accounts) {
            System.out.print(account);
            System.out.println("," + account.getUser());
        }
    }

    @Test
    public void testFindAllAccountLazyLoad() {
        List<Account> accounts = accountDao.findAllAccountLazyLoad();
        for (Account account : accounts) {
            System.out.println(account);
            System.out.println("," + account.getUser());
        }
    }

}
View Code

参考:

https://blog.csdn.net/zpcandzhj/article/details/80878563

https://mybatis.org/mybatis-3/zh/getting-started.html

原文地址:https://www.cnblogs.com/q10040/p/13038626.html