标签:mysql utf8 err 访问 == name 定义 flow env
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`last_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`gender` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
jdbc.url=jdbc:mysql://192.168.134.100:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&allowMultiQueries=true
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=123456
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
package com.sunxiaping.domain;
import org.apache.ibatis.type.Alias;
import java.io.Serializable;
@Alias("emp")
public class Employee implements Serializable {
private Integer id;
private String lastName;
private String email;
private String gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", lastName=‘" + lastName + ‘\‘‘ +
", email=‘" + email + ‘\‘‘ +
", gender=‘" + gender + ‘\‘‘ +
‘}‘;
}
}
package com.sunxiaping.mapper;
public interface EmployeeMapper {
}
<?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="com.sunxiaping.mapper.EmployeeMapper">
</mapper>
<?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>
<settings>
<!-- 开启自动驼峰命名规则映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启对jdbcType的NULL的支持 -->
<setting name="jdbcTypeForNull" value="NULL"/>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 开启按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.sunxiaping.mapper"/>
</mappers>
</configuration
和数据库同一次会话期间查询到的数据会放在本地缓存中,如果以后需要获取相同的数据,直接从缓存中取,而不需要再去查询数据库。
示例:
EmployeeMapper.java
package com.sunxiaping.mapper;
import com.sunxiaping.domain.Employee;
public interface EmployeeMapper {
Employee findById(Integer id);
}
<?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="com.sunxiaping.mapper.EmployeeMapper">
<!--
抽取可重用的SQL片段,方便后面引用
-->
<sql id="emp_sql" >
id as id,last_name as lastName,email as email ,gender as gender
</sql>
<select id="findById" resultType="com.sunxiaping.domain.Employee">
SELECT <include refid="emp_sql"/>
FROM employee
WHERE id = #{id,jdbcType=INTEGER}
</select>
</mapper>
package com.sunxiaping;
import com.sunxiaping.domain.Employee;
import com.sunxiaping.mapper.EmployeeMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class EmployeeTest {
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
EmployeeMapper employeeMapper = null;
@Before
public void before() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession(true);
employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
}
@After
public void after() {
if (null != sqlSession) {
sqlSession.close();
}
}
@Test
public void testFindById() {
Employee employee1 = employeeMapper.findById(1);
Employee employee2 = employeeMapper.findById(1);
System.out.println(employee1 == employee2);
}
}
步骤:
<settings>
<!-- 开启自动驼峰命名规则映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启对jdbcType的NULL的支持 -->
<setting name="jdbcTypeForNull" value="NULL"/>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 开启按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
<!--
cache标签:配置缓存的相关属性
- evication:缓存回收策略
- LRU:最近最少使用的,移除最长时间不被使用的对象,默认值。
- FIFO:先进先出,按对象进入缓存的顺序来移出它们
- SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象
- WEAK:弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象
- flushInterval:刷新时间,单位是毫秒。
- 缓存多长时间清空一次,默认不清空。
- size:缓存存放多少元素,正整数。
- readOnly:是否只读
- true:只读缓存。
- Mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。
- Mybatis为了加快获取速度,直接将数据在缓存中的引用交给用户。
- 不安全,速度快。
- false:读写缓存。
- Mybatis认为获取的数据可能会被修改。
- Mybatis会利用序列化&&反序列化的技术克隆一份新的数据给你。
- 安全,速度慢。
- type:指定自定义缓存的全类名。
- 实现Cache接口即可
-->
<cache eviction="LRU" flushInterval="60000" readOnly="false" size="1024" />
示例:
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"></properties>
<settings>
<!-- 开启自动驼峰命名规则映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启对jdbcType的NULL的支持 -->
<setting name="jdbcTypeForNull" value="NULL"/>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 开启按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<databaseIdProvider type="DB_VENDOR">
<!--
为不同的数据库厂商起别名
-->
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
<mappers>
<package name="com.sunxiaping.mapper"/>
</mappers>
</configuration>
package com.sunxiaping.mapper;
import com.sunxiaping.domain.Employee;
public interface EmployeeMapper {
Employee findById(Integer id);
}
<?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="com.sunxiaping.mapper.EmployeeMapper">
<!--
cache标签:配置缓存的相关属性
- evication:缓存回收策略
- LRU:最近最少使用的,移除最长时间不被使用的对象,默认值。
- FIFO:先进先出,按对象进入缓存的顺序来移出它们
- SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象
- WEAK:弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象
- flushInterval:刷新时间,单位是毫秒。
- 缓存多长时间清空一次,默认不清空。
- size:缓存存放多少元素,正整数。
- readOnly:是否只读
- true:只读缓存。
- Mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。
- Mybatis为了加快获取速度,直接将数据在缓存中的引用交给用户。
- 不安全,速度快。
- false:读写缓存。
- Mybatis认为获取的数据可能会被修改。
- Mybatis会利用序列化&&反序列化的技术克隆一份新的数据给你。
- 安全,速度慢。
- type:指定自定义缓存的全类名。
- 实现Cache接口即可
-->
<cache eviction="LRU" flushInterval="60000" readOnly="false" size="1024"/>
<sql id="emp_sql">
id as id,last_name as lastName,email as email ,gender as gender
</sql>
<select id="findById" resultType="com.sunxiaping.domain.Employee">
SELECT
<include refid="emp_sql"/>
FROM employee
WHERE id = #{id,jdbcType=INTEGER}
</select>
</mapper>
package com.sunxiaping;
import com.sunxiaping.domain.Employee;
import com.sunxiaping.mapper.EmployeeMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class EmployeeTest {
SqlSessionFactory sqlSessionFactory = null;
@Before
public void before() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testSecondLevelCache() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
EmployeeMapper employeeMapper2 = sqlSession2.getMapper(EmployeeMapper.class);
Employee employee1 = employeeMapper.findById(1);
System.out.println("employee1 = " + employee1);
sqlSession.close();
//第二次查询是从二级缓存中拿到的数据,并没有发送新的SQL
Employee employee2 = employeeMapper2.findById(1);
System.out.println("employee2 = " + employee2);
sqlSession2.close();
}
}
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!-- 磁盘保存路径 -->
<diskStore path="D:\ehcache" />
<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
<!--
属性说明:
l diskStore:指定数据在磁盘中的存储位置。
l defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略
以下属性是必须的:
l maxElementsInMemory - 在内存中缓存的element的最大数目
l maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大
l eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
l overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上
以下属性是可选的:
l timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
l timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
l diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
l diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作
l memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
-->
<?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="com.sunxiaping.mapper.EmployeeMapper">
<!--
配置Ehcache缓存
-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
<sql id="emp_sql">
id as id,last_name as lastName,email as email ,gender as gender
</sql>
<select id="findById" resultType="com.sunxiaping.domain.Employee">
SELECT
<include refid="emp_sql"/>
FROM employee
WHERE id = #{id,jdbcType=INTEGER}
</select>
</mapper>
如果想在命名空间中共享相同的缓存配置和示例,可以使用cache-ref标签来引用另外一个缓存。
示例:
DepartmentMapper.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">
<mapper namespace="com.sunxiaping.mapper.DepartmentMapper">
<!-- 参照缓存 -->
<cache-ref namespace="com.sunxiaping.mapper.EmployeeMapper"/>
</mapper>
标签:mysql utf8 err 访问 == name 定义 flow env
原文地址:https://www.cnblogs.com/xuweiweiwoaini/p/13660080.html