MyBatis 增删改查CRUD

MyBatis 增删改查 CRUD

1. 查询

根据上次所说实体类工具类不需要变了!我们只需要变的是UserMapper.javaUserMapper.xmlUserMapperTest.java(测试类)

步骤

  1. 编写接口
  2. 编写对应的mapper中的sql语句
  3. 测试

注意点:
增删改查,需要提交事务!
UserMapper.xml文件可以放在resources文件夹中!
sql语句 insert 、update、delete 返回值默认情况下是int类型 :matched(匹配的)行数
如果要返回:changed(受影响的)行数只需在mysql数据连接url参数加useAffectedRows=true
例如:jdbc.url=jdbc:mysql://localhost:3306/ssm?useAffectedRows=true

  1. 编写接口
    UserMapper.java
   //根据ID查询用户
   User getUserById(int id);
  1. 编写对应的mapper中的sql语句
    UserMapper.xml

  2. namespace中的包名要和Dao/mapper 接口的包名一致!
    <mapper namespace="com.guo.dao.UserMapper"> <!--绑定-->

  3. select 选择,查询语句

    • id 就是对应的namespace中的方法名
    • resultType: sql语句执行的返回值
    • parameterType:参数类型
  <select id="getUserById" parameterType="int" resultType="com.guo.pojo.User">
        select * from mybatis.user where id = #{id}
  </select>
  1. 测试
    UserMapperTest.java(测试类)
    @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(); // 不变
    }

mybatis

2. 增加 insert

UserMapper.java

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

UserMapper.xml

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

UserMapperTest.java(测试类)
增删改需要提交事物

    //增删改需要提交事物
    @Test
    public void addUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();//不变
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);//不变
        int res = mapper.addUser(new User(4,"赵六","121212"));
        if(res > 0){
            System.out.println("插入成功");
        }
        //提交事物
        sqlSession.commit();
        sqlSession.close(); //不变
    }

3. 修改 update

UserMapper.java

  //update修改用户
   int updateUser(User user);

UserMapper.xml

    <!--更新用户信息-->
    <update id="updateUser" parameterType="com.guo.pojo.User">
        update mybatis.user set name =#{name},pwd=#{pwd} where id = #{id};
    </update>

UserMapperTest.java(测试类)
增删改需要提交事物

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

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);//不变
        mapper.updateUser(new User(4,"更改了","123123"));

        //提交事物
        sqlSession.commit();
        sqlSession.close();//不变
    }

4. 删除 delete

UserMapper.java

   //delete 删除一个用户
   int deleteUser(int id);

UserMapper.xml

    <!--删除一个用户-->
    <delete id="deleteUser" parameterType="int">
         delete from mybatis.user where id = #{id};
    </delete>

UserMapperTest.java(测试类)
增删改需要提交事物

    @Test
    public void deleteUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();//不变
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);//不变
        mapper.deleteUser(4);

        //必须提交事物
        sqlSession.commit();
        sqlSession.close();//不变
    }

5. 分析错误

  1. 正确写法:
    <mapper namespace="com.guo.dao.UserMapper"> <!--绑定-->
    错误写法:
    <mapper namespace="com/guo/dao/UserMapper"> <!--绑定-->

  2. 标签不能匹配错:例如: insert 对应插入的方法

  3. mybatis-config.xml中:
    正确写法: resource是资源路径,绑定mapper需要使用路径,使用 /

   <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册!-->
    <mappers>
        <mapper resource="com/guo/dao/UserMapper.xml"/>
    </mappers>

错误写法:

   <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册!-->
    <mappers>
        <mapper resource="com.guo.dao.UserMapper.xml"/>
    </mappers>
  1. 程序数据库配置文件,必须符合规范!

  2. NullPointerException空指针异常 没有注册到资源!
    需要注意MybatisUtils.java中这两行的关系,是否能注册到资源!

   private static SqlSessionFactory sqlSessionFactory;
   sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //创建流
  1. 输出的target文件夹中的xml文件中存在中文乱码问题!

  2. maven资源没有导出问题!
    pom.xml中配置:

    <!--maven由于它的约定大于配置,我们以后可能遇到我们自己写的配置文件,无法被导出或者生效的问题,解决方法:-->
    <!--在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>

mybatis

6. Map

