mybatis注解开发

创建数据库表

/*
SQLyog Ultimate v12.5.0 (64 bit)
MySQL - 5.7.23-log : Database - test_mybatis
*********************************************************************
*/

/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`test_mybatis` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */;

USE `test_mybatis`;

/*Table structure for table `account` */

DROP TABLE IF EXISTS `account`;

CREATE TABLE `account` (
  `ID` int(11) NOT NULL COMMENT '编号',
  `UID` int(11) DEFAULT NULL COMMENT '用户编号',
  `MONEY` double DEFAULT NULL COMMENT '金额',
  PRIMARY KEY (`ID`),
  KEY `FK_Reference_8` (`UID`),
  CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `account` */

insert  into `account`(`ID`,`UID`,`MONEY`) values 
(1,46,1000),
(2,45,1000),
(3,46,2000);

/*Table structure for table `role` */

DROP TABLE IF EXISTS `role`;

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`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `role` */

insert  into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values 
(1,'院长','管理整个学院'),
(2,'总裁','管理整个公司'),
(3,'校长','管理整个学校');


/*Table structure for table `user` */

DROP TABLE IF EXISTS `user`;

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`)
) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8;

/*Data for the table `user` */

insert  into `user`(`id`,`username`,`birthday`,`sex`,`address`) values 
(41,'老王','2018-02-27 17:47:08','男','北京'),
(45,'阿宁','2018-03-04 12:04:06','男','南京'),
(46,'老李','2018-03-07 17:37:26','男','上海'),
(48,'小马宝莉','2018-03-08 11:44:00','女','广东');

/*Table structure for table `user_role` */

DROP TABLE IF EXISTS `user_role`;

CREATE TABLE `user_role` (
  `UID` int(11) NOT NULL COMMENT '用户编号',
  `RID` int(11) NOT NULL COMMENT '角色编号',
  PRIMARY KEY (`UID`,`RID`),
  KEY `FK_Reference_10` (`RID`),
  CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),
  CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `user_role` */

insert  into `user_role`(`UID`,`RID`) values 
(41,1),
(45,2),
(46,2),
(45,3),
(48,3);

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

多对多的关系是user-------user_role--------role(关系表)

1、搭建一个maven项目

2、引入mybatis需要的依赖

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.12</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
    </dependency>

    <!-- mybatis核心包 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.1</version>
    </dependency>

3、配置log4j和mysql

在resources目录下新建mybatis的核心配置文件log4j.properties和mysql.properties

# 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\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=D:\\Mybatis\\mybatis
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\n
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/test_mybatis?useUnicode=true&characterEncoding=UTF-8
jdbc.username = root
jdbc.password = 123456

4、使用 Mybatis 注解实现基本 CRUD

4.1创建User实体类

package com.ning.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

/**
 * @author aning
 */
public class User implements Serializable {

    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;

    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;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}

4.2搭建注解开发环境

在resources目录下新建mybatis的核心配置文件mybatis-config.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>
    <!-- 配置连接数据库的信息
     resource 属性:
     用于指定 properties 配置文件的位置,要求配置文件必须在类路径下  resource="jdbcConfig.properties" -->
    <!--配置properties-->
    <properties resource="properties/mysql.properties"></properties>


<!--使用typeAliases配置别名,它只能配置entity中类的别名-->
    <typeAliases>
          <!--typeAlias用于配置别名,type属性指的是实体类全限定类名,alias属性指定别名,当指定了别名就不在区分大小写-->
          <!--<typeAlias alias="Employee" type="com.ning.entity.Employee"/>-->
        <!--用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不在区分大小写-->
        <!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
        <package name="com.ning.entity"/>
        <!--  <package name="其他存放实体类的包路径"/> -->
    </typeAliases>

    <!-- 配置 mybatis 的环境 -->
    <environments default="mysql">
        <!-- 配置 mysql 的环境 -->
        <environment id="mysql">
            <!-- 配置事务的类型 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置连接数据库的信息:用的是数据源(连接池) -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 指定带有注解的dao接口所在位置 -->
    <mappers>
        <!--package标签是用于指定mapper接口所在的包,当指定了之后就不需要在写mapper以及resource或者class了-->
        <package name="com.ning.mapper"></package>
    </mappers>
    
</configuration>

4.3编写User的持久层接口并使用注解配置

package com.ning.mapper;

