Mybatis中Map的使用
如果需要所有的代码,可以看我上一篇
在接口中定义
int addUser1(Map<String,Object> map);
插入语句
<insert id="addUser1">
insert into user(id,name,pwd) values (#{userid},#{username},#{userPwd})
</insert>
测试
@Test
public void test(){
SqlSession sqlSession = MyUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map=new HashMap();
map.put("userid",9);
map.put("username","妮妮");
map.put("userPwd","28592385");
mapper.addUser1( map);
sqlSession.commit();
sqlSession.close();
}
如果有多个参数,使用map;map中还可以自定义键的名字,当然如果键的名字改变,需要修改插入语句中值,要一一对应。好处是可以随意修改,而实体类传参不能随意修改。
属性
属性可以在外部进行配置,并可以进行动态替换。
使用的几种方式
第一种,组合使用
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8
<properties resource="db.properties">
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="123456"/>
</properties>
第二种,引入外部
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=12345
优先级问题,如果同时在内部和外部配置name和password,就会先使用外部,外部优先级大于内部
无论是内部的配置还是外部的配置都需要跟值一一对应,因为这里是动态绑定的
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
解释一下,在每个值面前加前缀(jdbc.url)的目的,如果直接使用的话,会有报错,所以我就全部换了
类型别名
配置类型别名的三种方式
第一种,核心配置(mybatis-config.xml)文件中使用,有先后顺序,会有提示
<typeAliases>
<typeAlias type="com.qing.pojo.User" alias="user"></typeAlias>
</typeAliases>
第二种,指定实体类的包名
没有注解,user或User作为它的别名
<typeAliases>
<package name="com.qing.pojo"/>
</typeAliases>
有注解,使用注解值作为它的别名,也需要扫描包,要需要配注解值,在实体类上,只是可以任意指定别名
<typeAliases>
<package name="com.qing.pojo"/>
</typeAliases>
@Alias("hello")
public class User {...}
只要指定了别名,别名就可以代替包名+类名,所在的任何位置使用
映射器(mappers)
MapperRegistry:注册绑定我们的mapper文件
四种映射方式
方式一:resources绑定注册,推荐使用
<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="com/qing/dao/UserMapper.xml"/>
</mappers>
方式二:url,不建议使用
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
</mappers>
方式三:使用class文件绑定注册
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="com.qing.dao.UserMapper"/>
</mappers>
注意点:
- 接口和它的Mapper配置文件必须同名
- 接口和它的Mapper配置文件必须在同一个包下
方式四:使用包扫描
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="com.qing.dao"/>
</mappers>
注意点:
- 接口和它的Mapper配置文件必须同名
- 接口和它的Mapper配置文件必须在同一个包下
如果没有注册就会报错
生命周期和作用域
理解我们之前讨论过的不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。
执行流程图:
SqlSessionFactoryBuilder
一旦创建了 SqlSessionFactory,就不再需要它了 。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。
SqlSessionFactory(可以想象成数据库连接池)
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
SqlSession
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。用完需要关闭,否则浪费资源。
这里的每一个Mapper,就代表一个具体的业务。上图mapper查询用户id