Mybatis注解开发:基本CRUD、一对多映射、多对一映射、延迟加载 、二级缓存

Java 1007℃

1.准备工作

创建maven、添加jar包坐标、log4j的配置文件等准备工作可以参考:IDEA中Maven工程的MyBatis快速入门

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>
    <settings>
        <!-- 开启延迟加载 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
        <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>
    <environments default="local">
        <!-- 数据库环境配置 -->
        <environment id="local">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="sxd5443380"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!-- 映射接口包路径 -->
        <package name="com.gqzzw.mapper"/>
    </mappers>
</configuration>

3.编写实体类

假如数据库内容为:

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`sex` char(1) default NULL COMMENT '性别',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into `user`(`id`,`username`,`sex`) values (41,'老王','男'),(42,'小二王','女'),(43,'小三王','女');
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`),
CONSTRAINT `FK_Reference_1` FOREIGN KEY (`uid`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into `account`(`id`,`uid`,`money`) values (1,41,1000),(2,42,1000),(3,42,2000);

需要创建的User类具有相同的数表字段名,同时需要实现Serializable接口,放在src/main/java下,代码如下:

package com.gqzzw.domain;

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

public class User implements Serializable {
    private int id;
    private String username;
    private char sex;
    private List<Account> accounts;

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

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public char getSex() {
        return sex;
    }

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

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

还需要创建的Account类具有相同的数表字段名,同时需要实现Serializable接口,放在src/main/java下,代码如下:

package com.gqzzw.domain;

import java.io.Serializable;

public class Account implements Serializable {
    private int id;
    private int uid;
    private double money;
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getUid() {
        return uid;
    }

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

    public double getMoney() {
        return money;
    }

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

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

4.编写实体类的持久层映射接口

这里对应的User类持久层映射接口取名UserMapper,放在src/main/java下,代码如下:

package com.gqzzw.mapper;

import com.gqzzw.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

@CacheNamespace(blocking = true)//开启二级缓存
public interface UserMapper {
    //保存用户
    @Insert("insert into user(username,sex) value(#{username},#{sex})")
    void save(User user);
    //修改用户
    @Update("update user set username=#{username},sex=#{sex} where id=#{id}")
    void update(User user);
    //根据id查询
    @Select("select * from user where id=#{id}")
    List<User> findById(int id);
    //删除用户
    @Delete("delete from user where id=#{id}")
    void delete(User user);
    //一对多查询
    @Select("select * from user")
    @Results(value = {
            @Result(id = true,column = "id",property = "id"),
            @Result(column = "username",property = "username"),
            @Result(column = "sex",property = "sex"),
            @Result(column = "id",property = "accounts",
                    many = @Many(select = "com.gqzzw.mapper.AccountMapper.findByUid", fetchType = FetchType.LAZY))
    })
    List<User> findAll();
}

这里对应的Account类持久层映射接口取名AccountMapper,放在src/main/java下,代码如下:

package com.gqzzw.mapper;

import com.gqzzw.domain.Account;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

@CacheNamespace(blocking = true)//开启二级缓存
public interface AccountMapper {
    //多对一查询
    @Select("select * from account")
    @Results(value = {
            @Result(id = true,column = "id",property = "id"),
            @Result(column = "uid",property = "uid"),
            @Result(column = "money",property = "money"),
            @Result(column = "uid",property = "user",
                    one = @One(select = "com.gqzzw.mapper.UserMapper.findById",fetchType = FetchType.EAGER))
    })
    List<Account> findAll();
    //根据uid查询账户
    @Select("select * from account where uid=#{uid}")
    List<Account> findByUid(int uid);
}

5.编写测试类

放在src/test/java下,编写测试类UserMapperTest,内容如下:

package com.gqzzw.mapper;

import com.gqzzw.domain.User;
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.IOException;
import java.io.InputStream;
import java.util.List;

public class UserMapperTset {
    private InputStream in;
    private SqlSessionFactory factory;
    private SqlSession sqlSession;
    private UserMapper userMapper;

    @Before
    public void init() throws IOException {
        //读取配置文件
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory的构建者对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //使用构建者创建工厂对象SqlSessionFactory
        factory = builder.build(in);
        //使用SqlSessionFactory产SqlSession对象生
        sqlSession = factory.openSession();
        //产SqlSession对象时可以传true代表自动提交事务
        //sqlSession = factory.openSession(true);
        //使用SqlSession创建映射接口的代理对象
        userMapper = sqlSession.getMapper(UserMapper.class);
    }

    @After
    public void destroy() throws IOException {
        //提交事务,释放资源
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }
    //保存用户
    @Test
    public void save(){
        User user = new User();
        user.setUsername("05bk.com");
        user.setSex('男');
        userMapper.save(user);
    }
    //修改用户
    @Test
    public void update(){
        User user = new User();
        user.setId(43);
        user.setUsername("05bk");
        user.setSex('女');
        userMapper.update(user);
    }
    //根据id查询
    @Test
    public void findById(){
        List<User> users = userMapper.findById(43);
        System.out.println(users);

    }
    //删除用户
    @Test
    public void delete(){
        User user = new User();
        user.setId(43);
        userMapper.delete(user);
    }
    //一对多查询
    @Test
    public void findAll(){
        List<User> users = userMapper.findAll();
        for (User user : users) {
            System.out.println(user);
            System.out.println(user.getAccounts());

        }
    }

}

放在src/test/java下,编写测试类AccountMapperTest,内容如下:

package com.gqzzw.mapper;

import com.gqzzw.domain.Account;
import com.gqzzw.domain.User;
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.IOException;
import java.io.InputStream;
import java.util.List;

public class AccountMapperTset {
    private InputStream in;
    private SqlSession sqlSession;
    private AccountMapper accountMapper;

    @Before
    public void init() throws IOException {
        //读取配置文件
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory的构建者对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //使用构建者创建工厂对象SqlSessionFactory
        SqlSessionFactory factory = builder.build(in);
        //使用SqlSessionFactory产SqlSession对象生
        sqlSession = factory.openSession();
        //产SqlSession对象时可以传true代表自动提交事务
        //sqlSession = factory.openSession(true);
        //使用SqlSession创建映射接口的代理对象
        accountMapper = sqlSession.getMapper(AccountMapper.class);
    }

    @After
    public void destroy() throws IOException {
        //提交事务,释放资源
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }
    @Test
    //多对一查询
    public void findAll(){
        List<Account> accounts = accountMapper.findAll();
        for (Account account : accounts) {
            System.out.println(account);
            System.out.println(account.getUser());
        }
    }
    @Test
    //根据uid查询账户
    public void findByUid(){
        List<Account> accounts = accountMapper.findByUid(42);
        System.out.println(accounts);
    }

}

转载请注明:零五宝典 » Mybatis注解开发:基本CRUD、一对多映射、多对一映射、延迟加载 、二级缓存