import com.ning.entity.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**
 * @author aning
 *
 * 用户的持久层接口
 */
public interface IUserMapper {

    /**
     * 查询所有用户
     * @return
     */
    @Select("select * from user")
    List<User> findAll();

    /**
     * 保存用户
     * @param user
     */
    @Insert("insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})")
    void saveUser(User user);

    /**
     * 更新用户
     * @param user
     */
    @Update("update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id=#{id}")
    void updateUser(User user);

    /**
     * 删除用户
     * @param userId
     */
    @Delete("delete from user where id=#{id} ")
    void deleteUser(Integer userId);

    /**
     * 根据id查询用户
     * @param userId
     * @return
     */
    @Select("select * from user  where id=#{id} ")
    User findById(Integer userId);

    /**
     * 根据用户名称模糊查询
     * @param username
     * @return
     */
    
    @Select("select * from user where username like '%${value}%' ")
    List<User> findUserByName(String username);

    /**
     * 查询总用户数量
     * @return
     */
    @Select("select count(*) from user ")
    int findTotalUser();

}

4.4编写测试方法

 package test;


import com.ning.entity.User;
import com.ning.mapper.IUserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.Date;
import java.util.List;


public class UserTest {
    private InputStream in;
    private SqlSession sqlSession;
    private IUserMapper iUserMapper;

    @Before//用于在测试方法执行之前执行
    public void init()throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("mybatis-config.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SqlSession对象
        sqlSession = factory.openSession();
        //4.获取dao的代理对象
        iUserMapper = sqlSession.getMapper(IUserMapper.class);
    }

     //5.执行Dao的方法

    /**
     * 测试基于注解的删除添加操作
     * @param
     */
    @Test
    public void testSave(){
        User user = new User();
        user.setUsername("mybatis annotation");
        user.setAddress("北京市昌平区");

        iUserMapper.saveUser(user);
    }

    /**
     * 测试基于注解的更新操作
     * @param
     */
    @Test
    public void testUpdate(){
        User user = new User();
        user.setId(57);
        user.setUsername("mybatis annotation update");
        user.setAddress("北京市海淀区");
        user.setSex("男");
        user.setBirthday(new Date());

        iUserMapper.updateUser(user);
    }

    /**
     * 测试基于注解的删除操作
     * @param
     */
    @Test
    public void testDelete(){
        iUserMapper.deleteUser(1);
    }

    /**
     * 测试基于注解的根据id查找操作
     * @param
     */
    @Test
    public void testFindOne(){
        User user = iUserMapper.findById(57);
        System.out.println(user);
    }

    /**
     * 测试基于注解的根据用户名查找操作
     * @param
     */
    @Test
    public  void testFindByName(){
        List<User> users = iUserMapper.findUserByName("阿宁");
        for(User user : users){
            System.out.println(user);
        }
    }

    /**
     * 测试基于注解的查询数据总数操作
     * @param
     */
    @Test
    public  void testFindTotal(){
        int total = iUserMapper.findTotalUser();
        System.out.println(total);
    }



@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
    //提交事务
    sqlSession.commit();
    //6.释放资源
    sqlSession.close();
    in.close();
   }
}

5.使用注解实现复杂关系映射开发

实现复杂关系映射之前我们可以在映射文件中通过配置resultMap来实现,在使用注解开发时我们需要借助@Results 注解,@Result 注解,@One 注解,@Many 注解。

5.1复杂关系映射的注解说明

@Results 注解 代替的是标签<resultMap>  
	该注解中可以使用单个@Result 注解,也可以使用@Result 集合
	 @Results({@Result(),@Result()})@Results(@Result()) 


@Resut 注解 代替了 <id>标签和<result>标签  
	@Result 中 属性介绍:  
	   id 是否是主键字段 
	   column 数据库的列名 
	   property 需要装配的属性名 
	   one  需要使用的@One 注解(@Result(one=@One)())) 
	   many  需要使用的@Many 注解(@Result(many=@many)()))  
	   
@One 注解(一对一)  
    代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@One 注解属性介绍: 
    select  指定用来多表查询的 sqlmapper  
    fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。
    使用格式:  @Result(column=" ",property="",one=@One(select=""))   

@Many 注解(多对一)  
    代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。 
    注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType (一般为 ArrayList)但是注解中可以不定义;  
  使用格式:@Result(property="",column="",many=@Many(select=""))

