Mybatis中的注解开发

114 阅读5分钟

声明

本博客是基于相关黑马程序员的课程总结而来,感兴趣的可以去看视频教程,没什么废话,还是比较推荐的。 这篇博客其实就是对前面的mybatis的一次总结,用的是比较常用的方法————注解的形式。

计划本博客的内容有:

  1. 坏境的搭建
  2. 单表CRUD操作
  3. 多表查询操作
  4. 缓存的配置

0 数据库的准备

1 环境搭建

1.1 创建一个新的maven工程

pom.xml文件中引入需要用到的依赖 相关代码:

<?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>day04_eesy_03annotation_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>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>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!-- 这是我在后面运行时出现的一个错误的解决方法  java: 错误: 不支持发行版本 5 -->
    <properties>
        <java.version>11</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
    </properties>

</project>

另外:java: 错误: 不支持发行版本 5 问题的解决方法也放在上面了

1.2 单表CRUD操作

1.2.1 创建实体类对象和创建持久层接口

image.png

package com.zhouman.domain;

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

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

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday=" + 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;
    }
}
package com.zhouman.dao;

import com.zhouman.domain.User;
import java.util.List;

public interface IUserDao {
    /**
     * 查询所有用户
     * @return
     */
    List<User> findAll();
}

1.2.2 编写主配置文件

注意是在resource包下

image.png

关于log4j.propertiesjdbcConfig.properties的内容我就不放在这里了,可以百度一下就可以了 jdbcConfig.properties主要放的就是数据连接所需的那四个信息。

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>
    <!-- 引入外部配置文件的形式 -->
    <properties resource="jdbcConfig.properties"></properties>

    <!-- 配置别名 -->
    <typeAliases>
        <package name="com.zhouman.domain"/>
    </typeAliases>

    <!-- 配置环境 -->
    <environments default="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 name="com.zhouman.dao"/>
    </mappers>
</configuration>

1.2.3 在dao持久层接口中的方法体前加对应的注解。

在mybatis中,CRUD一共有四个注解:@Select @Insert @Update @Delect

以findAll方法为例:

package com.zhouman.dao;

import com.zhouman.domain.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;

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

1.2.4 编写测试类进行测试

image.png

  1. 获取字节输入流
  2. 根据字节输入流创建 SqlSessionFactory
  3. 根据 SqlSessionFactory 生产一个 SqlSession
  4. 使用 SqlSession 获取 Dao 的代理对象
  5. 执行 Dao 方法
  6. 释放资源
package com.zhouman.test;

import com.zhouman.dao.IUserDao;
import com.zhouman.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 java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MybatisAnnoTest {
    /**
     * 测试基于注解的 mybatis 使用
     * @param args
     */
    public static void main(String[] args) throws IOException {
        //1. 获取字节输入流
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2. 根据字节输入流创建 SqlSessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3. 根据 SqlSessionFactory 生产一个 SqlSession
        SqlSession sqlSession = sessionFactory.openSession();
        //4. 使用 SqlSession 获取 Dao 的代理对象
        IUserDao userDao = sqlSession.getMapper(IUserDao.class);
        //5. 执行 Dao 方法
        List<User> users = userDao.findAll();
        for (User user : users){
            System.out.println(user);
        }
        //6. 释放资源
        sqlSession.close();
        inputStream.close();
    }
}

运行效果: image.png 我出现问题的话一般在数据库jdbcConfig.properties,要弄清楚文件中的信息和自己数据库的信息是否匹配

1.2.5 用注解的形式实现保存和更新功能

保存用户功能(即添加用户)

在 IUserDao 接口中 创建方法 并写注释

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

创建测试类来测试方法

package com.zhouman.test;

import com.zhouman.dao.IUserDao;
import com.zhouman.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;

public class AnnotationCRUDTest {

    private InputStream inputStream;
    private SqlSessionFactory sessionFactory;
    private SqlSession sqlSession;
    private IUserDao userDao;

    @Before
    public void init() throws IOException {
        //1. 获取字节输入流
        inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2. 根据字节输入流创建 SqlSessionFactory
        sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3. 根据 SqlSessionFactory 生产一个 SqlSession
        sqlSession = sessionFactory.openSession();
        //4. 使用 SqlSession 获取 Dao 的代理对象
        userDao = sqlSession.getMapper(IUserDao.class);
    }

    @After
    public void destroy() throws IOException {
        //6. 释放资源
        sqlSession.commit();
        sqlSession.close();
        inputStream.close();
    }

    @Test
    public void testSave(){
        User user = new User();
        user.setUsername("annotation");
        user.setAddress("广州市荔湾区");

        userDao.saveUser(user);
    }
}

@After @Before的用法之前的博客就介绍过了,因为这两块创建dao代理对象和销毁资源的代码,每个方法都要用,所以提出来单独放,能简化代码。

我运行的结果是这样的: image.png

这是因为中文显示不出来。在jdbcConfig.properties文件中改一下这个就行了:jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis?useUnicode=true&characterEncoding=utf8

改了之后再次运行的结果: image.png

更新用户的功能

在dao接口中创建方法,用注释的形式

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

到测试方法类中写测试方法(也就是上面的那个方法里面)

    @Test
    public void testUpdate(){
        User user = new User();
        user.setId(57);
        user.setUsername("uptate");
        user.setAddress("广州市大学城");
        user.setSex("男");
        user.setBirthday(new Date());

        userDao.updateUser(user);
    }

执行结果:

image.png

删除用户的功能

在dao接口中创建方法,用注释的形式

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

到测试方法类中写测试方法(也就是上面的那个方法里面)

    @Test
    public void testDelete(){
        userDao.deleteUser(58);
        userDao.deleteUser(59);
    }

执行结果:

image.png

根据 id 查询用户功能

在dao接口中创建方法,用注释的形式

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

到测试方法类中写测试方法(也就是上面的那个方法里面)

    @Test
    public void testFindById(){
        System.out.println(userDao.findById(57));
        System.out.println(userDao.findById(58));
    }

执行结果:

image.png

根据 用户名称 模糊查询

在dao接口中创建方法,用注释的形式

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

到测试方法类中写测试方法(也就是上面的那个方法里面)

    @Test
    public void testFindByName(){
        List<User> users = userDao.findByName("%王%");
        for (User user : users){
            System.out.println(user);
        }
    }

执行结果

image.png

查询总用户数量

在dao接口中创建方法,用注释的形式

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

到测试方法类中写测试方法(也就是上面的那个方法里面)

    @Test
    public void testTotalUser(){
        int totalUser = userDao.findTotalUser();
        System.out.println(totalUser);
    }

执行结果:

image.png

总结

博客的内容就到这里,最近杂事儿很多,转行不易。

  1. 多表查询操作
  2. 缓存的配置

留到下一篇博客写。看到这里的读者点个赞呗!