遇到问题:当前类字段是三个,可以写成(id,name,pwd) values (#{id},#{name},#{pwd})形式。
UserMapper.xml

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

如果实体类或者数据库表中字段过多,不太建议都写成以上这样,建议使用Map

UserMapper.java

//万能的Map 不需要传
   int addUser2(Map<String,Object> map);

UserMapper.xml

    <!--对象中的属性,map对象不需要一一对应,传递map的key-->
    <insert id="addUser2" parameterType="map">
        insert into mybatis.user(id,name,pwd) values (#{userid},#{userName },#{passWord});
    </insert>

UserMapperTest.java(测试类)

    @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",5);//随意制造参数
        map.put("userName","孙七");//
        map.put("passWord","12345");
        mapper.addUser2(map);
        //必须提交事物
        sqlSession.commit();
        sqlSession.close();//不变
    }

6.1 修改查询 (根据id查询用户)

UserMapper.java

//根据ID查询用户
//User getUserById(int id); 原来的
User getUserById2(Map<String,Object> map);//改成

UserMapper.xml

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

UserMapperTest.java(测试类)

      @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);//需要与`UserMapper.xml`对应上
        map.put("name","张三");
        User user = mapper.getUserById2(map);
        System.out.println(user);
        sqlSession.close();//不变
    }

总结:

  • Map传递参数,直接在sql中取出key即可!parameterType="map"
  • 对象传递参数,直接在sql中取对象的属性即可!parameterType="map"
  • 只有一个基本参数的情况下,可以直接在sql中取到!
    举个例子:

UserMapper.javagetUserById方法只传了一个值

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

UserMapper.xmlparameterType="int"可以不写了,多个参数用Map,或者注解

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

6.2 模糊查询

    1. Java代码执的时候,传递通配符% %
      List<User> userList = mapper.getUserLike("%李%");
    1. 在sql拼接中使用通配符!(容易sql注入)
      select * from mybatis.user where name like "%" #{value} "%"

UserMapper.java

//模糊查询
   List<User> getUserLike(String value);

UserMapper.xmlparameterType="int"可以不写了,多个参数用Map,或者注解

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

不要写成:

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

能运行,但是容易造成sql语句拼接,产生sql注入

      select * from mybatis.user where id = ?
      select * from mybatis.user where id = 1 or 1 = 1

UserMapperTest.java(测试类)

    @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();//不变
    }

7. 配置解析

MyBatis配置文档:
mybatis
Mybatis的配置文件包含了深深影响myBatis行为的设置和属性信息。

7.1 核心配置文件

mybatis-config.xml

  • configuration(配置)
    • properties(属性)
    • settings(设置)
    • typeAliases(类型别名)
    • typeHandlers(类型处理器)
    • objectFactory(对象工厂)
    • plugins(插件)
    • environments(环境配置)
      • environment(环境变量)
      • transactionManager(事务管理器)
      • dataSource(数据源)
    • databaseIdProvider(数据库厂商标识)
    • mappers(映射器)

7.2 环境配置(environments)

学会使用配置多套运行环境,不过要记住:尽管可以配置多个环境,但每个SqlSessionFactory实例只能选择一种环境

<environments default="test"><!--这里的default对应environment的id-->
  <environment id="development">
    <transactionManager type="JDBC"> <!--Mybatis默认的事务管理器就是JDBC-->
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED"> <!--数据源是连接数据库:连接池:POOLED(用完可以回收)-->
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
 
   <environment id="test"> <!--使用的是test环境-->
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </transactionManager>
    <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>

7.3 属性properties

我们可以通过properties属性来实现引用配置文件

这些属性都是课外不配置且可以动态替换的,既可以在典型的java属性文件中配置,亦可以通过properties元素的子元素来传递。【db.properties】

<!--官方文档-->
<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</properties>

也可以编写一个配置文件db.properties

<!-- db.properties -->
driver = com.mysql.jdbc.Driver
url =jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
username = 
password = 

核心配置文件中(mybatis-config.xml)引入,在xml中,所有的标签都可以规定其顺序

mybatis
可以直接引入外部文件
可以在起哄增加一些属性配置
如果两个文件有同一个字段,优先使用外部配置文件