5.2使用注解实现一对一复杂关系映射及延迟加载

需求: 加载账户信息时并且加载该账户的用户信息,根据情况可实现延迟加载。(注解方式实现)

5.2.1 添加 User 实体类及 Account 实体类

package com.ning.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * @author aning
 */
public class User implements Serializable {

    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;

    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;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}

package com.ning.entity;

import java.io.Serializable;

/**
 * @author aning
 */
public class Account implements Serializable {

    private Integer id;
    private Integer uid;
    private Double money;

   //多对一关系映射:从表方应该包含一个主表方的对象引用 
    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 getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", uid=" + uid +
                ", money=" + money +
                '}';
    }
}

5.2.2 添加账户的持久层接口并使用注解配置

package com.ning.mapper;

import com.ning.entity.Account;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

/**
 * @author aning
 *
 * 账户的持久层接口
 */
public interface IAccountMapper {

    /**
     * 查询所有账户,并且获取每个账户所属的用户信息
     * @return
     */
    @Select("select * from account")
    @Results(id="accountMap",value = {
            @Result(id=true,column = "id",property = "id"),
            @Result(column = "uid",property = "uid"),
            @Result(column = "money",property = "money"),
            @Result(property = "user",column = "uid",one=@One(select="com.ning.mapper.IUserMapper.findById",
                    //一对一最好用立即加载 FetchType.EAGER
                    fetchType= FetchType.EAGER))
    })

    List<Account> findAll();
}

5.2.3 添加用户的持久层接口并使用注解配置

package com.ning.mapper;

import com.ning.entity.User;
import org.apache.ibatis.annotations.*;
    /**
     * 根据id查询用户
     * @param userId
     * @return
     */
    @Results(id="userMap",value={
            @Result(id=true,column = "id",property = "userId"),
            @Result(column = "username",property = "username"),
            @Result(column = "address",property = "address"),
            @Result(column = "sex",property = "sex"),
            @Result(column = "birthday",property = "birthday")
    })
    
    @Select("select * from user  where id=#{id} ")
    User findById(Integer userId);
}

5.2.4 测试一对一关联及延迟加载

package test;

import com.ning.entity.Account;
import com.ning.mapper.IAccountMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.List;

public class AccountTest {
    private InputStream in;
    private SqlSession sqlSession;
    private IAccountMapper iAccountMapper;

    @Before//用于在测试方法执行之前执行
    public void init()throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("mybatis-config.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SqlSession对象
        sqlSession = factory.openSession();
        //4.获取dao的代理对象
        iAccountMapper = sqlSession.getMapper(IAccountMapper.class);
    }

    @After//用于在测试方法执行之后执行
    public void destroy()throws Exception{
        //提交事务
        sqlSession.commit();
        //6.释放资源
        sqlSession.close();
        in.close();
    }

    //5.执行Dao的方法
    @Test
    public void testFindAll(){
        List<Account> accounts = iAccountMapper.findAll();
        for(Account account : accounts){
            System.out.println("----每个账户的信息-----");
            System.out.println(account);
            System.out.println(account.getUser());
        }
    }


}

5.3 使用注解实现一对多复杂关系映射

需求: 查询用户信息时,也要查询他的账户列表。使用注解方式实现。
分析: 一个用户具有多个账户信息,所以形成了用户(User)与账户(Account)之间的一对多关系。

5.3.1 User 实体类加入 List< Account >*

package com.ning.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

/**
 * @author aning
 */
public class User implements Serializable {

    private Integer userId;
    private String username;
    private String address;
    private String sex;
    private Date birthday;

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

    public List<Account> getAccounts() {
        return accounts;
    }

    public void setAccounts(List<Account> accounts) {
        this.accounts = accounts;
    }

    public Integer getUserId() {
        return userId;
    }

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

    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;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", username='" + username + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday=" + birthday +
                ", accounts=" + accounts +
                '}';
    }
}

5.3.2 编写用户的持久层接口并使用注解配置

package com.ning.mapper;

import com.ning.entity.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;

/**
 * @author aning
 *
 * 用户的持久层接口
 */
public interface IUserMapper {

