MyBatis框架学习(2)(kuangshen):CRUD操作及配置解析及解决属性名和字段名不一致的问题

namespace

1、将上面案例中的UserMapper接口改名为 UserDao;
2、将UserMapper.xml中的namespace改为为UserDao的路径 .
3、再次测试

结论:
配置文件中namespace中的名称为对应Mapper接口或者Dao接口的完整包名,必须一致!

select

  • select标签是mybatis中最常用的标签之一
  • select语句有很多属性可以详细配置每一条SQL语句
    • SQL语句返回值类型。【完整的类名或者别名】
    • 传入SQL语句的参数类型 。【万能的Map,可以多尝试使用】
    • 命名空间中唯一的标识符
    • 接口中的方法名与映射文件中的SQL语句ID 一一对应
    • id
    • parameterType
    • resultType

需求:根据id查询用户

1、在UserMapper中添加对应方法

public interface UserMapper {
     
    // 查询全部用户
    List<User> getUserList();
    // 根据ID查询用户
    User getUserById(int id);
}

2、在UserMapper.xml中添加Select语句


<select id="getUserById"  resultType="com.fan.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标签进行插入操作,它的配置和select标签差不多!

需求:给数据库增加一个用户

1、在UserMapper接口中增加对应的方法

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

2、在UserMapper.xml中添加insert语句

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

3、测试

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

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

        int res = mapper.addUser(new User(5, "哈哈", "123333"));
        if (res > 0) {
     
            System.out.println("插入成功!");
        }

        // 提交事务
        sqlSession.commit();
        sqlSession.close();
    }

注意点:增、删、改操作需要提交事务!

update

我们一般使用update标签进行更新操作,它的配置和select标签差不多!

需求:修改用户的信息

1、同理:编写接口方法

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

2、编写对应的配置文件的SQL

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

3、测试

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

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

        mapper.updateUser(new User(4, "呵呵", "123123"));

        sqlSession.commit();


        sqlSession.close();
    }

delete

我们一般使用delete标签进行删除操作,它的配置和select标签差不多!

需求:根据id删除一个用户

1、同理:编写接口方法

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

2、编写对应的配置文件SQL

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

3、测试

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

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

        mapper.deleteUser(4);

        sqlSession.commit();


        sqlSession.close();
    }

小结

  • 所有的增删改操作都需要提交事务!
  • 接口所有的普通参数,尽量都写上@Param参数,尤其是多个参数时,必须写上!
  • 有时候根据业务的需求,可以考虑使用map传递参数!
  • 为了规范操作,在SQL的配置文件中,我们尽量将Parameter参数和resultType都写上!

思考题

模糊查询like语句该怎么写?

第1种:在Java代码中添加sql通配符。

@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();
    }
<select id="getUserLike" resultType="com.fan.pojo.User">
        select * from mybatis.user where name like #{value}
select>

第2种:在sql语句中拼接通配符,会引起sql注入

string wildcardname = “smi”;
list names = mapper.selectlike(wildcardname);



配置解析

核心配置文件

  • mybatis-config.xml系统核心配置文件
  • MyBatis的配置文件包含了会深深影响MyBatis行为和属性信息。
  • 能配置的内容如下:
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)

我们可以阅读 mybaits-config.xml 上面的 dtd 的头文件!

environments元素

<environments default="development">
  <environment id="development">
    <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>
  • 配置MyBatis的多套运行环境,将SQL映射到多个不同的数据库上,必须指定其中一个为默认运行环境(通过default指定)

  • 子元素节点:environment

    • dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
    • 数据源必须配置的。
    • 有三种内建的数据源类型。
    type="[UNPOOLED|POOLED|JNDI]")
    
    • unpooled: 这个数据源的实现只是每次被请求时打开和关闭连接。
    • pooled: 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来 , 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
    • jndi: 这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
    • 数据源也有很多第三方的实现,比如dbcp,c3p0,druid等等…

    • 详情:查看官方文档
    • 这两种事务管理器类型都不需要设置任何属性。
    • 具体的一套环境,通过设置id进行区别,id保证唯一!
    • 子元素节点:transactionManager - [ 事务管理器 ]
    
    <transactionManager type="[ JDBC | MANAGED ]"/>
    
    • 子元素节点:数据源(dataSource)

属性(Properties)

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

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

在这里插入图片描述
编写一个配置文件

db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456

在核心配置文件中映入

    
    <properties resource="db.properties">
        <property name="username" value="root"/>
        <property name="pwd" value="11111"/>
    properties>
  • 可以直接引入外部文件
  • 可以在其中增加一些属性配置
  • 如果两个文件有同一个字段,优先使用外部配置文件的!

类型别名(typeAliases)

  • 类型别名是为 Java 类型设置一个短的名字。
  • 存在的意义仅在于用来减少类完全限定名的冗余。
    
    <typeAliases>
        <typeAlias type="com.fan.pojo.User" alias="User"/>
    typeAliases>

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:
扫描实体类的包,它的默认别名就为这个类的 类名,首字母小写!


<typeAliases>
    <package name="com.fan.pojo"/>
typeAliases>

在实体类比较少的时候,使用第一种方式。

如果实体类十分多,建议使用第二种。

第一种可以DIY别名,第二种则·不行·,如果非要改,需要在实体上增加注解

@Alias("user")
public class User {
     }

设置

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

在这里插入图片描述
在这里插入图片描述

其他配置

  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins插件
    • mybatis-generator-core
    • mybatis-plus
    • 通用mapper

映射器(mappers)

MapperRegistry:注册绑定我们的Mapper文件

方式一: 【推荐使用】


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

方式二:使用class文件绑定注册


<mappers>
    <mapper class="com.fan.dao.UserMapper"/>
mappers>

注意点:

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

方式三:使用扫描包进行注入绑定


<mappers>
    <package name="com.fan.dao"/>
mappers>

注意点:

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

生命周期和作用域

MyBatis框架学习(2)(kuangshen):CRUD操作及配置解析及解决属性名和字段名不一致的问题_第1张图片
生命周期,和作用域,是至关重要的,因为错误的使用会导致非常严重的并发问题

SqlSessionFactoryBuilder:

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

SqlSessionFactory:

  • 说白了就是可以想象为 :数据库连接池
  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
  • 因此 SqlSessionFactory 的最佳作用域是应用作用域。
  • 最简单的就是使用单例模式或者静态单例模式。

SqlSession

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

MyBatis框架学习(2)(kuangshen):CRUD操作及配置解析及解决属性名和字段名不一致的问题_第2张图片
这里面的每一个Mapper,就代表一个具体的业务!

解决属性名和字段名不一致的问题

1、问题

数据库中的字段

MyBatis框架学习(2)(kuangshen):CRUD操作及配置解析及解决属性名和字段名不一致的问题_第3张图片
新建一个项目,拷贝之前的,测试实体类字段不一致的情况

public class User {
     
    
    private int id;
    private String name;
    private String password;
}

测试出现问题

解决方法:

  • 起别名
    <select id="getUserById" resultType="com.fan.pojo.User">
    select id,name,pwd as password from mybatis.user where id = #{id}
    
```

2、resultMap

结果集映射

id   name   pwd
id   name   password

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

<select id="getUserById" resultMap="UserMap">
    select * from mybatis.user where id = #{id}
select>
  • resultMap 元素是 MyBatis 中最重要最强大的元素
  • ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。
  • ResultMap 最优秀的地方在于,虽然你已经对它相当了解了,但是根本就不需要显式地用到他们。
  • 如果世界总是这么简单就好了。

你可能感兴趣的:(java)