Mybatis搞三下(参数的深入理解&模糊查询)

Mybatis搞三下(参数的深入理解&模糊查询)

上篇我们详细了解了Mapper文件里的namespace、各种CRUD语句的解析和执行过程,本篇详解这些和java程序连接的mapper文件里的参数调用(偏实战)。

CRUD语句

select

选择,查询语句;

  • id : 就是对应的namespace中的方法名;
  • resultType:Sql语句执行的返回值!
  • parameterType : 参数类型!
  1. 编写接口

    //根据ID查询用户
    User getUserById(int id);
    
  2. 编写对应的mapper中的sql语句

    <select id="getUserById" parameterType="int" resultType="com.feng.pojo.User">
            select * from mybatis.user where id = #{
          
          id}
    </select>
    
  3. 测试

        @Test
        public void getUserById() {
          
          
            SqlSession sqlSession = MybatisUtils.getSqlSession();
    
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
            User user = mapper.getUserById(1);
            System.out.println(user);
    
            sqlSession.close();
        }
    
    

Insert

    <!--对象中的属性,可以直接取出来-->
    <insert id="addUser" parameterType="com.feng.pojo.User">
        insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd});
    </insert>

update

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

Delete

    <delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id = #{id};
    </delete>

注意点:

  • 增删改需要提交事务!

parameterType

传入参数类型

<select id="getUserById" parameterType="int" resultType="com.feng.pojo.User">
        select * from mybatis.user where id = #{id}
</select>
  • 写在mapper文件中的一 个属性。表示dao接口中方法的参数数据类型。
  • 这个属性是可选的(mybatis里反射能拿到接口参数类型)

(基本数据类型:int,string,long,Date; 复杂数据类型:类和Map)

如何获取参数中的值?

基本数据类型:#{value}或${value} 获取参数中的值

复杂数据类型:#{属性名}或KaTeX parse error: Expected 'EOF', got '#' at position 14: {属性名} ,map中则是#̲{key}或{key}

注:#{}与${}的区别:

#{value}:输入参数的占位符,相当于jdbc的? 防注入 自动添加了‘ ’ 引号!
例如:select * from user where username = #{name} //输入的参数xiaoming,就会自动加上引号
变成:select * from user where username = ‘xiaoming’
注意:value可以写任意变量,没有统一规定

v a l u e : 不 防 注 入 , 就 是 字 符 串 拼 接 例 如 : s e l e c t ∗ f r o m u s e r w h e r e u s e r n a m e l i k e ′ {value}: 不防注入,就是字符串拼接 例如:select * from user where username like '% value:selectfromuserwhereusernamelike{value}%’ //默认不加引号
注意:只能写value!!!

select * FROM user WHERE username like “%”‘s’"%"//是正确的,符合语法,引号的形式只能是这样,不能变!

#{}更安全,优先考虑,${}还用于properties文件中的变量占位符

#{} ${}
意义 占位符 拼接字符串(properties中占位符)
参数类型 简单类型、pojo属性值 简单类型,pojo属性值(如果传输单个简单类型或者字符串类型值,${}括号中只能写value)
解析 解析时参数带引号,解析为JDBC预编译语句的参数占位符 纯粹的String替换,解析不带引号,动态SQL解析会进行变量替换
安全 防止SQL注入 存在SQL注入风险
用处 一般用于传递用户输入值(不确定) 一般用于传递确定值(开发人员确定的值)

resultType

输出结果集就两种,基本数据类型或者pojo类型

注意这里不管查询返回的是list还是map或者array,亦或者是单个User(pojo)对象,resultType都要写成user(pojo)

返回java对象

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

返回java类型

<delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id = #{id};
    </delete>

resultMap(常用)

resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

这里的resultMap如果使用,需要在UserMapper.xml配置

 <resultMap id="UserMap" type="User">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
    </resultMap>


<select id="getUserByRowBounds" resultMap="UserMap">
         select * from  mybatis.user
    </select>

接口

	//分页1
    List<User> getUserByLimit(Map<String,Integer> map);

    //分页2
    List<User> getUserByRowBounds();

测试

@Test
    public void getUserByLimit(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("startIndex",1);
        map.put("pageSize",2);

        List<User> userList =  mapper.getUserByLimit(map);

        for (User user : userList) {
    
    
            System.out.println(user);
        }

        sqlSession.close();
    }


    @Test
    public void getUserByRowBounds(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //RowBounds实现
        RowBounds rowBounds = new RowBounds(1, 2);

        //通过Java代码层面实现分页
        List<User> userList = sqlSession.selectList("com.feng.dao.UserMapper.getUserByRowBounds",null,rowBounds);

        for (User user : userList) {
    
    
            System.out.println(user);
        }
        sqlSession.close();
    }
  • resultMap 元素是 MyBatis 中最重要最强大的元素
  • ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。
  • ResultMap 最优秀的地方在于,虽然你已经对它相当了解了,但是根本就不需要显式地用到他们。

其实不难发现,这个resultMap就是为了解决属性名和字段名不一致的问题

模糊查询,like

mapper

<select id="getUserLike" resultType="com.feng.pojo.User">
        select * from mybatis.user where name like "%"#{value}"%"
    </select>

test

@Test
    public void getUserLike(){
    
    
        //模糊查询
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> userList = mapper.getUserLike("%李%");

        for (User user : userList) {
    
    
            System.out.println(user);
        }

        sqlSession.close();
    }