    /**
     * 查询所有用户
     * @return
     */
    @Select("select * from user")
    @Results(id="userMap",value={
            @Result(id=true,column = "id",property = "userId"),
            @Result(column = "username",property = "username"),
            @Result(column = "address",property = "address"),
            @Result(column = "sex",property = "sex"),
            @Result(column = "birthday",property = "birthday"),
            @Result(property = "accounts",column = "id",
                    many = @Many(select = "com.ning.mapper.IAccountMapper.findAccountByUid",
                            //一对多最好用延迟加载FetchType.LAZY
                            fetchType = FetchType.LAZY))
    })
    List<User> findAll();
}


@Many: 
	 相当于<collection>的配置  
	 select 属性:代表将要执行的 sql 语句  
	 fetchType 属性:代表加载方式,一般如果要延迟加载都设置为 LAZY 的值 

5.3.3 编写账户的持久层接口并使用注解配置

package com.ning.mapper;

import com.ning.entity.Account;
import org.apache.ibatis.annotations.Select;
import java.util.List;

/**
 * @author aning
 *
 * 账户的持久层接口
 */
public interface IAccountMapper {

    /**
     * 根据用户id查询账户信息
     * @param uId
     * @return
     */
    @Select("select * from account where uid = #{uId}")
    List<Account> findAccountByUid(Integer uId);
}

5.3.4 添加测试方法

package test;

import com.ning.entity.User;
import com.ning.mapper.IUserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;

public class UserTest {
    private InputStream in;
    private SqlSession sqlSession;
    private IUserMapper iUserMapper;

    @Before//用于在测试方法执行之前执行
    public void init()throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("mybatis-config.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SqlSession对象
        sqlSession = factory.openSession();
        //4.获取dao的代理对象
        iUserMapper = sqlSession.getMapper(IUserMapper.class);
    }

    @Test
    public  void  testFindAll(){
        List<User> users = iUserMapper.findAll();
        for(User user : users){
            System.out.println("---每个用户的信息----");
            System.out.println(user);
            System.out.println();
            System.out.println(user.getAccounts());
         }
    }
    

    @After//用于在测试方法执行之后执行
public void destroy()throws Exception{
    //提交事务
    sqlSession.commit();
    //6.释放资源
    sqlSession.close();
    in.close();
  }
}

6. 使用注解实现多对多复杂关系映射

*6.1. User 实体类加入 List< Role> *

package com.ning.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * @author aning
 */
public class User implements Serializable {

    private Integer userId;
    private String username;
    private String address;
    private String sex;
    private Date birthday;

    
  //多对多的关系映射:一个用户可以赋予多个角色
     private  List<Role> roles;

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public Integer getUserId() {
        return userId;
    }

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

    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;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", username='" + username + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday=" + birthday +
                ", roles=" + roles +
                '}';
    }
}

*6.2 Role 实体类加入 List< User> *

package com.ning.entity;

import java.io.Serializable;
import java.util.List;

/**
 * @author aning
 */
public class Role implements Serializable {
    private Integer roleId;
    private String roleName;
    private String roleDesc;
    //多对多的关系映射:一个角色可以赋予多个用户
    private List<User> users;
    public List<User> getUsers() {
        return users;
    }
    public void setUsers(List<User> users) {
        this.users = users;
    }
    public Integer getRoleId() {
        return roleId;
    }
    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }
    public String getRoleName() {
        return roleName;
    }
    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
    public String getRoleDesc() {
        return roleDesc;
    }
    public void setRoleDesc(String roleDesc) {
        this.roleDesc = roleDesc;
    }
    @Override
    public String toString() {
        return "Role{" +
                "roleId=" + roleId +
                ", roleName='" + roleName + '\'' +
                ", roleDesc='" + roleDesc + '\'' +
                ", users=" + users +
                '}';
    }
}


6.3 编写用户的持久层接口并使用注解配置

package com.ning.mapper;

import com.ning.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
 * @author aning
 *
 * 用户的持久层接口
 */
public interface IUserMapper {
    /**
     * 查询所有用户
     * @return
     */
    //根据uid查询用户
    @Select("select * from user")
    @Results(id="userMap",value={
            @Result(id=true,column = "id",property = "userId"),
            @Result(column = "username",property = "username"),
            @Result(column = "address",property = "address"),
            @Result(column = "sex",property = "sex"),
            @Result(column = "birthday",property = "birthday"),
            @Result(property = "roles",
                    column = "id",//User对象对应的数据库主键id字段,作为参数传递到findRoleAndUserByUId中进行查询的参数
                    many = @Many(select = "com.ning.mapper.IRoleMapper.findRoleAndUserByUId"))
    })
    List<User> findAll();

