mybatis学习第一天

111 阅读4分钟

这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

简介

什么是 MyBatis?

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。(官网说的)

入门

构建一个普通maven工程,导入依赖

<dependencies>
//mybatis依赖
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    //mysql依赖
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    //单元测试依赖
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    //lombok依赖
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.20</version>
    </dependency>
</dependencies>
//maven静态资源过滤配置文件
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>
数据库表

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6e40c05ab9274d5191375d0a2fd11c76~tplv-k3u1fbpfcp-watermark.image?)
连接数据库配置文件,注册mapper
```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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_test?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
//注册mapper
    <mappers>
        <mapper resource="com/study/mapping/UserMapper.xml"/>
    </mappers>
</configuration>

配置连接数据库工具类

public class MybatisUtils {

   private static SqlSessionFactory sqlSessionFactory;

   static {
       try {
           //获取核心配置文件获取sqlSessionFactory
           String resource = "mybatsi-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      } catch (IOException e) {
           e.printStackTrace();
      }
  }

    //获取SqlSession连接
    public static SqlSession getSession(){
        return sqlSessionFactory.openSession();
    }
}

实体类

@Data
public class User {
    private int id;  //id
    private String name;   //姓名
    private String pwd;   //密码
}

接口

public interface UserMapper {
    //查询所有
    List<User> selectUser();
}

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">
<!--绑定mapping接口-->
<mapper namespace="com.study.mapping.UserMapper">
    <select id="selectUser" resultType="com.study.pojo.User">
        select * from user
    </select>
</mapper>

测试类

 @Test
 public void selectUser() {
     //获取sqlsession
     SqlSession session = MybatisUtils.getSession();
     UserMapper mapper = session.getMapper(UserMapper.class);
     List<User> users = mapper.selectUser();

     for (User user: users){
         System.out.println(user);
    }
     session.close();
}

运行结果

image.png

进门了

接下来看 Crud

先看UserMapper里的个标签意思

image.png

    namespace 对应的接口的全路径名
    select 查询标签
    insert 插入标签
    delect 删除
    update 更新标签
    id 对应的方法名
    resultType  返回值类型
    parameterType 入参类型
//根据id查询
User findUserById(Integer id);
//新增一个用户
void InserUser(User user);
//更新用户信息
void updateUser(User user);
// 删除用户信息
void deleteUserById(Integer id);

增删改查mapper.xml

<select id="findUserById" resultType="com.study.pojo.User" parameterType="int">
    select * from user where id =#{id}
</select>

<insert id="InserUser" parameterType="com.study.pojo.User" >
    insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>

<update id="updateUser" parameterType="com.study.pojo.User">
    update user set name=#{name},pwd=#{pwd} where  id = #{id}
</update>

<delete id="deleteUserById" parameterType="Int">
    delete
    from user
    where id=#{id};
</delete>

接口

//根据id查询
User findUserById(Integer id);
//新增一个用户
void InserUser(User user);
//更新用户信息
void updateUser(User user);
// 删除用户信息
void deleteUserById(Integer id);

测试类

@Test
public void  test2(){
    //获取sqlsession
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    User userById = mapper.findUserById(1);
    System.out.println(userById);
    session.close();
}


  @Test
  public void  test3(){
      //获取sqlsession
      SqlSession session = MybatisUtils.getSession();
      UserMapper mapper = session.getMapper(UserMapper.class);
      User user = new User();
      user.setId(4);
      user.setName("王麻子");
      user.setPwd("12345");
      mapper.InserUser(user);
      //提交
      session.commit();
      //关闭资源
      session.close();
  }

  @Test
  public void  test4(){
      //获取sqlsession
      SqlSession session = MybatisUtils.getSession();
      UserMapper mapper = session.getMapper(UserMapper.class);
      User user = new User();
      user.setId(4);
      user.setName("王麻子修改后");
      user.setPwd("12345");
      mapper.updateUser(user);
      //提交
      session.commit();
      //关闭资源
      session.close();
  }
  @Test
  public void  test5(){
      //获取sqlsession
      SqlSession session = MybatisUtils.getSession();
      UserMapper mapper = session.getMapper(UserMapper.class);
      mapper.deleteUserById(2);
      //提交
      session.commit();
      //关闭资源
      session.close();
  }

数据库结果

image.png

parameterType

参数类型,mapper接口的形参类型,给mybatis来给sql语句参数来赋值的,有两种写法,第一种是写java类型的全新定类型名称,第二种是写mybatsi自定义的别名(下图),还有可以不写可以通过反射自己去获取

image.png

给参数赋值,接口的形参是简单数据类型(java基本数据类型和String)我们常用#{任意字符},

只有一个入参的情况下我,我们直接写一个如上边代码findUserById()方法,
有多个简单参数,我们的就得使用@Param注解来绑定参数,参数比较多的情况下我们使用对象来做参数,比如上边的updateUser(),对象类型也可以是自定义的,要有getset方法。

接口

List<User> findUserNameOrPwd (@Param("username") String userName,@Param("pwd") String pwd);

xml

<select id="findUserNameOrPwd" resultType="com.study.pojo.User">
    select  * from user where name = #{username} or pwd = #{pwd}
</select>

测试类

@Test
public void selectUserLlike1() {
    //获取sqlsession
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    List<User> users = mapper.findUserNameOrPwd("王麻子","123456");

    for (User user: users){
        System.out.println(user);
    }
    session.close();
}

如果不用来绑定参数,他就不知道哪个传给哪个,就会出现下图的报错

image.png

还有一种方法,我们可以通过位置来写多个普通参数传参#{arg0}#{arg1}....
List<User> findUserNameOrPwd1 ( String userName, String pwd);
<select id="findUserNameOrPwd1" resultType="com.study.pojo.User">
    select  * from user where name = #{arg0} or pwd = #{arg1}
</select>
@Test
public void selectUserLlike2() {
    //获取sqlsession
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    List<User> users = mapper.findUserNameOrPwd1("王麻子","123456");

    for (User user: users){
        System.out.println(user);
    }
    session.close();
}
还可以使用map来赋值
List<User> findUserByMap (Map<String,Object> map);
<select id="findUserByMap" resultType="com.study.pojo.User">
    select  * from user where name = #{username} or pwd = #{pwd}
</select>
@Test
public void selectUserByMap() {
    //获取sqlsession
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    HashMap<String, Object> map = new HashMap<>();
    map.put("username","王麻子");
    map.put("pwd","123456");
    List<User> users = mapper.findUserByMap(map);

    for (User user: users){
        System.out.println(user);
    }
    session.close();
}
#和$

处理占位符# 使用的是PrepareStatment对象,创建PrepareStatment对象,执行sql语句,遇到一个#变成一个占位符,然后通过set方法去给?赋值。 #{}的特点

  1. 使用PrepareStatment对象效率高
  2. 避免sql注入
  3. #{}作为列的值使用,位于等号的右边,#{}位置的值是和数据类型有关的,set值时匹配数据类型选择set方法

语法格式语法格式{},表示字符创连接,吧sql语句和其他内容链接在一起,创建Statement对象来执行sql语句

${}的特点

  1. 效率低
  2. 使用字符创连接 sql注入问题
  3. 数据原样使用不会区分数据类型
  4. 常用表名列明
${}用法

表名或者列名的时候直接拼接字符串的

需求 : 一个方法实现不同情况用不同列排序
分析 :使用&{}拼不同的列明


List<User> findUserOderyBy(String colmle);
<select id="findUserOderyBy" resultType="com.study.pojo.User">
    select * from user order by ${value}
</select>
@Test
public void selectUserOrderBycomle() {
    //获取sqlsession
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
   // List<User> users = mapper.findUserOderyBy("id");
   // List<User> users = mapper.findUserOderyBy("name");
    List<User> users = mapper.findUserOderyBy("pwd");

    for (User user: users){
        System.out.println(user);
    }
    session.close();
}