MyBatis(一)

Mybatis(1)

使用原生JDBC的问题

  • 数据库连接使用时创建,不使用时关闭,对数据库进行频繁的开启和关闭,造成了数据库资源的浪费,影响数据库性能

使用数据库连接池进行管理数据库连接

  • 将SQL语句硬编码到java代码内,如果SQL语句修改,需要重新编译,不利于系统维护

将SQL语句配置到XML文件内

  • 向preparedStatemment中设置参数,对于占位符和参数硬编码在java代码内,不利于维护

配置在XML文件内

  • resultSet结果集数硬编码于Java代码内

将结果自动映射成java对象

Mybatis 框架(持久层的框架)

入门程序

  • 根据主键查询信息
  • 根据用户名称模糊查询
  • 增、删、查、改

根据用户ID查询信息

创建Mybatis配置文件
  • SqlMapConfig.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">
<!--            使用了JDBC的事务管理,事务控制有Mybatis-->
            <transactionManager type="JDBC"/>
<!--            数据库链接池,由Mybatis管理-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>
创建映射文件(Mapper)
  • 命名方式:XXXmapper.xml
  • 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">

<!--命名空间,作用是对Sql进行父类管理(SQL的隔离)-->
<mapper namespace="com.test.user">
<!--    在映射文件内配置多个SQL语句-->

<!--    查询
        id:标识映射文件内的SQL,称为statement的id(将来SQL语句会封装到mapperSatement对象内)
        #{} 表示一个占位符,#{id} 内的id表示接受的参数名称为id
        parameterType 指定输入参数的类型
        resultType 指定SQL返回的结果所映射的java对象的类型
-->
    <select id="findUserById"
            parameterType="int"
            resultType="com.pojo.User">
        select * from user where id = #{id}
    </select>
</mapper>
创建POJO类(普通javaBean)
package com.pojo;

public class User {

//    属性名要和java字段对应
    private Integer id;
    private String username;
    private String password;
    private String name;
    private String sex;
    private String addr;

    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 getPassword() {
        return password;
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }
}

在SqlMapConfig.xml 内记载Mapper文件
<mappers>
    <mapper resource="Mapper 文件路径"/>
</mappers>
编写代码
package com.mybatisStudy1;

import com.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.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;


/**
 * Hello world!
 *
 */
public class App {

//    根据id查询用户信息
    @Test
    public void test() throws IOException {

//        创建会话工厂
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);

//        通过工厂获取SqlSession
        SqlSession ss = ssf.openSession();

//        操作数据库
//        selectOne(String statement, Object parameter);
//        statement:映射文件内statement的id, 值为mapper的命名空间(namespace)和SQL id
//        parameter:输入的参数(类型要和parameterType所写的类型匹配)
//        返回resultType内所写类型的对象
        User user = ss.selectOne("com.test.user.findUserById",
                1);

        System.out.println(user.toString());

//        释放资源
        ss.close();
        is.close();

    }

}

根据用户名称模糊查询信息

创建mapper文件
<?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">

<!--命名空间,作用是对Sql进行父类管理(SQL的隔离)-->
<mapper namespace="com.test.user">
<!--    在映射文件内配置多个SQL语句-->

<!--    查询
        id:标识映射文件内的SQL,称为statement的id(将来SQL语句会封装到mapperSatement对象内)
        #{} 表示一个占位符,#{id} 内的id表示接受的参数名称为id
        parameterType 指定输入参数的类型
        resultType 指定SQL返回的结果所映射的java对象的类型
-->
    <select id="findUserById"
            parameterType="int"
            resultType="com.pojo.User">
        select * from user where id = #{id}
    </select>


<!--    resultType:指定的就是单条记录所映射的java类型-->
<!--    ${}:表示拼接sql串,将接受到的内容不加任何修饰拼接到sql中
        可能会引起SQL注入
        如果传入的是简单类型参数,则${}内只能写成value - ${value}
-->
    <select id="findUserByName"
            parameterType="string"
            resultType="com.pojo.User">
        select * from user where name like '%${value}%'
    </select>

</mapper>
编写程序
@Test
    public void testFindUserByName() throws IOException {
//        创建SQL 会话工厂
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);

//        创建会话
        SqlSession ss = ssf.openSession();

//        操作数据库 --- 使用${} 存在sql注入的风险
        List<User> users = ss.selectList("findUserByName", "铁");

        for (User u:users
             ) {
            System.out.println("【RESULT】:" + u.toString());
        }


//        释放资源
        ss.close();
        is.close();

    }

添加用户

mapper 文件
  • 配置添加用户的Statement
    OGNL
<!--    添加用户
        parameterType:指定输入的类型是pojo(包括用户信息)
        #{}:内写指定的pojo的属性名,接受到pojo的属性值
        (mybatis是使用OGNL获取对象的属性值)
