• day02 mybatis


    day02 mybatis

    根据id进行查询

    UserDao

        /**
         * 根据id查询
         */
        User findUserById(Integer id);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    xml代码

    
        <select id="findUserById" parameterType="java.lang.Integer" resultType="com.atguigu.pojo.User">
            select * from user where id = #{id}
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    测试代码

    @Test
    public void testFindUserById(){
        User user = userDao.findUserById(48);
        System.out.println(user);  // User{id=48, username=小马宝莉, password='96543'}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    模糊查询

    核心配置文件.xml 添加日志

     
        <settings>
            <setting name="logImpl" value="STDOUT_LOGGING"/>
        settings>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    打印结果

    在日志初始化的时候,使用标准输出
    Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.log4j:
    
    打开JDBC的链接
    Opening JDBC Connection
    创建链接
    Created connection 1020155847.
    设置自动提交false
    Setting autocommit to false on JDBC Connection 
    [com.mysql.cj.jdbc.ConnectionImpl@3cce57c7]
    执行SQL语句
    ==>  Preparing: select * from user where username like ?
    ==> Parameters: %李%(String)
    <==    Columns: id, password, username, birthday
    <==        Row: 42, 456, 李四, null
    <==      Total: 1
    执行结果
    User{id=42, password=456, username='李四'}
    Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3cce57c7]
    Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3cce57c7]
    执行完毕之后,把链接对象返回到连接池
    Returned connection 1020155847 to pool.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    UserDao代码

        /**
         * 模糊查询
         */
        List<User> findUserByName(String name);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    模糊查询有两种实现方式

    第一种实现方式 使用#{} xml代码

    
        <select id="findUserByName" parameterType="string" resultType="com.atguigu.pojo.User">
            select * from user where username like #{username}
        select>
    
    • 1
    • 2
    • 3
    • 4

    测试代码

        @Test
        public void testFindUserByName(){
    //        第一种实现方法 sql中不需要添加sql 传递的参数需要加上%
            List<User> users = userDao.findUserByName("%李%");
            for (User user : users) {
                System.out.println(user);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    第二种实现方式 使用${} xml代码

    
    
       
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    测试代码

        @Test
        public void testFindUserByName(){
            // 第二种实现方法 在sql中添加% 传递的参数不需要加%
            List<User> users = userDao.findUserByName("李");
            for (User user : users) {
                System.out.println(user);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ${}:字符串连接 字符串替换 UserDao代码

        /**
         * 使用mybatis的替换
         * 如果有多个参数,二个或两个以上参数就必须使用这个注解 注解里面的参数建议跟形参保持一致
         * @param columName
         * @param columValue
         * @return
         */
        List<User> findByNameOrPassword(@Param("columName") String columName, @Param("columValue") String columValue);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    xml代码

    
        <select id="findByNameOrPassword" resultType="com.atguigu.pojo.User">
            select * from user where ${columName} like concat('%', #{columValue}, '%')
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    测试代码

        // 通过username或password进行查找
        @Test
        public void testFindByNameOrPassword(){
            // 使用username进行查找
    //        List userList = userDao.findByNameOrPassword("username", "李");
            // 使用password进行查找
            List<User> userList = userDao.findByNameOrPassword("password", "9");
            for (User user : userList) {
                System.out.println(user);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意:${} 除了拼接和替换以外 其他所有的地方 都必须使用#{}

    聚合函数

    UserDao代码

        /**
         * 查询总用户数
         */
        int findTotal();
    
    • 1
    • 2
    • 3
    • 4

    xml代码

    
        <select id="findTotal" resultType="int">
            select count(*) from user
        select>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    测试代码

        // 测试查询总记录条数
        @Test
        public void testFindTotal(){
            int total = userDao.findTotal();
            System.out.println(total);  // 10
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    复杂的查询

    创建QueryVo类

    package com.atguigu.pojo;
    
    public class QueryVo {
        private User user;
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    UserDao代码

        List<User> findByVo(QueryVo vo);
    
    • 1

    xml代码

     
        <select id="findByVo" resultType="com.atguigu.pojo.User" parameterType="com.atguigu.pojo.QueryVo">
            select * from user where username like #{user.username}
        select>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    测试代码

        @Test
        public void testFindByQueryVo(){
            QueryVo queryVo = new QueryVo();
            User user = new User();
            user.setUsername("%李%");
            queryVo.setUser(user);
            List<User> users = userDao.findByVo(queryVo);
            for (User user1 : users) {
                System.out.println(user1);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    返回结果映射

    新建User2类

    package com.atguigu.pojo;
    
    public class User2 {
        private Integer id;
        private String userName;
        private String pass_word;
    
    
        @Override
        public String toString() {
            return "User2{" +
                    "id=" + id +
                    ", userName='" + userName + '\'' +
                    ", pass_word='" + pass_word + '\'' +
                    '}';
        }
    
        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 getPass_word() {
            return pass_word;
        }
    
        public void setPass_word(String pass_word) {
            this.pass_word = pass_word;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    UserDao代码

        List<User2> findAll2();
    
    
    • 1
    • 2

    xml代码

    
        <resultMap id="userMap" type="com.atguigu.pojo.User2">
            <id column="id" property="id">id>
            <result column="username" property="userName">result>
            <result column="password" property="pass_word">result>
        resultMap>
    
        <select id="findAll2" resultMap="userMap">
            select * from user
        select>
    
    
    
    
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    测试代码

        @Test
        public void testFindAll(){
            List<User2> user2List = userDao.findAll2();
            for (User2 user2 : user2List) {
                System.out.println(user2);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    设置别名

    作用:降低冗余

    在核心配置文件里面设置别名

    
        <typeAliases>
    
            <package name="com.atguigu.pojo"/>
        typeAliases>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    之后在xml配置文件里面 写参数类型 或者写返回值类型可以直接写对象的名称

    <mapper namespace="com.atguigu.dao.UserDao">
    
        <select id="findAll" resultType="user">
            select * from user
        select>
    
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    抽取数据源

    需要在核心配置文件里面获取数据源

    
        <properties resource="jdbc.properties">properties>
    
    • 1
    • 2

    在资源配置文件resources下面创建jdbc.properties

    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    jdbc.username=root
    jdbc.password=123456
    
    • 1
    • 2
    • 3
    • 4

    修改核心配置文件

     <dataSource type="POOLED">
                    <property name="username" value="${jdbc.username}">property>
                    <property name="password" value="${jdbc.password}">property>
    
    • 1
    • 2
    • 3

    连接池

    mybatis中数据源的配置

    测试数据源:

    我们的数据源配置就是在SqlMapConfig.xml文件中,具体配置如下:

    MyBatis在初始化时,解析此文件,根据 的type属性来创建相应类型的的数据源DataSource,即:

    type=”POOLED”:MyBatis会创建PooledDataSource实例

    在这里插入图片描述

    结论:它是从池中获取一个连接来用。

    type=”UNPOOLED” : MyBatis会创建UnpooledDataSource实例

    在这里插入图片描述

    结论:它是每次创建一个新的连接来用。

    所以我们使用连接池的技术会节省连接资源。

    mybatis的事务控制

    JDBC 中事务的回顾

    在 JDBC 中我们可以通过手动方式将事务的提交改为手动方式,通过 setAutoCommit()方法就可以调整。
    通过 JDK 文档,我们找到该方法如下:

    在这里插入图片描述

    那么我们的 Mybatis 框架因为是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式,本身也是用 JDBC 的
    setAutoCommit()方法来设置事务提交方式的。

    Mybatis 中事务提交方式

    Mybatis 中事务的提交方式,本质上就是调用 JDBC 的 setAutoCommit()来实现事务控制。
    我们运行之前所写的代码:

     @Test
        public void testProxyDao() throws IOException {
            InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //获得MyBatis框架生成的UserMapper接口的实现类
            UserDao userMapper = sqlSession.getMapper(UserDao.class);
            User user = userMapper.findById(41);
            System.out.println(user);
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    mybatis自动提交事务的设置

    通过上面的研究和分析,现在我们一起思考,为什么 CUD 过程中必须使用 sqlSession.commit()提交事
    务?主要原因就是在连接池中取出的连接,都会将调用 connection.setAutoCommit(false)方法,这样我们
    就必须使用 sqlSession.commit()方法,相当于使用了 JDBC 中的 connection.commit()方法实现事务提
    交。
    明白这一点后,我们现在一起尝试不进行手动提交,一样实现 CUD 操作。注释手动提交事物

    在这里插入图片描述

    我们发现,此时事务就设置为自动提交了,同样可以实现CUD操作时记录的保存。虽然这也是一种方式,但就
    编程而言,设置为自动提交方式为 false 再根据情况决定是否进行提交,这种方式更常用。因为我们可以根据业务
    情况来决定提交是否进行提交。

    Mybatis映射文件深入

    动态sql语句概述

    Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了。

    动态sql之if

    我们根据实体类的不同取值,使用不同的 SQL 语句来进行查询。比如在 id 如果不为空时可以根据 id 查询,
    如果 username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。

    ① 创建工程:

    mabatis-dynamic-sql

    ②添加pom文件

    
    <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.0modelVersion>
    
        <groupId>org.examplegroupId>
        <artifactId>day44mybatis-dynamic-sqlartifactId>
        <version>1.0-SNAPSHOTversion>
    
        <dependencies>
            <dependency>
                <groupId>org.mybatisgroupId>
                <artifactId>mybatisartifactId>
                <version>3.5.6version>
            dependency>
    
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>8.0.16version>
            dependency>
    
            <dependency>
                <groupId>junitgroupId>
                <artifactId>junitartifactId>
                <version>4.12version>
                <scope>testscope>
            dependency>
    
            <dependency>
                <groupId>log4jgroupId>
                <artifactId>log4jartifactId>
                <version>1.2.17version>
            dependency>
        dependencies>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    ③导入基本配置:

    拷贝这五个文件到项目

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oeXfnoTW-1667721726513)(C:/Users/ZZC/AppData/Roaming/Typora/typora-user-images/image-20221106153354214.png)]

    ④在UserDao接口中 添加查询条件的方法

    package com.atguigu.dao;
    
    import com.atguigu.pojo.User;
    
    import java.util.List;
    
    public interface UserDao {
    
        /**
         * 根据条件动态设置sql
         */
        List<User> findByCondition(User user);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ⑤UserDao.xml

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.atguigu.dao.UserDao">
        <select id="findByCondition" parameterType="user" resultType="user">
            select * from user where 1=1
            <if test="id!=null">
                and id=#{id}
            if>
            <if test="username!=null">
                and username=#{username}
            if>
            <if test="password!=null">
                and password=#{password}
            if>
        select>
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    测试文件代码

    package com.atguigu;
    
    import com.atguigu.dao.UserDao;
    import com.atguigu.pojo.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 MybatisTest {
    
    
        private UserDao userDao;
        private SqlSession sqlSession;
        private InputStream is;
    
    
        @After
        public void after() throws Exception{
            // 提交事务
            sqlSession.commit();
            // 释放资源
            sqlSession.close();
            is.close();
        }
    
    
    
        @Before
        public void before() throws IOException {
            // 1.需要找到核心配置文件
            is = Resources.getResourceAsStream("sqlMapConfig.xml");
            // 2.构建会话工厂
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            // 3.读取核心配置文件里面的io流
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
            // 4.获取会话对象
            sqlSession = sqlSessionFactory.openSession();
            // 5.通过会话工厂 获取userdao对象
            userDao = sqlSession.getMapper(UserDao.class);
    
        }
    
        @Test
        public void testFindByCondition(){
            User user = new User();
            user.setId(43);
            user.setUsername("王安石");
            user.setPassword("123123");
            List<User> userList = userDao.findByCondition(user);
            for (User user1 : userList) {
                System.out.println(user1);
            }
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    where1=1的用处

    where 1 = 1,永远为真

    where 1 = 1 用于动态SQL,规范语句

    where 1=1; 这个条件始终为True,在不定数量查询条件情况下,1=1可以很方便的规范语句。

  • 相关阅读:
    Python3.11教程5:类与对象
    Linux介绍
    几个常用的函数
    在hadoop上搭建hive环境
    山西电力市场日前价格预测【2023-10-17】
    好心情精神心理科医生:如何与青春期的孩子沟通?
    2023南京审计大学计算机考研信息汇总
    C++ 函数返回多个值的方法总结
    OpenCV之形态学操作
    Spring Boot框架中的@Conditional系列注解
  • 原文地址:https://blog.csdn.net/Libra_97/article/details/127716942