小白入门java基础 - mybatis实现MySQL增删改查

2024-01-07 17:55:05

一:前言

????????MyBatis 是一款优秀的持久层框架,它支持定制化?SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的?POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

mybatis特点

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件。易于学习,易于使用。通过文档和源代码,可以比较完全的掌握它的设计思路和实现。

  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。

  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。

  • 提供映射标签,支持对象与数据库的ORM字段关系映射。

  • 提供对象关系映射标签,支持对象关系组建维护。

  • 提供xml标签,支持编写动态sql。

在本次案例中,我们使用 mybatis 实现对 MySQL 数据库的增删改查操作

二:代码部分

1、项目目录

? ? ? ? 下面是本次实验的项目目录,其中下方是我们的数据库表?

2、数据库初始化

? ? ? ? 新建一个名字为 demo 的 MySQL 数据库,并且运行下列代码创建一张表,在表内随意增添数据

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) DEFAULT NULL,
  `password` varchar(20) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `gender` char(1) DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8;

3、pom.xml 使用依赖

? ? ? ? 在该文件中,导入依赖如下

    <dependencies>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>

        <!-- Mybatis核心 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.13</version>
        </dependency>

        <!-- log4j日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

    </dependencies>

4、resource 资源文件

1)jdbc.properties 配置文件

? ? ? ? 配置数据的url,账号和密码等?

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456

2)log4j.properties 配置文件

????????配置日志文件的相关参数

log4j.rootLogger=DEBUG,stdout
# MyBatis logging configuration...
# MyBatis
log4j.logger.com.example.test.datasource.mappers.UserMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

3)mybatis-config.xml 配置文件

? ? ? ? 这个是 mybatis 的配置文件,其中文件名是固定的,不能修改,否则会报错

<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis DTD文档约束-->
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--
        mybatis核心配置文件中的标签必须要按照指定的顺序配置
        properties?,settings?,typeAliases?,
        typeHandlers?,objectFactory?,
        objectWrapperFactory?,reflectorFactory?,
        plugins?,environments?,
        databaseIdProvider?,mappers?
    -->

    <!--    引入properties文件,此后就可以在当前文件中使用${key}的方式访问value-->
    <properties resource="jdbc.properties"/>


    <!--
    typeAliases类型别名
        设置类型别名,即为某个具体的类型设置一个别名
        在Mybatis范围中,就可以使用别名表示一个具体的类型
    -->
    <typeAliases>
        <!--
                type:设置需要起别名的类型
                alias:设置某个类型的别名
                如果没有设置alias,当前的类型就拥有默认的别名,即类名且不区分大小写
        -->
        <typeAlias type="com.example.test.datasource.entities.User" alias="User"/>

        <!--通过包类设置类型别名,指定包下所有的类型将全部拥有默认的别名,即类名且不区分大小写-->
    </typeAliases>

    <!--   environments:配置连接数据库的环境
            default:设置默认使用的环境的id
            属性:
                id:设置环境的唯一标识,不能重复
    -->
    <!--在MyBatis中可以配置多套环境,然后通过default来控制采用哪套环境,让配置变得灵活-->
    <environments default="development">
        <environment id="development">
            <!--            transactionManager:设置事务管理器-->
            <!--            属性:-->
            <!--                type:设置事务管理的方式-->
            <!--            type="JDBC|MANAGED-->
            <!--            JDBC:表示使用JDBC原生的事务管理方式-->
            <!--            MANAGED:被管理,例如spring-->
            <!--采取JDBC方式对数据库事务进行commit/rollback-->
            <transactionManager type="JDBC"/>
            <!--            dataSource:设置数据源
                            属性:
                               type:设置数据源类型
                                type="POOLED|UNPOOLED|JNDI"
                                POOLED:表示使用数据库连接池
                                UNPOOLED:表示不是要给你数据库连接池
                                JNDI:表示使用上下文中的数据源
            -->
            <!--采用连接池方式管理数据库连接-->
            <dataSource type="POOLED">
                <!--数据库驱动-->
                <property name="driver" value="${jdbc.driver}"/>
                <!--IP、端口、库、字符集-->
                <!--需要注意的是&在XML中是有意义的,需要使用amp;进行转义-->
                <property name="url" value="${jdbc.url}"/>
                <!--用户名和密码-->
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>

        <!-- 比如下面这个就是另一种环境,不过我们在本次实验中没有使用到 -->
        <environment id="prod">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://148.70.251.110:3306/babytun?useUnicode=yes&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="931548241"/>
            </dataSource>
        </environment>
    </environments>
    <!--    引入mybatis的映射文件-->
    <mappers>
        <mapper resource="mappers/User.xml"/>
    </mappers>
