Mybatis

82 阅读3分钟

mybatis的基本使用

Config配置文件(用于告诉java代码去连接哪一个数据库进行操作)

<?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>
​
    <settings>
        <!--在控制台输出发送的sql日志-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
​
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
​
            <!--目前只关注这部分内容,它的作用就是声明要连接的数据信息-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>  //自己的数据库
                <property name="username" value="root"/> //用户名
                <property name="password" value="1234"/>  //密码
            </dataSource>
        </environment>
    </environments>
​
    <mappers>
        <!--声明含有sql的接口所在包-->
        <package name="com.itheima.mapper"/>
    </mappers>
</configuration>

Mapper层

// 1. 这是一个接口
// 2. 接口名:操作的表名+Mapper
public interface UserMapper {
​
    // #{}里面的内容
    // 1. 如果参数是对象类型,#{}写的是对象的属性名
    @Insert("insert into user values (null,#{name},#{age},#{gender},#{phone})")
    void save(User user);
​
    // @Options
    // useGeneratedKeys 拿到自增主键
    // keyProperty 指定哪个字段是主键
    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("insert into user values (null,#{name},#{age},#{gender},#{phone})")
    void save2(User user);
​
    @Update("update user set name = #{name},age=#{age},gender=#{gender},phone = #{phone} where id=#{id} ")
    void update(User user);
​
    @Delete("delete from user where id = #{id}")
    void delete(Integer id);
​
​
    @Delete("delete from user where name = #{name}")
    void deleteByName1(String name);
​
    @Delete("delete from user where name = ${name}")
    void deleteByName2(String name);
}
​

测试类

public class UserMapperTest {
    @Test
    public void testSave() throws IOException {
        // 1. 创建对象
        User user = new User();
        user.setName("张三");
        user.setAge(18);
        user.setGender(1);
        user.setPhone("15515847153");
​
        // 工具类获取sqlSession
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
​
        // 获取UserMapper对象,调用方法
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        userMapper.save(user);
​
        // 工具类关闭sqlSession
        MyBatisUtil.close(sqlSession);
    }
​
​
    @Test
    public void testDeleteByName1() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
​
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        userMapper.deleteByName1("张三");
        // delete from user where name = '张三'
​
        MyBatisUtil.close(sqlSession);
    }
​
    @Test
    public void testDeleteByName2() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
​
        // 用户名叫作:'李四' or id>1
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        userMapper.deleteByName2(" '李四' or id>1"); // ${}会产生sql注入问题
        // delete from user where name = '李四' or id>1
​
        MyBatisUtil.close(sqlSession);
    }
}
​

驼峰映射

当表中字段和类中属性的关系是_和驼峰写法时,可以开启mybatis的自动驼峰映射

<setting name="mapUnderscoreToCamelCase" value="true"/>

image.png

起别名

当表中字段和类中属性完全没有关系时,可以使用别名来修改sql返回集中字段的名称

给不对应的字段起别名

    //查询
    @Select("select id, username, password, name, gender, image, job, entrydate as ed, dept_id, create_time, update_time from emp")
    List<Emp> findAll2();

测试

 //查询所有
    @Test
    public void testFindAll2() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
​
        List<Emp> empList = empMapper.findAll2();
        empList.forEach(e -> System.out.println(e));//lambda方式打印
​
        MybatisUtil.close(sqlSession);
    }

自定义映射

当表中字段和类中属性完全没有关系时,可以通过@Results进行手动结果映射

自定义结果映射

    //查询
    @Results({//@Results: 自定义结果映射
            @Result(column = "entrydate", property = "ed"),//@Result一条映射规则 (column = "数据表中字段名", property = "实体类属性名")
            @Result(column = "dept_id", property = "deptId")
    })
    @Select("select * from emp")
    List<Emp> findAll3();

测试

    //查询所有
    @Test
    public void testFindAll3() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
​
        List<Emp> empList = empMapper.findAll3();
        empList.forEach(e -> System.out.println(e));//lambda方式打印
