JavaWeb——Mybatis优化

  1. Mybatis #{}和${}的区别
  2. Mybatis懒加载,延迟加载
  3. Mybatis一级缓存、二级缓存
  4. Mybatis逆向工程

一、Mybatis #{}和${}的区别

  1. #{ }使用预编译,会自动识别参数类型,如果是字符串类型会自动添加"",不能用在模糊查询上。
  2. ${ } 类似与字符串拼接,如果只有一个入参,必须使用${value},单个参数不会形成映射。
  3. 在mybatis里能使用#{ }时就不使用${ },防止SQL注入。

二、Mybatis懒加载,延迟加载,按需加载

在使用嵌套查询多表时才能使用

在一张表中嵌套查询在使用的时候,才去查询,节省资源

使用的时候需要在配置文件中注明

作项目优化时比较常用

主配置文件:

<?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>

<settings>
<!-- 全局的懒加载设置 -->
	<setting name="lazyLoadingEnabled" value="true"/>
	<!-- 设为false不会一次全部查询 -->
	<setting name="aggressiveLazyLoading" value="false"/>
</settings>

	<!-- 配置别名 作用:在mapper映射文件内 不用写包名+类名 -->
	<typeAliases>
		<!-- type 需要配置别名的类 alias 别名 -->
		<!-- <typeAlias type="beer.onexone.cnf" alias="cnf"/> -->
		<!-- 也可以配置扫描包 该包下所有的类 默认添加别名 不区分大小写 -->
		<package name="beer.onexone.beans"  />
	</typeAliases>

	<!-- default 表示默认的使用id -->
	<environments default="development">
		<environment id="development">
			<!-- 事务管理 type只有两个值 JDBC(支持事务) managed(不支持事务) -->
			<transactionManager type="JDBC" />
			<!-- 数据源 type 连接池的类型 POOLED jdbc连接池 UNPOOLED 不使用连接池 JNDI 其他连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql:///userinfo?characterEncoding=utf8" />
				<property name="username" value="root" />
				<property name="password" value="Qwertyuiop852963" />
			</dataSource>
		</environment>
	</environments>

	<!-- 用来管理映射文件 -->
	<mappers>
		
		<!-- <mapper resource="beer/onexone/entity/PersonMapper.xml"/> -->
  		<!-- <mapper  class="beer.onexone.mapper.PersonMapper"/> -->
		<!-- 单个映射文件 resourse 写xml的包名加上名字 调用session.insert  -->
		<!--也可以使用class来配置
						1、需要创建一个与接口名称与xml文件一致的接口类
						2、在接口中创建和mapper中对应的方法
						3、在mapper.xml文件中namespace必须指定接口的地址
						使用时调用session.getMapper()方法 -->
		<!-- 还可以使用packge标签来配置单个映射文件,可以只配置包名 -->
		<package name="beer.onexone.mapper"/>
		
	</mappers>
</configuration>

子配置文件:

<?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="beer.onexone.mapper.EndableLazyL">

	<resultMap type="Employee" id="baseEmployee">
		<id column="e_id" property="id" />
		<result column="e_name" property="name" />
		<result column="e_age" property="age" />
		<result column="e_sal" property="salary" />
	</resultMap>

	<resultMap type="Department" id="theDepartment">
		<id column="d_id" property="id" />
		<result column="d_name" property="name" />
		<result column="d_address" property="address" />
		<collection property="employees" 
			column="d_id"  ofType="employee"  select="empByDep">
		</collection>
	</resultMap>

	<!-- 使用嵌套查询 -->
	<select id="selectDepByID" resultMap="baseEmployee">
		select * from department where e_depart_id =#{id}
	</select>
	<select id="empByDep" resultMap="theDepartment">
		select * from employee where e_id = #{id}
	</select>
</mapper>

接口:

package beer.onexone.mapper;

import beer.onexone.beans.Department;

public interface  EndableLazyL{
	Department  empByDep(int id);
}

测试类:
当不查询Department的内Employee时

	@Test
	public void EndableLazyLoad() throws Exception {
		// 获取配置文件
		InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
		// 获取工厂
		SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
		// 开启session
		SqlSession openSession = build.openSession();
		//获取mapper
		EndableLazyL mapper = openSession.getMapper(EndableLazyL.class);
		//查询
		Department department = mapper.empByDep(1);
		System.out.println();
	}

只进行一次查询

DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7a1ebcd8]
DEBUG [main] - ==>  Preparing: select * from employee where e_id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <==      Total: 1

三、Mybatis一级缓存、二级缓存

一级缓存,session级别的缓存
mybatis默认使用缓存
在使用mybatis查询的时候 先查看是否有缓存,若有缓存则直接调用缓存

二级缓存,全局缓存,作用范围更大,项目运行期间存在
需要在配置中开启二级缓存,实体类必须实现序列化接口

在主配置中开启二级缓存

mapper 映射中加一根标签  cache

如果要多个mapper 公共一个缓存地址

使用引入   缓存地址的时候  确保被引入的命名空间 开启了全局缓存 使用了cache 标签

属性 :readOnly

保证缓存  如果有更新的时候  不会去更新  如果想要在数据更新同时改变缓存数据 

四、Mybatis逆向工程

根据数据库的表
创建javabean  映射对应的接口   mapper映射  常用的方法
不支持多表联合查询 和复杂的查询 

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
	<context id="testTables" targetRuntime="MyBatis3">
		<commentGenerator>
			<!-- 是否去除自动生成的注释 true:是 : false:否 -->
			<property name="suppressAllComments" value="true" />
		</commentGenerator>
		<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
		<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/userinfo" userId="root"
			password="Qwertyuiop852963">
		</jdbcConnection>
		
		<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 
			NUMERIC 类型解析为java.math.BigDecimal -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>

		<!-- targetProject:生成实体类的位置 -->
		<javaModelGenerator targetPackage="beer.onexone.po"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
			<!-- 从数据库返回的值被清理前后的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
		
        <!-- targetProject:mapper映射文件生成的位置 -->
		<sqlMapGenerator targetPackage="beer.onexone.mapper" 
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</sqlMapGenerator>
		<!-- targetPackage:mapper接口生成的位置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="beer.onexone.mapper" 
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</javaClientGenerator>
		<!-- 指定数据库表 -->
		<table tableName="person"></table>
	
	</context>
</generatorConfiguration>

生成方法:

package beer.onexone.dao;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;

class GeneratorTest {
	
	public static void main(String[] args) throws Exception {

		List<String> warnings = new ArrayList<String>();
		boolean overwrite = true;

		File configFile = new File("./config/generatorConfig.xml"); 
		ConfigurationParser cp = new ConfigurationParser(warnings);
		Configuration config = cp.parseConfiguration(configFile);
		DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,callback, warnings);
		myBatisGenerator.generate(null);
	}
}

日志文件:

DEBUG [main] - Retrieving column information for table "person"
DEBUG [main] - Found column "id", data type 4, in table "userinfo..person"
DEBUG [main] - Found column "sex", data type 4, in table "userinfo..person"
DEBUG [main] - Found column "name", data type 12, in table "userinfo..person"
DEBUG [main] - Found column "birthday", data type 91, in table "userinfo..person"
DEBUG [main] - Found column "age", data type 12, in table "userinfo..person"

jingsongchan

发表评论

电子邮件地址不会被公开。 必填项已用*标注