1、嵌套查询
嵌套查询其实算是个知识的扩充点把,就是不用写比较复杂的sql进行多表联查,而是通过xml文件把他们关联起来,当查询一个表的时候,也把另一个表查了
但是因为嵌套查询需要执行俩次sql语句,因此执行的效率会比执行一次的效率低
1.1 实体类
首先我们先查看数据库两张表的结构
可以看到两张表的关系是第一张表的id对应第二张表的dept_id
(1)导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.qianwz</groupId>
<artifactId>mybatis02</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>
(2)根据ROM创建实体类
package com.qianwz.entity;
import lombok.Data;
@Data
public class Department {
private Integer id;
private String name;
private String location;
}
package com.qianwz.entity;
import lombok.Data;
@Data
public class Employee {
private Integer id;
private String name;
private String salary;
private Department departments;
}
(3)创建接口
package com.qianwz.dao;
import com.qianwz.entity.Department;
public interface DepartmentDao {
Department findById(Integer id);
}
package com.qianwz.dao;
import com.qianwz.entity.Employee;
public interface EmployeeDao {
Employee findById(Integer id);
}
(4)创建工具类
package com.qianwz.util;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory;
public class DruidDataSourceFactory extends PooledDataSourceFactory {
public DruidDataSourceFactory(){
this.dataSource = new DruidDataSource();//替换数据源
}
}
(5)
1、log4j.properties 的文件 方便我们之后查看懒加载
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
2、db.properties 文件
db.driverClassName = com.mysql.cj.jdbc.Driver
db.url = jdbc:mysql://localhost:3306/javacoffee?serverTimezone=Asia/Shanghai&characterEncoding=UTF8
db.username=root
db.password=1234
(6)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文件-->
<properties resource="db.properties"></properties>
<!-- 下面注释的这个是懒加载开启的方式!!!-->
<!-- <settings>-->
<!-- <setting name="lazyLoadingEnabled" value="true"/>-->
<!-- <setting name="aggressiveLazyLoading" value="false"/>-->
<!-- </settings>-->
<!-- 将studentDao中查询需要的实体类按照包重命名 默认为类名首字母小写-->
<typeAliases>
<!-- <typeAlias -->
<package name="com.qianwz.entity"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="com.qianwz.util.DruidDataSourceFactory">
<property name="driverClassName" value="${db.driverClassName}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.qianwz.dao"/>
</mappers>
</configuration>
(7)EmployeeDao.xml 与 DepartmentDao.xml mapper文件
<?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.qianwz.dao.EmployeeDao">
<!-- 手动写入映射 id为这个的id type 为实体类 因为在mybatis-config.xml中重命名过-->
<resultMap id="employeeMap" type="com.qianwz.entity.Employee">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="salary" column="salary"></result>
<!-- select后面加另一个的方法,colum为本次执行的sql语句需要传去的值-->
<association property="departments" javaType="com.qianwz.entity.Department" select="com.qianwz.dao.DepartmentDao.findById" column="dept_id">
</association>
</resultMap>
<select id="findById" resultMap="employeeMap">
select e.id,e.name,e.salary,e.dept_id
from t_employee e
where e.id = #{id}
</select>
</mapper>
<?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.qianwz.dao.DepartmentDao">
<!-- 手动写入映射 id为这个的id type 为实体类 因为在mybatis-config.xml中重命名过-->
<resultMap id="departmentMap" type="com.qianwz.entity.Department">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="location" column="location"></result>
</resultMap>
<select id="findById" resultMap="departmentMap">
select d.id,d.name,d.location
from t_department d
where d.id = #{id}
</select>
</mapper>
(8)测试代码
@org.junit.Test
public void test2() throws IOException {
String resourrce = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resourrce);
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = build.openSession();
EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
Employee dById = mapper.findById(1);
System.out.println(dById);
sqlSession.close();
inputStream.close();
}
结果如下,可以看到执行的sql语句连接到一起了,并且查出来的结果和联合查询的结果差不多
2、懒加载
懒加载对于程序的优化很重要,这里就只是一个简单的小入门,便于大家了解懒加载这个是什么,就拿上面的代码举个栗子
首先我们把懒加载打开,把之前注释的代码取消注释一下
当我们开启懒加载之前,我们控制台打印出来的日志文件如下,会看到执行了两次
sql语句,那么懒加载是什么?我的理解就是开启懒加载之后,程序就只会用什么加载
什么,也可以当成单例模式的懒汉式
下面是开启懒加载之后,控制台打印出来的
可以看到现在只是执行了一半的sql语句,另一半没有执行,可能有的朋友发现他们用
了控制台打印这个对象,最后还是两条,我的理解是当你打印的时候,调用了他们的
toString方法,自然也就会执行两次sql了,懒加载这种思想,也就是用什么调什么方
法,大大节省了系统的开销,对于程序的优化很有用,在面试的时候也是很经常问的,
3、IDEA逆向工程
逆向工程这名字听起来高大上,实际上可以理解为通过数据库表,生成一系列
mapper.xml 实体类等等的文件,就不用咱们按着数据库来一个一个苦逼的建实体类和
xml文件了,对于我们来说十分方便,同时生成的mapper文件中的方法也还挺重要
的,下面就简单介绍一下逆向工程的使用,其实生产逆向工程需要我们自己写的东西不
超过十行,完全cv大法
首先这是我的文件及结构
pom.xml文件导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.coffee</groupId>
<artifactId>abs</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<!-- mybatis-generator自动生成代码插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.6</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.6</version>
</dependency>
</dependencies>
</project>
log4j的配置文件
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
generationConfig,xml文件
<?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="mybatisGenerator" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/javacoffee?serverTimezone=Asia/Shanghai&characterEncoding=UTF8"
userId="root"
password="1234">
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.qq.pojo"
targetProject="D:\javast\java_ssm\abs\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.qq.mapper"
targetProject="D:\javast\java_ssm\abs\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.qq.mapper"
targetProject="D:\javast\java_ssm\abs\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table tableName="student"></table>
<!-- 有些表的字段需要指定java类型
<table schema="" tableName="">
<columnOverride column="" javaType="" />
</table> -->
</context>
</generatorConfiguration>
最后是工具类
package test;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Generator {
public void generator() throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
/**指向逆向工程配置文件*/
File configFile = new File("D:\\javast\\java_ssm\\abs\\src\\main\\resources\\generationConfig.xml");
ConfigurationParser parser = new ConfigurationParser(warnings);
Configuration config = parser.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
callback, warnings);
myBatisGenerator.generate(null);
}
public static void main(String[] args) throws Exception {
try {
Generator generatorSqlmap = new Generator();
generatorSqlmap.generator();
} catch (Exception e) {
e.printStackTrace();
}
}
}