1.3 配置及优化
环境配置(environments)
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中,开发、测试和生产环境需要有不同的配置,不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory实例只能选择一种环境。所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例
事务管理器(transactionManager)
type="[JDBC|MANAGED]",如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器,因为Spring 模块会使用自带的管理器来覆盖前面的配置
数据源(dataSource)
type="[UNPOOLED|POOLED|JNDI]"
1.3.1 配置属性优化
property属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。
编写properties配置文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/xxx?serverTimezone=GMT
username=root
password=root
在主配置文件中引入properties配置文件即可,用 $ 符号引入
<properties resource="db.properties"/>
<environments default="test">
<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>
</environments>
1.3.2 配置别名优化
类型别名(typeAliases)
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写
<typeAliases>
<typeAlias type="com.wlt.domain.User" alias="user"/>
</typeAliases>
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,在没有注解的情况下,会使用Bean 的首字母小写的非限定类名来作为它的别名。
<typeAliases>
<typeAlias package="com.wlt.domain"/>
</typeAliases>
若有注解,则别名为其注解,例如
@Alias("user")
public class User {
...
}
1.3.3 映射器
<!-- 使用相对于类路径的资源引用 -->
<mapper resource="com/wlt/mapper/Mapper.xml"/>
<!-- 使用映射器接口实现类的完全限定类名 -->
<mapper class="com.wlt.mapper.UserMapper"/>
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="com.wlt.dao"></package>
</mappers>
退荐使用第一种方式 , 即resource,后面springboot和mybatis整合时也常用resource方式来指定mapper配置文件的引用
第二种方式和第三种方式要求接口和其对应的maper文件同名且在同一个包下,否则会报错
1.3.4 作用域和生命周期
作用域和生命周期是至关重要的,错误的使用会造成严重的并发问题
SqlSessionFactoryBuilder对象
<u>该对象的作用在于创建SqlSessionFactory对象,创建成功后就失去作用,所以它只能存在于创建SqlSession对象的方法中,而不能长期存在,因此其最佳作用域为局部变量</u>
SqlSessionFactory对象
相当于一个数据库连接处,其作用在于创建SqlSession接口对象,一旦创建了SqlSessionFactory对象就要长期保存,其生命周期等同于Mybatis的应用周期
SqlSessionFactory是一个对数据库的连接池,占据着数据库的连接资源,如果创建多个对象,那就存在多个数据库连接池,不利于对数据库资源的控制,应尽量避免此情况发生
SqlSessionFactory的最佳作用域为 应用作用域(从Mybatis开始到结束)
SqlSession对象
相当于一个数据库连接(Connection对象),存活在一个业务请求中,处理完请求后需要关闭这条连接(SqlSession.close()),归还到SqlSessionFactory中,否则数据库资源很容易耗费光,系统瘫痪
SqlSession的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是 请求或方法作用域。

1.3.5 设置
mapUnderscoreToCamelCase:是否开启驼峰命名自动映射,即从经典数据库列名A_COLUMN 映射到经典 Java 属性名 aColumn。
![]()
1.4 ResultMap结果集映射
1.4.1 简单举例:解决数据库字段名和实体类属性名不一致的问题

实体类中的属性为password,而数据库表中的字段为pwd
/**
* 通过id查询person表的信息的测试方法
*/
@Test
public void getPersonByIdTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person = mapper.getPersonById(2);
System.out.println(person);
}
查询出的结果为:

可以看到查出的数据中实体类的 password属性为null,因为mybatis没有从数据库中找到对应的字段名
解决方法:使用resultMap结果集映射
select标签中的resultMap应与resultMap标签的id值想同
resultMap中的type标签为返回的实体类,result标签中的column对应表中的字段名,而property对应实体类中的属性名
<mapper namespace="com.wlt.mapper.PersonMapper">
<resultMap id="personMap" type="com.wlt.domain.Person">
<result column="pwd" property="password"></result>
</resultMap>
<select id="getPersonById" resultMap="personMap">
select * from person where id=#{id};
</select>
</mapper>
重新进行测试后可得:
![]()
1.5 日志工厂
1.5.1 标准的日志工厂 STDOUT_LOGGING
<settings>
<!--标准的日志实现,不需要导包,可直接使用-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
在控制台打印出的日志信息