​
        MybatisUtil.close(sqlSession);
    }

条件查询

当查询方法出现多个查询条件时,需要使用@Param注解设置对应关系

添加条件查询的方法

    //#{} 里面的内容
    //1. 如果参数是一个对象类型, #{}写的是对象中的属性名
    //2. 如果参数是一个简单类型(8基本 + 8包装 +String) ,#{}可以随便写, 但是推荐写方法形参名
    //3. 如果参数是多个简单类型的参数, #{}中写的是@Param注解中的值
    //条件查询
    @Select("select * from emp where name = #{name} and gender = #{gender} and entrydate between #{begin} and #{end}")
    List<Emp> findList(@Param("name") String name, @Param("gender") Short gender, @Param("begin") LocalDate begin, @Param("end") LocalDate end);

测试

    //条件查询
    @Test
    public void testFindList() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
​
        List<Emp> empList = empMapper.findList("张三丰", (short) 1, LocalDate.of(2002, 01, 01), LocalDate.of(2023, 12, 31));
        empList.forEach(e -> System.out.println(e));//lambda方式打印
​
        MybatisUtil.close(sqlSession);
    }

模糊查询

当查询sql中出现模糊查询语法时,需要使用concat函数连接条件,比如根据用户名进行模糊查询 `where name like '%张%'----------------->where name like concat('%',#{username},'%')

** 添加条件查询的方法**

    //模糊查询
    @Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and entrydate between #{begin} and #{end}")
    List<Emp> findListLike(@Param("name") String name, @Param("gender") Short gender, @Param("begin") LocalDate begin, @Param("end") LocalDate end);

** 测试 **

    //模糊查询
    @Test
    public void testFindListLike() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
​
        List<Emp> empList = empMapper.findListLike("张", (short) 1, LocalDate.of(2002, 01, 01), LocalDate.of(2023, 12, 31));
        empList.forEach(e -> System.out.println(e));//lambda方式打印
​
        MybatisUtil.close(sqlSession);
    }

util工具类(进行处理的类 导入即可)

public class MybatisUtil {
private static SqlSessionFactory sqlSessionFactory = null;
​
//保证SqlSessionFactory仅仅创建一次
static {
    try {
        //读取配置文件
        InputStream stream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
​
//获取sqlSession
public static SqlSession getSqlSession() {
    return sqlSessionFactory.openSession();
}
​
//提交事务 关闭sqlSession
public static void close(SqlSession sqlSession) {
    if (sqlSession != null) {
        //提交事务
        sqlSession.commit();
        //释放资源
        sqlSession.close();
    }
}
}

批量添加数据


<insert id="insertEmp">
        ​
        insert into emp(id,username,pasword,name,gender,create_time,update_time)
        ​
        values
        ​
<foreach collection="empList"item="emp"separator=",">
        ​
        (null,#{emp.username},#{emp.password},#{emp.name},#{emp.gender},now(),now())
        ​
</foreach>
        ​
</insert>
        ​
        接口中
        ​
        void insertEmp(@Param("empList") List<emp> empList);
        ​
        测试类
        ​
public void insertEmp(){
        ​
        SqlSession sqlSession=MybatisUtil.getSqlSession();
        ​
        EmpMapper mapper=sqlSession.getMapper(EmpMapper.class);
        ​
        ArrayList<Emp> empList=new ArrayList<>(;
        ​
        for(int i=0;i<1000;i++){Emp.emp=new Emp();
        ​
        emp.setUsernmae("乐迪来喽"+i);
        ​
        emp.setPassword("1234");
        ​
        emp.setName("李四"+i);
        ​
        empList.add(emp)
        ​
        }
        ​
        mapper.inserEmp(empList);
        ​
        MybatisUtil.close(sqlSession);
        ​
        }

sql中#和$符的区别

  1. #表示占位符,防止SQL注入问题,同类型SQL只能编译一次 (在{}中写的数据默认添加单引号) 2.$表示字符串的拼接,存在SQL注入问题,每次SQL都重新编译 (在{}中写的数据写啥就是啥)