-->
    <insert id="addUser"
            parameterType="com.pojo.User">
        insert into user (id, username, password, name, sex, addr)
        values (#{id},#{username},#{password},#{name},#{sex},#{addr});
    </insert>
编写代码
@Test
    public void testAddUser() throws IOException {
//        创建SqlSessionFactory
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);

//        创建SqlSession
        SqlSession ss = ssf.openSession();

//        操作数据库
        System.out.println(ss.insert("addUser", new User(null, "12131", "12131", "上官翠花", "女", "公主坟")));
        ss.commit();


//        释放资源
        ss.close();
        is.close();

    }
  • 主键的返回
  • 自增主键的返回(Mysql)
  • 在执行insert提交之前生成一个自增主键
    SELECT LAST_INSERT_ID() 在Insert之后调用
    TIM截图20190511172047.png
<insert id="addUser"
            parameterType="com.pojo.User">
            /*
                将插入的数据的主键值返回到User对象内
                SELECT LAST_INSERT_ID():得到 insert 进去记录的主键值(只适用于自增)
                _**selectKey:查询数据库内某一个属性的值,并且将查询的值赋值给keyProperty内声明的属性
                keyProperty:将查询结果设置到parameterType指定对象的哪个属性
                order:相对于当前SQL语句的执行顺序(执行前BEFORE/执行后AFTER)**_
            */
            <selectKey keyProperty="id" order="AFTER" resultType="int">
                SELECT LAST_INSERT_ID()
            </selectKey>

            /*执行后结果 User{id=null, username='12131', password='12131', name='欧阳铁柱', sex='女', addr='公主坟'}*/
            <!--<selectKey order="AFTER" resultType="com.pojo.User" keyProperty="name" >
                select * from user where username = '12138'
            </selectKey>
-->
        insert into user (id, username, password, name, sex, addr)
        values (#{id},#{username},#{password},#{name},#{sex},#{addr});
    </insert>
  • 非自增主键的返回(Mysql)
  • 使用SELECT UUID()获取(条件:表中id字段类型为varchar,长度为35)
  • 执行过程:
  1. 先通过UUID()查询到主键,再将主键设置到sql语句中(设置到#{id})
  2. 执行UUID()在insert语句之前
  • usertempuuid_mapper.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.pojo.User_temp_uuid_">

    <insert id="addUser"
            parameterType="com.pojo.User_temp_uuid_">
            /*
                resultType:返回类型,返回值会赋值给INSERT语句内的#{id}
            */
            <selectKey order="BEFORE" keyProperty="id" resultType="string">
                SELECT UUID()
            </selectKey>

        INSERT INTO user_temp_uuid_(id, name)
        value (#{id}, #{name})
    </insert>

</mapper>
 @Test
    public void testAddUserUUID() throws IOException {
//        创建SqlSessionFactory
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);

//        创建SqlSession
        SqlSession ss = ssf.openSession();

//        创建实体类对象
        User_temp_uuid_ utu = new User_temp_uuid_("1", "欧阳铁柱");

//        操作数据库
        ss.insert("com.pojo.User_temp_uuid_.addUser", utu);

        System.out.println(utu.toString());

//        提交事务
        ss.commit();

//        释放资源
        ss.close();
        is.close();

    }
  • 执行结果
  • TIM截图20190511180632.png
  • TIM截图20190511180702.png

删除用户/更新用户

mapper配置
<!--    删除用户-->
    <delete id="deleteUser" parameterType="int">
        DELETE FROM USER where id = #{id}
    </delete>

<!--    更新用户
        #{id}:从输入的user对象内获取id属性的值 -->
    <update id="updateUser" parameterType="com.pojo.User">
        update user set username = #{username}, password = #{password}, name = #{name}, sex = #{sex}, addr = #${addr}
        where id = #{id}
    </update>
编写代码
//    删除用户
    @Test
    public void deleteUser() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

        SqlSession sqlSession = sqlSessionFactory.openSession();

        sqlSession.delete("deleteUser", 15);
        sqlSession.commit();
        sqlSession.close();
        is.close();
    }

//    更新用户
    @Test
    public void updateUser() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

        SqlSession sqlSession = sqlSessionFactory.openSession();

        sqlSession.update("updateUser", new User(3, "11221", "11221", "小崔", "男", "蓬莱路"));
        sqlSession.commit();
        sqlSession.close();
        is.close();
    }

总结

parameterType
  • 在映射文件内通过parameterType指定输入参数的类型
resultType
  • 在映射文件内通过resultType指定输出结果的类型
#{}和${}
  • #{}:表示占位符
  • ${}:表示拼接符 — 存在SQL注入的风险,不建议使用
selectOne() 和 selectList()
  • selectOne():查询一条记录进行映射
  • selectList():查询出一个列表(多条记录)来进行映射
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值