    /**
     *多对多查询(根据id查询用户及其所对应的角色)
     * @param rId
     * @return
     */
    @Select("SELECT * FROM USER u LEFT OUTER JOIN user_role ur ON u.id = ur.uid WHERE ur.rid= #{rId}")
    @ResultMap("userMap")
    User findUserAndRoleByRId(Integer rId);
}

6.4 编写角色的持久层接口并使用注解配置*

package com.ning.mapper;

import com.ning.entity.Role;
import com.ning.entity.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * @author aning
 *
 * 角色的持久层接口
 */
public interface IRoleMapper {

    //通过rId查询角色信息
    @Select("Select * from role")
    @Results(id = "roleMap",value={
            @Result(property = "roleId",column = "id"),
            @Result(property = "roleName",column = "role_name"),
            @Result(property = "roleDesc",column = "role_desc"),
            @Result(property = "users",
                    column = "ID",//Role对象的数据库主键id字段,作为参数传递到findUserAndRoleByRId中进行查询的参数
                    many = @Many(select = "com.ning.mapper.IUserMapper.findUserAndRoleByRId"))
    })
    List<Role> findAll();
    /**
     *多对多查询(根据id查询用户及其所对应的角色)
     * @param uId
     * @return
     */
    @Select("SELECT * FROM Role r LEFT OUTER JOIN user_role ur ON r.id= ur.rid WHERE ur.uid = #{uId}")
    @ResultMap("roleMap")
    User findRoleAndUserByUId(Integer uId);

}

6.5 编写用户测试类

package test;
import com.ning.entity.Role;
import com.ning.entity.User;
import com.ning.mapper.IUserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class UserTest {
    private InputStream in;
    private SqlSession sqlSession;
    private IUserMapper iUserMapper;

    @Before//用于在测试方法执行之前执行
    public void init()throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("mybatis-config.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SqlSession对象
        sqlSession = factory.openSession();
        //4.获取dao的代理对象
        iUserMapper = sqlSession.getMapper(IUserMapper.class);
    }
    @Test
    public void showAllUserAndRole(){
         List<User> users =iUserMapper.findAll();
          for (User user:users){
              System.out.print(user.getUserId()+"\t"+user.getUsername()+"\t");
              for (Role role:user.getRoles()){
                  System.out.print(" "+role.getRoleId()+"  "+role.getRoleName());
              }
              System.out.println();
          }
    }
    @After//用于在测试方法执行之后执行
    public void destroy()throws Exception{
        //提交事务
        sqlSession.commit();
        //6.释放资源
        sqlSession.close();
        in.close();
    }
}

6.6 编写角色测试类

package test;

import com.ning.entity.Role;
import com.ning.entity.User;
import com.ning.mapper.IRoleMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.List;

public class RoleTest {

    private InputStream in;
    private SqlSession sqlSession;
    private IRoleMapper iRoleMapper;

    @Before//用于在测试方法执行之前执行
    public void init()throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("mybatis-config.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SqlSession对象
        sqlSession = factory.openSession();
        //4.获取dao的代理对象
        iRoleMapper = sqlSession.getMapper(IRoleMapper.class);
    }

    @Test
    public void showAllRoleAndUser(){
        List<Role> roles =iRoleMapper.findAll();
        for (Role role : roles){
            System.out.print(role.getRoleId()+"\t"+role.getRoleName());
             for (User user:role.getUsers()){
                 System.out.print(" "+user.getUsername()+" "+user.getSex());
             }
            System.out.println();
        }
    }

    @After//用于在测试方法执行之后执行
    public void destroy()throws Exception{
        //提交事务
        sqlSession.commit();
        //6.释放资源
        sqlSession.close();
        in.close();
    }

}

7. mybatis 基于注解的二级缓存

在 SqlMapConfig 中开启二级缓存支持

<!-- 配置二级缓存 --> <settings> 
 <!-- 开启二级缓存的支持 -->  <setting name="cacheEnabled" value="true"/> </settings> 

在持久层接口中使用注解配置二级缓存

@CacheNamespace(blocking=true)//mybatis 基于注解方式实现配置二级缓存 public interface IUserMapper {} 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值