第四天
- 类型转换器
- 自定义类型转换器
- 整合log 4j日志
- 缓存
--------------------------------------------------------------------------------------------------------------------
类型转换器
在mybatis框架中,我们可以对实体类中的属性和数据表中的字段进行自动映射。但是这个自动映射的实现其实是apache公司给我们在底层封装了默认的类型转换。比如实体类中string类型--------->数据表char varchar类型,实体类中的integer类型------>数据表int类型。
默认转换器如下图所示:
但是也会经常出现数据库字段类型与java类属性类型不能自动转换的情况,这时候就需要我们自己定义一个类型转换器
例如下面的需求:
student类中有一个属性是hobby,字段类型是String[],
但是保存在数据库中的字段属性是varchar,传过来的每一个String用分隔。
接下来,我们就要用到自定义转换器了。
--------------------------------------------------------------------------------------------------------------------
自定义转换器 (使用前记得要导入mybits的官网源码)
步骤一:自定义一个类型转换器
public class StringTypeHandler extends BaseTypeHandler<String[]> {
/*
* set方法表示从java到数据库应该采用什么方式进行映射 泛型string[]表示要开始转换的实体类属性类型为String[] String[]
* parameter 是实体类传入的值 JdbcType jdbcType 是数据库中存储的值
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String[] parameter, JdbcType jdbcType)
throws SQLException {
StringBuffer result = new StringBuffer();
for (String st : parameter) {
result.append(st).append(","); // 将字符串进行拼接并用,号进行隔开
}
result.deleteCharAt(result.length() - 1); // 删除最后一个,号
ps.setString(i, result.toString()); // 和jdbc输入一样,最后把stringbuffer类型转换为string类型
}
/*
* get方法表示从数据库到java应该采用什么方式进行映射 下面提供了三种方式从数据库中取值,从字段名取值,从字段名索引取值,从存储过程进行取值
*/
@Override
public String[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
return rs.getString(columnName).split(","); // rs.getstring拿到字段的值,调用split方法直接将字符串转换为字符串数组
}
@Override
public String[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return rs.getString(columnIndex).split(",");
}
@Override
public String[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return cs.getString(columnIndex).split(",");
}
}
步骤二:mybatis.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">
</properties>
<typeHandlers>
<typeHandler handler="First_demo.StringTypeHandler"
javaType="[Ljava.lang.String;" jdbcType="VARCHAR" />
<!--注意jdbcType="VARCHAR"是大写,小写会报错-->
</typeHandlers>
<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>
<!-- 注册userMapper.xml映射文件, usersMapper.xml位于io.xuda.mapping这个包下,所以resource写成io/xuda/mapping/usersMapper.xml -->
<mapper resource="First_demo/PersonMapper.xml" />
</mappers>
</configuration>
步骤三:编写SQL语句,注意这里需要用resultMap
<resultMap id="studentMapping" type="First_demo.student">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="sex" column="sex"></result>
<result property="hobby" column="hobby"
javaType="[Ljava.lang.String;" jdbcType="VARCHAR"></result>
</resultMap>
步骤四:进行插入和查询操作
<?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">
<mapper namespace="First_demo.PersonMapper">
<select id="selectPerson" parameterType="int"
resultMap="studentMapping">
select * from person where id=#{id}
</select>
<insert id="addPerson" parameterType="First_demo.student">
insert into
person(id,username,sex,hobby) values
(#{id},#{username},#{sex},#{hobby,jdbcType=OTHER,typeHandler=First_demo.StringTypeHandler})
</insert>
<!-- 上步中要在hobby属性中标记为其它非默认类型 -->
<resultMap id="studentMapping" type="First_demo.student">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="sex" column="sex"></result>
<result property="hobby" column="hobby"
javaType="[Ljava.lang.String;" jdbcType="VARCHAR"></result>
</resultMap>
</mapper>
步骤四:mapper接口实现
package First_demo;
public interface PersonMapper {
student selectPerson(int id);
void addPerson(student student);
}
步骤五:测试
package First_demo;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class first_test {
public static void main(String[] args) {
InputStream is = Resources.class.getResourceAsStream("/mybatis.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = sessionFactory.openSession(true);
PersonMapper mapper = session.getMapper(PersonMapper.class);
student student = new student();
String[] hobby = { "学习", "玩耍","看书"};
student.setId(6);
student.setUsername("小垃圾");
student.setSex("女");
student.setHobby(hobby);
mapper.addPerson(student);
session.close();
}
}
--------------------------------------------------------------------------------------------------------------------
整合log 4j日志
步骤一:下载log4j.jar包,在mybatis全局配置文件中通过<settings> 标签控制日志开关
<settings>
<setting name="logImpl" value="LOG4J" />
</settings>
步骤二:在src目录下创建file文件,文件名为log4j.properties
log4j.rootLogger=DEBUG, stdout
log4j.logger.com.thundersoft.mybatis.model=TRACE //\u6309\u7167\u5305\u6765\u6253log
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n //\u8F93\u51FA\u683C\u5F0F
--------------------------------------------------------------------------------------------------------------------
缓存
缓存,主要作用是提高了查询性能,减少了跟数据库交互的次数。
Mybatis中有一级缓存和二级缓存。
Mybatis一级缓存是Session缓存。一级缓存的作用域默认是一个SqlSession,Mybatis默认开启一级缓存。
就是说同一个SqlSession中,执行查询SQL语句,第一次会去数据库进行查询,并写到缓存中;第二次执行相同的查询SQL语句,不会到数据库中查询数据而是到缓存中进行查询
Mybatis二级缓存是指mapper映射文件,二级缓存的作用域是同一个namespace下的mapper映射文件下的相同SQL语句,多个SqlSession共享。Mybatis二级缓存不是自动开启的,要手动进行配置。就是说当在第一个SqlSession中,执行查询SQL语句,首先会到Mapper接口中寻找对应方法,并写到缓存中;第二个不同SqlSession执行相同的查询SQL语句,不会到Mapper接口中寻找对应的方法,而是直接从缓存中换取该方法。
一级缓存的开始/关闭
<settings>
<setting name="localCacheScope" value="SESSION/STATEMENT"/>
</settings>
<!--一级缓存的范围有SESSION和STATEMENT两种,默认是SESSION,如果不想使用一级缓存,可以把一级缓存的范围指定为STATEMENT-->
二级缓存的开始/关闭
<settings>
<setting name="cacheEnabled" value="false/true" />
</settings>
<!--true表示开启,false表示关闭 -->