1.5.2 log4j日志
-
在pom.xml中导入log4j的依赖
<!-- 导入log4j的依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
在resources资源下编写log4j.properties配置文件
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/wlt.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
-
使用log4j的类
//导包
import org.apache.log4j.Logger;
//创建logger对象
static Logger logger = Logger.getLogger(UserTest.class);
//logger的三个方法
logger.info()
logger.error()
logger.debug()
1.6 分页查询功能
1.6.1 利用limit进行分页,map集合传参
/**
* 分页查询
* @param map
*
* @return
*/
List<Person> findPersonByPage(Map<String,Object> map);
<select id="findPersonByPage" resultMap="personMap" parameterType="map">
select * from person limit #{startIndex},#{pageSize};
</select>
/**
* 分页查询的测试方法
*/
@Test
public void findPersonByPageTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("startIndex",1);
map.put("pageSize",3);
List<Person> person = mapper.findPersonByPage(map);
for (Person pr : person) {
System.out.println(pr);
}
sqlSession.close();
}
1.7 使用注解开发(简单的sql语句可以使用注解,但对于复杂的sql语句使用xml来进行编写,方便后期的维护)
直接在接口上添加注解后再编写sql语句
使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪。因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。
接口方法中传入参数为基本类型或者String类型时需要添加注解@Param()
sql语句中引用的就是@Param()注解中的属性名
/**
* 查询所有信息
* @return
*/
@Select("select * from person")
List<Person> findAllPerson();
/**
* 通过id查询信息
* @param id
* @return
*/
@Select("select * from person where id=#{id}")
Person findPersonById(@Param("id") int id);
/**
* 增加用户
* @param person
*/
@Insert("insert into person (name,pwd)values(#{name},#{password})")
void insertPerson(Person person);
/**
* 通过id删除信息
* @param id
*/
@Delete("delete from person where id=#{id}")
void deletePersonById(@Param("id") int id);
/**
* 通过id修改信息
* @param person
*/
@Update("update person set name=#{name},pwd=#{password} where id=#{id}")
void updatePersonById(Person person);
/**
* 使用注解测试查询所有信息
*/
@Test
public void findAllPersonTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
List<Person> allPerson = mapper.findAllPerson();
for (Person person : allPerson) {
System.out.println(person);
}
sqlSession.close();
}
/**
* 使用注解测试通过id查询信息
*/
@Test
public void findPersonByIdTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person = mapper.findPersonById(2);
System.out.println(person);
sqlSession.close();
}
/**
* 使用注解测试增加用户
*/
@Test
public void insertPersonTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
mapper.insertPerson(new Person("悦湖","152400"));
sqlSession.close();
}
/**
* 使用注解测试修改用户信息
*/
@Test
public void updatePersonTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
mapper.updatePersonById(new Person("小费","0303",6));
sqlSession.close();
}
/**
* 使用注解测试删除用户信息
*/
@Test
public void deletePersonByIdTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
mapper.deletePersonById(6);
sqlSession.close();
}
本文详细介绍了MyBatis的环境配置、事务管理器、数据源的配置,以及属性优化、类型别名、映射器的设置。强调了SqlSessionFactoryBuilder和SqlSessionFactory对象的作用域,推荐使用resource方式引用mapper配置文件。此外,讲解了日志工厂的配置,包括STDOUT_LOGGING和log4j的使用。最后,提到了分页查询和注解开发的实践方法,指出注解适用于简单SQL,复杂SQL则宜采用XML映射。
794

被折叠的 条评论
为什么被折叠?