<?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>
    <!--引入外部配置文件--> <!--如果两个文件有同一个字段,优先使用外部配置文件-->
    <properties resource="db.properties">

    </properties>
    <!--环境 environments下可以配置多个environment环境  环境名称是id="" environments default=使用哪个个环境就写哪个环境的id-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>    <!--事物管理-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/> <!--驱动--><!--编码--> <!--&amp;就是and  serverTimezone时区-->
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册!-->
    <mappers>
        <mapper resource="com/guo/dao/UserMapper.xml"/>
    </mappers>
</configuration>

当然也可以这样配置:
db.properties

driver = com.mysql.jdbc.Driver
url =jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
<?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>
    <!--引入外部配置文件--> <!--如果两个文件有同一个字段,优先使用外部配置文件-->
    <properties resource="db.properties">
        <property name="username" value=""/>
        <property name="pwd" value=""/>
    </properties>
 
    <!--环境 environments下可以配置多个environment环境  环境名称是id="" environments default=使用哪个个环境就写哪个环境的id-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>    <!--事物管理-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/> <!--驱动--><!--编码--> <!--&amp;就是and  serverTimezone时区-->
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${pwd}"/>
            </dataSource>
        </environment>
    </environments>

    <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册!-->
    <mappers>
        <mapper resource="com/guo/dao/UserMapper.xml"/>
    </mappers>

</configuration>

7.4 类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,存在的意义仅在于用来减少类完全限定名的冗余。

第一种,在实体类比较少的时候使用的方式,这种方式可以自定义:

    <!--可以给实体类起别名-->
    <typeAliases>
        <typeAlias alias="User" type="com.guo.pojo.User"/>
    </typeAliases>

第二种,如果实体类比较多,建议也可以这样写:
扫描实体类的包,它的默认别名就为这类的类名首字母

    <!--可以给实体类起别名-->
    <typeAliases>
         <package name="com.guo.pojo"/>
    </typeAliases>
    <select id="getUserList" resultType="user" > <!--这里user最好,也可以用User-->
        <!--执行SQL-->
        select * from mybatis.user;
    </select>

使用第二种方式,还可以在实体类上增加注解直接起名字
User.java实体类

import org.apache.ibatis.type.Alias;
@Alias("user")
public class User {
    ...
}

7.5 设置(setting)

mybatis官方文档(设置):

原因;原来很多公司用Oracle数据库,在其数据库中,字段lastName 常常会转化为

mybatis
LASTNAME,因此程序员默认开始使用_来分隔字段。现在加下面的参数last_Name转化为lastName
mybatis
mybatis

配置

<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <setting name="defaultFetchSize" value="100"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

7.6 插件及其他

mybatis插件:
插件举例:

  • MyBatis Generator Core
  • MyBatis Plus
  • 通用mapper

mybatis

7.6.1 映射器(mappers)

MapperRegistry:注册绑定我们的Mapper文件
mybatis
方式一:【推荐使用】
mybatis-config.xml

    <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册!-->
    <mappers>
        <mapper resource="com/guo/dao/UserMapper.xml"/>
    </mappers>

方式二:使用class文件绑定注册
mybatis-config.xml

    <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册!-->
    <mappers>
        <mapper class="com.guo.dao.UserMapper"/>
    </mappers>

注意点:

  • 接口和它的Mapper配置文件必须同名!
  • 接口和它的的配置文件必须在同一个包下!

方式三:使用扫描包进行注入绑定
mybatis-config.xml

    <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册!-->
    <mappers>
       <package name="com.guo.dao"/>
    </mappers>

注意点:

  • 接口和它的Mapper配置文件必须同名!
  • 接口和它的的配置文件必须在同一个包下!

如果配置不对会报错:

mybatis

8. 生命周期和作用域

mybatis
mybatis

生命周期作用域是至关重要的,因为错误的使用会导致非常严重的并发问题

SqlSessionFactoryBuilder:

  • 一旦创建了 SqlSessionFactory,就不再需要它了
  • 作用域 :局部变量

SqlSessionFactory:

  • 可以理解为数据库连接池
  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
  • 多次重建 SqlSessionFactory 被视为一种代码“坏习惯”
  • 因此 SqlSessionFactory 的最佳作用域是应用作用域。全局变量
  • 最简单的就是使用单例模式或者静态单例模式。

SqlSession:

  • 连接到数据库连接池的一个请求。
  • SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
  • 用完之后需要关闭,否则资源被占用!

mybatis

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值