image-20200923111437989

可以看到这里like后面已经拼接完成了

(这里使用了log4j日志打印信息)

log4j配置

在pom文件中添加log4j依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
</dependencies>

在resources中添加log4j.properties

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/feng.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

在mybatis-config.xml中添加

image-20200923111825114

<settings>
        <!--        <setting name="logImpl" value="STDOUT_LOGGING"/>-->
        <setting name="logImpl" value="LOG4J"/>

    </settings>

运行即可

具体代码

mybatis-config.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?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="*****"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="com/feng/dao/UserMapper.xml"/>
    </mappers>

</configuration>

User.java

package com.feng.pojo;
//实体类
public class User {
    
    
    private int id;
    private String name;
    private String pwd;

    public User() {
    
    
    }

    public User(int id, String name, String pwd) {
    
    
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public int getId() {
    
    
        return id;
    }

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

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getPwd() {
    
    
        return pwd;
    }

    public void setPwd(String pwd) {
    
    
        this.pwd = pwd;
    }

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

pom.xml部分

<!--在build中配置resources,来防止我们资源导出失败的问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

UserMapper.java

package com.feng.dao;

import com.feng.pojo.User;

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

public interface UserMapper {
    
    

    List<User> getUserLike(String value);


    //查询全部用户
    List<User> getUserList();

    //根据ID查询用户
    User getUserById(int id);

    User getUserById2(Map<String,Object> map);

    //insert一个用户
    int addUser(User user);

    int addUser2(Map<String,Object> map);

    //update一个用户
    int updateUser(User user);

    //Delete一个用户
    int deleteUser(int id);

}

UserMapper.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">

<mapper namespace="com.feng.dao.UserMapper">
    
    
    <select id="getUserLike" resultType="com.feng.pojo.User">
        select * from mybatis.user where name like "%"#{value}"%"
    </select>

    <select id="getUserList" resultType="com.feng.pojo.User">
        select * from mybatis.user
    </select>


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

    <select id="getUserById2" parameterType="map" resultType="com.feng.pojo.User">
        select * from mybatis.user where id = #{helloId} and name=#{name}
    </select>


    <insert id="addUser" parameterType="com.feng.pojo.User" >
        insert into mybatis.user (id,name,pwd) values (#{id},#{name},#{pwd});
    </insert>

    <insert id="addUser2" parameterType="map" >
        insert into mybatis.user (id,pwd) values (#{userid},#{password});
    </insert>



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

    <delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id = #{id};
    </delete>

</mapper>

MybatisUtil.java

package com.feng.utils;

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;

//sqlSessionFactory --> sqlSession
public class MybatisUtils {
    
    

    private static SqlSessionFactory sqlSessionFactory;

    static {
    
    
        try {
    
    
            //使用Mybatis第一步:获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }

    }

    //既然有了 SqlSessionFactory,顾名思义,我们就可以从中获得 SqlSession 的实例了。
    // SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。
    public static SqlSession getSqlSession() {
    
    
        return sqlSessionFactory.openSession();
    }

}

UserMapperTest.java

package com.feng.dao;

import com.feng.pojo.User;
import com.feng.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

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

public class UserMapperTest {
    
    

    @Test
    public void getUserLike(){
    
    
        //模糊查询
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> userList = mapper.getUserLike("%李%");

        for (User user : userList) {
    
    
            System.out.println(user);
        }

        sqlSession.close();
    }


    @Test
    public void test() {
    
    
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        try {
    
    

            //方式一:getMapper
            UserMapper UserMapper = sqlSession.getMapper(UserMapper.class);
            List<User> userList = UserMapper.getUserList();

            //方式二:
            //List<User> userList = sqlSession.selectList("com.feng.dao.UserDao.getUserList");

            for (User user : userList) {
    
    
                System.out.println(user);
            }

        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            //关闭SqlSession
            sqlSession.close();
        }
    }

    //根据id查询用户
    @Test
    public void getUserById(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserById(1);
        System.out.println(user);
        sqlSession.close();
    }


    @Test
    public void getUserById2(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        Map<String, Object> map = new HashMap<String, Object>();

        map.put("helloId", 1);
        mapper.getUserById2(map);
        for (String key : map.keySet()) {
    
    
            System.out.println("key= "+ key + " and value= " + map.get(key));
        }

        sqlSession.close();
    }



    //增删改查需要提交事务
    @Test
    public void addUser(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        int res = mapper.addUser(new User(6, "小仙", "222255"));
        if (res > 0) {
    
    
            System.out.println("插入成功");
        }
        //提交事务
        sqlSession.commit();

        sqlSession.close();
    }



    @Test
    public void addUser2(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("userid",7);
        map.put("password","546552");


        mapper.addUser2(map);

        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void updateUser(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        int res = mapper.updateUser(new User(6, "小小仙", "222222"));
        if (res > 0) {
    
    
            System.out.println("修改成功");
        }
        //提交事务
        sqlSession.commit();

        sqlSession.close();
    }

    @Test
    public void deleteUser(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        int res = mapper.deleteUser(6);
        if (res > 0) {
    
    
            System.out.println("删除成功");
        }
        //提交事务
        sqlSession.commit();

        sqlSession.close();
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43876186/article/details/108749302