MyBatis-02
今日要点:
一、增删改查实现
UserMapper:
public interface UserMapper{
//获取用户列表
List<User> getUserList();
//增加一个用户
int addUser(User user);
//删除一个用户
int deleteUser(long id);
//更改一个用户
int updateUser(User user);
}
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">
<!--namespace:对应数据访问层的接口-->
<mapper namespace="com.jack.dao.UserMapper">
<!--id:接口内部的方法名;resultType:方法返回的实体类或类型;parameterType:方法参数类型;#{}:从parameterType中取值-->
<!--查询-->
<select id="getUserList" resultType="com.jack.pojo.User">
select * from test.user
</select>
<!--增加-->
<insert id="addUser" parameterType="com.jack.pojo.User">
insert into test.user (id,name,age,email)
values (#{id},#{name},#{age},#{email});
</insert>
<!--删除-->
<delete id="deleteUser" parameterType="long">
delete
from test.user
where id = #{id};
</delete>
<!--更新-->
<update id="updateUser" parameterType="com.jack.pojo.User">
update test.user
set name = #{name},age = #{age},email = #{email}
where id = #{id};
</update>
</mapper>
UserMapperTest:
public class UserMapperTest {
/**
* 测试查询操作
*/
@Test
public void test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserList();
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
/**
* 测试添加操作
*/
@Test
public void testAddUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.addUser(new User(6,"狗子",12,"1286624819@qq.com"));
//提交事务,务必添加,否则数据库字段不会发生改变
sqlSession.commit();
sqlSession.close();
}
/**
* 测试删除操作
*/
@Test
public void testDeleteUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.deleteUser(5);
//提交事务,务必添加,否则数据库字段不会发生改变
sqlSession.commit();
sqlSession.close();
}
/**
* 测试更新操作
*/
@Test
public void testUpdateUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.updateUser(new User(6,"飞飞",23,"1346793940@qq.com"));
//提交事务,务必添加,否则数据库字段不会发生改变
sqlSession.commit();
sqlSession.close();
}
}
二、Map以及模糊查询
1、Map适用情况:
实体类或者数据库中的表字段参数过多时应当考虑用Map
如何使用Map?
首先在UserMapper中创建一个方法,方法接受参数设置为Map类型
int insertUser(Map<String,Object> map);
在UserMapper.xml文件中写SQL语句
<insert id = "insertUser" parameterType = "map">
insert into test.user
(id,name,age,email)
values (#{user_id},#{user_name},#{user_age},#{user_email})
</insert>
进行单元测试
@Test
public void testInsertUser(){
//从MyBatis工具类取得SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//加载Mapper类文件
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//创建Map对象
Map<String,Object> map = new HashMap<String,Object>();
map.put("user_id",6);
map.put("user_name","Jack");
map.put("user_age",22);
map.put("user_email","1286624819@qq.com");
//调用mapper中的方法
mapper.insertUser(map);
sqlSession.commit();
sqlSession.close();
}
实践过程中发现,在实体类或者数据库字段参数很多的情况下,使用Map进行传参仅仅有利于update更新操作,即只需要更新必要的字段,避免了写过多无用代码
2、模糊查询
模糊查询的两种方式:
第一种方式:
UserMapper:
List<User> getUserLike(String value);
XML的SQL语句:
<select id = "getUserLike" parameterType = "String" resultType = "com.jack.pojo.User">
select * from test.user where name like #{value}
</select>
测试:
@Test
public void testGetUserLike(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//加载Mapper类文件
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.getUserLike("%J%");
sqlSession.commit();
sqlSession.close();
}
第二种方式:
UserMapper:
List<User> getUserLike(String value);
XML的SQL语句:
<select id = "getUserLike" parameterType = "String" resultType = "com.jack.pojo.User">
select * from test.user where name like "%"#{value}"%"
</select>
测试:
@Test
public void testGetUserLike(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//加载Mapper类文件
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.getUserLike("J");
sqlSession.commit();
sqlSession.close();
}
三、配置属性优化
数据库配置可以单独写一个properties文件,便于管理:
db.properties:
driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/test?useSSL=false&characterEncoding=utf8&allowPublicKeyRetrieval=true
username = root
password = root
此时mybatis-config.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>
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<!--事务管理-->
<transactionManager type="JDBC"/>
<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="mapper/UserMapper.xml"/>
</mappers>
</configuration>
environment属性:
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中,现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置。
因此,针对不同生产环境我们可以做出如下配置:
<?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"/>
<environments default="development">
<!--发布环境-->
<environment id="development">
<!--事务管理-->
<transactionManager type="JDBC"/>
<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>
<!--测试环境-->
<environment id="test">
<!--事务管理-->
<transactionManager type="JDBC"/>
<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>
<!--生产环境-->
<environment id="pro">
<!--事务管理-->
<transactionManager type="JDBC"/>
<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="mapper/UserMapper.xml"/>
</mappers>
</configuration>
属性说明:
POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求。
poolMaximumActiveConnections
– 在任意时间可存在的活动(正在使用)连接数量,默认值:10poolMaximumIdleConnections
– 任意时间可能存在的空闲连接数。poolMaximumCheckoutTime
– 在被强制返回之前,池中连接被检出(checked out)时间,默认值:20000 毫秒(即 20 秒)poolTimeToWait
– 这是一个底层设置,如果获取连接花费了相当长的时间,连接池会打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直失败且不打印日志),默认值:20000 毫秒(即 20 秒)。poolMaximumLocalBadConnectionTolerance
– 这是一个关于坏连接容忍度的底层设置, 作用于每一个尝试从缓存池获取连接的线程。 如果这个线程获取到的是一个坏的连接,那么这个数据源允许这个线程尝试重新获取一个新的连接,但是这个重新尝试的次数不应该超过poolMaximumIdleConnections
与poolMaximumLocalBadConnectionTolerance
之和。 默认值:3(新增于 3.4.5)poolPingQuery
– 发送到数据库的侦测查询,用来检验连接是否正常工作并准备接受请求。默认是“NO PING QUERY SET”,这会导致多数数据库驱动出错时返回恰当的错误消息。poolPingEnabled
– 是否启用侦测查询。若开启,需要设置poolPingQuery
属性为一个可执行的 SQL 语句(最好是一个速度非常快的 SQL 语句),默认值:false。poolPingConnectionsNotUsedFor
– 配置 poolPingQuery 的频率。可以被设置为和数据库连接超时时间一样,来避免不必要的侦测,默认值:0(即所有连接每一时刻都被侦测 — 当然仅当 poolPingEnabled 为 true 时适用)。
个人想法:如果我们将environmens中的属性default设置为${environment},在配置文件中写入environment的值,这样会不会更加便于管理
四、配置别名优化
类型别名可为 Java 类型设置一个缩写名字,它仅用于 XML 配置,意在降低冗余的全限定类名书写。
如此一来config文件可简化为:
<?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"/>
<typeAliases>
<typeAlias type="com.jack.pojo.User" alias="User"/>
</typeAliases>
<environments default="development">
<!--发布环境-->
<environment id="development">
<!--事务管理-->
<transactionManager type="JDBC"/>
<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>
<!--测试环境-->
<environment id="test">
<!--事务管理-->
<transactionManager type="JDBC"/>
<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>
<!--生产环境-->
<environment id="pro">
<!--事务管理-->
<transactionManager type="JDBC"/>
<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="mapper/UserMapper.xml"/>
</mappers>
</configuration>
另一种方式:
<?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"/>
<typeAliases>
<package name="com.jack.pojo"/>
</typeAliases>
<environments default="development">
<!--发布环境-->
<environment id="development">
<!--事务管理-->
<transactionManager type="JDBC"/>
<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>
<!--测试环境-->
<environment id="test">
<!--事务管理-->
<transactionManager type="JDBC"/>
<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>
<!--生产环境-->
<environment id="pro">
<!--事务管理-->
<transactionManager type="JDBC"/>
<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="mapper/UserMapper.xml"/>
</mappers>
</configuration>
这样就会扫描包下的Java Bean
每一个在包 domain.blog
中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author
的别名为 author;若有注解,则别名为其注解值
@Alias("author")
public class Author {
...
}
五、配置映射器说明
Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉MyBatis 到哪里去找映射文件
有四种方式:
<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
一般建议使用第一种方式,第三种以及第四种方式应当在包下面存在,而不是在resource文件夹下存在
六、生命周期以及作用域
官方描述:
SqlSessionFactoryBuilder:方法作用域内
SqlSessionFactory:运行期间一直存在,最好保持单例模式
SqlSession:不是线程安全的,因此,每打开一个SqlSession就应当在使用完毕后将其关闭
七、ResultMap结果集映射
解决属性名和字段名不一致的问题
用法:
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
其中properties对应实体类实际属性值,而column对应的是数据库字段。
即将实际实体类属性与数据库字段进行了映射
<select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>
相关文章:
- 什么是MyBatis
- 为什么要用MyBatis
- 如何使用MyBatis?
- 日志实现
- 分页实现
- 注解开发
- MyBatis执行流程
- 通过注解实现增删改查
- LomBok使用
- 复杂查询环境搭建
- 多对一处理
- 一对多处理
- 动态SQL环境搭建
- IF标签
- 常用标签
- WHERE
- CHOOSE
- WHEN
- TRIM
- OTHERWISE
- SET
- ForEach标签
- 缓存简介
- 一级缓存
- 二级缓存
- MyBatis缓存原理