</configuration>

4)mappers.User.xml 映射文件

? ? ? ? 该文件是映射文件,这里需要注意的是,映射文件的 id 需要和前面的接口文件名称保持一致

<?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.example.test.datasource.mappers.UserMapper">
    <!--    namespace需和UserMapper映射接口全类名保持一致  -->
    <!--
    mapper接口和映射文件要保证两个一致
    1、mapper接口的全类名和映射文件的namespace一致
    2、mapper接口中的方法名要和映射文件中的sql的id保持一致
     parameterType:传入数据的类型
        resultType:返回结果类型(这里返回list,mybatis会自动转成User的集合类型)
        ${value}:对于字符串拼接中的占位符,必须用value
        #{ss}:普通占位符,ss和任意取
        parameterType="User" 值User对应配置文件typeAlias设置的别名
    -->
    <insert id="insertUser" useGeneratedKeys="true" keyProperty="id" parameterType="User">
        insert into t_user value (#{id}, #{username}, #{password}, #{age}, #{gender}, #{email})
    </insert>

    <update id="updateUser">
        update t_user
        <set>
            <if test="user.username != null">username=#{user.username},</if>
            <if test="user.password != null">password=#{user.password},</if>
            <if test="user.age != null">age=#{user.age},</if>
            <if test="user.gender != null">gender=#{user.gender},</if>
            <if test="user.email != null">email=#{user.email}</if>
        </set>
        <trim prefix="where" prefixOverrides="AND |OR ">
            <if test="userCondition.id != null">id=#{userCondition.id}</if>
            <if test="userCondition.username != null">AND username=#{userCondition.username}</if>
            <if test="userCondition.password != null">AND password=#{userCondition.password}</if>
            <if test="userCondition.age != null">AND age=#{userCondition.age}</if>
            <if test="userCondition.gender != null">AND gender=#{userCondition.gender}</if>
            <if test="userCondition.email != null">AND email=#{userCondition.email}</if>
        </trim>
    </update>

    <delete id="deleteById">
        delete
        from t_user
        where id = #{id};
    </delete>

    <select id="queryAll" resultType="User">
        select * from t_user
    </select>

    <select id="queryAllByIds">
        select * from t_user where id in
        <foreach collection="array" item="item" index="index" open="(" separator="," close=")">
            #{item}
        </foreach>
    </select>

    <select id="queryAllByIds2">
        select * from t_user
        <foreach collection="list" item="item" index="index" open=" where id in(" separator="," close=")">
            #{item}
        </foreach>
    </select>

    <select id="queryAllByIds3">
        select * from t_user
        <foreach collection="listIds" item="item" index="index" open=" where id in(" separator="," close=")">
            #{item}
        </foreach>
    </select>

    <select id="queryByAge">
        select * from t_user where age > #{age}
    </select>

</mapper>

5、User 实体对象

? ? ? ? 这个类是我们的实体类,和数据库的每一个属性相对应。并且提供 get 和 set 方法。?

package com.example.test.datasource.entities;

public class User {
  private Long id;

  private String username;

  private String password;

  private Integer age;

  private String gender;

  private String email;

  public User(){}

  public User(String username, String password, Integer age, String gender, String email) {
    this.username = username;
    this.password = password;
    this.age = age;
    this.gender = gender;
    this.email = email;
  }

  public Long getId() {
    return id;
  }

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

  public String getUsername() {
    return username;
  }

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

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public Integer getAge() {
    return age;
  }

  public void setAge(Integer age) {
    this.age = age;
  }

  public String getGender() {
    return gender;
  }

  public void setGender(String gender) {
    this.gender = gender;
  }

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }

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

6、UserMapper 接口文件

? ? ? ? 这里和前面的配置文件名称需要保持一致?

package com.example.test.datasource.mappers;

import com.example.test.datasource.entities.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;
import java.util.Map;

public interface UserMapper {

  int insertUser(User user);

  int updateUser(@Param("user") User user, @Param("userCondition") User userCondition);

  int deleteById(int id);

  List<User> queryAll();

  List<User> queryAllByIds(Integer[] ids);

  List<User> queryAllByIds2(List<Integer> list);

  List<User> queryAllByIds3(Map<String, Object> mapIds);

  List<User> queryByAge(Integer age);
  @Select("select * from t_user")
  List<User> queryAll2();

  /**
   * 使用注解传递多个参数
   */
  @Select("select ${fields} from t_user where id = #{id}")
  User queryById(@Param("id") int id, @Param("fields") String fields);

}

7、UserService 接口

package com.example.test.datasource.service;

import com.example.test.datasource.entities.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;
import java.util.Map;

public interface UserService {
  int insertUser(User user);

  int updateUser(User user, User userCondition);

  int deleteById(int id);

  List<User> queryAll();

  List<User> queryAllByIds(Integer[] ids);

  List<User> queryAllByIds2(List<Integer> list);

  List<User> queryAllByIds3(Map<String, Object> mapIds);

  List<User> queryAll2();

  User queryById(int id, String fields);

  List<User> queryByAge(Integer age);
}

8、UserServiceImpl 实现类

package com.example.test.datasource.service;

import com.example.test.datasource.entities.User;
import com.example.test.datasource.mappers.UserMapper;

import java.util.List;
import java.util.Map;

public class UserServiceImpl implements UserService {

  public UserMapper userMapper;

  public UserServiceImpl(UserMapper userMapper){
    this.userMapper = userMapper;
  }

  @Override
  public int insertUser(User user) {
    return userMapper.insertUser(user);
  }

  @Override
  public int updateUser(User user, User userCondition) {
    return userMapper.updateUser(user, userCondition);
  }

  @Override
  public int deleteById(int id) {
    return userMapper.deleteById(id);
  }

  @Override
  public List<User> queryAll() {
    return userMapper.queryAll();
  }

  @Override
  public List<User> queryAllByIds(Integer[] ids) {
    return userMapper.queryAllByIds(ids);
  }

  @Override
  public List<User> queryAllByIds2(List<Integer> list) {
    return userMapper.queryAllByIds2(list);
  }

  @Override
  public List<User> queryAllByIds3(Map<String, Object> mapIds) {
    return userMapper.queryAllByIds3(mapIds);
  }

  @Override
  public List<User> queryAll2() {
    return userMapper.queryAll2();
  }

  @Override
  public User queryById(int id, String fields) {
    return userMapper.queryById(id, fields);
  }
  @Override
  public List<User> queryByAge(Integer age){
    return userMapper.queryByAge(age);
  }
}

9、App 主方法

? ? ? ? 该方法是我们的执行方法,并且定义了增删改查等方法,在实际开发中,我们是需要将其拆分定义到 dao 中的

package com.example.test;

import com.example.test.datasource.entities.User;
import com.example.test.datasource.mappers.UserMapper;
import com.example.test.datasource.service.UserServiceImpl;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.SQL;
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.text.SimpleDateFormat;
import java.util.*;

@SuppressWarnings("all")
public class App
{
  /** 下面是初始化这些公共参数 */
  static String resource = "mybatis-config.xml";
  static InputStream inputStream;
  static {
    try {
      inputStream = Resources.getResourceAsStream(resource);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
  static SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

  public static void main( String[] args ) throws IOException {
    App app = new App();
//    app.select1();
    app.queryByAge();
  }


  /** 查询1*/
  public static void select1() throws IOException {
    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
      UserServiceImpl userService = new UserServiceImpl(sqlSession.getMapper(UserMapper.class));
      List<User> users = userService.queryAll();
      System.out.println(users);
    } catch (Exception e) {
      System.err.println(e.getMessage());
    }
  }


  /** 查询2*/
  public static void select2() throws IOException {
//    String resource = "mybatis-config.xml";
//    InputStream inputStream = Resources.getResourceAsStream(resource);
//    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
      UserServiceImpl userService = new UserServiceImpl(sqlSession.getMapper(UserMapper.class));
      User user = userService.queryById(1, "id,username");

    } catch (Exception e) {
      System.err.println(e.getMessage());
    }
  }

  /** 根据年龄查询,大于18岁*/
  public static void queryByAge() throws IOException {
    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
      UserServiceImpl userService = new UserServiceImpl(sqlSession.getMapper(UserMapper.class));
      List<User> user = userService.queryByAge(18);

    } catch (Exception e) {
      System.err.println(e.getMessage());
    }
  }


  /** 插入*/
  public static void insert() throws IOException {
//    String resource = "mybatis-config.xml";
//    InputStream inputStream = Resources.getResourceAsStream(resource);
//    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    // SqlSession sqlSession = sqlSessionFactory.openSession(true); //加上参数true,会自动提交事务
    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
      UserServiceImpl userService = new UserServiceImpl(sqlSession.getMapper(UserMapper.class));
      User user = new User("小石头", "123456789", 21, "男", "123456789@qq.com");
      int res = userService.insertUser(user);
      // 提交事务
      sqlSession.commit();
      System.out.println((res == 0 ? "新增失败" : "新增成功") + " 自增id=" + user.getId());
    } catch (Exception e) {
      System.err.println(e.getMessage());
    }

  }

  /** 更新*/
  public static void update() throws IOException {
//    String resource = "mybatis-config.xml";
//    InputStream inputStream = Resources.getResourceAsStream(resource);
//    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
      UserServiceImpl userService = new UserServiceImpl(sqlSession.getMapper(UserMapper.class));
      User condition = userService.queryById(1, "id,username,email");
      // 更新字段
      User user = new User();
      user.setEmail("newEmail@qq.com");
      int res = userService.updateUser(user, condition);
      System.out.println((res == 0 ? "更新失败" : "更新成功") + " res=" + res);
    } catch (Exception e) {
      System.err.println(e.getMessage());
    }

  }

  /** 删除*/
  public static void delete() throws IOException {
//    String resource = "mybatis-config.xml";
//    InputStream inputStream = Resources.getResourceAsStream(resource);
//    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
      UserServiceImpl userService = new UserServiceImpl(sqlSession.getMapper(UserMapper.class));
      int res = userService.deleteById(1);
      System.out.println((res == 0 ? "删除失败" : "删除成功") + " res=" + res);
    } catch (Exception e) {
      System.err.println(e.getMessage());
    }

  }

}

10、运行效果

? ? ? ? 这里我们执行的是第一个查询全部的方法,效果如下:

三:结尾

? ? ? ? mybatis 是目前开发中,连接数据较为常用的技术栈,已经逐步开始替代 jdbc ,因此我们要熟练地掌握 mybatis 对数据库的增删改查等操作。当然?mybatis 也可以使用注解进行开发,不过使用注解开发无法解决较为复杂的处理逻辑,因此,本案例是使用的 xml 完成案例实践。好啦本文就到此为止啦,希望能够对各位小伙伴有所帮助哦!

文章来源:https://blog.csdn.net/c18559787293/article/details/135401287
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。