mybaits入门到精通 之 高级应用[generator 代码生成器、外连接查询自动映射 以及动态代理]


mybaits 高级应用

pom.xml 文件配置信息:

 <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <junit.version>5.7.1</junit.version>
    </properties>
    <dependencies>
        <!--非常重要-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.58</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>

        <!--非常重要-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>

        <!--1. 分页插件【非常重要】 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.1.4</version>
        </dependency>
<!--        动态代理 依赖-->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                    <debug>true</debug>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.0</version>
            </plugin>
            <!--mybatis自动生成插件-->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <configurationFile>src/main/resources/create_mapper.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.mybatis.generator</groupId>
                        <artifactId>mybatis-generator-core</artifactId>
                        <version>1.3.2</version>
                    </dependency>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.19</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

generator插件配置信息:

需要注意的是,在执行插件生成代码的时候,sql语句配置文件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="mySqlTables"  targetRuntime="MyBatis3">  
        <commentGenerator>  
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>  
        </commentGenerator>  
        <!--数据库链接URL,用户名、密码 -->  
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/testv4" userId="root" password="root">
        </jdbcConnection>
        <javaTypeResolver>  
            <property name="forceBigDecimals" value="false"/>  
        </javaTypeResolver>  
        <!--pojo生成位置-->  
        <javaModelGenerator targetPackage="com.sichengzhang.t6.pojo" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>  
            <property name="trimStrings" value="true"/>  
        </javaModelGenerator>  
        <!--映射文件生成位置-->  
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">  
            <property name="enableSubPackages" value="true"/>  
        </sqlMapGenerator>  
        <!--dao生成位置-->  
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.sichengzhang.t6.dao" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>  
        <!-- 
		tableName是数据库中的表名或视图名
		domainObjectName是实体类名
		-->  
		<!--表1 有多少表,则需要写多少个table-->
        <table tableName="invitation" domainObjectName="Invitation" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
 </context>  
</generatorConfiguration>  

mybaits核心配置文件

<?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>
	<!-- 数据库环境 -->
	<environments default="mysqlEnv">
		<!-- mysql -->
		<environment id="mysqlEnv">
			<!-- 事务管理 -->
			<transactionManager type="JDBC"/>
			<!-- 连接信息 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url"
					value="jdbc:mysql://localhost:3306/testv4?useUnicode=true&amp;characterEncoding=UTF-8&amp;allowMultiQueries=true" />
				<property name="username" value="root" />
				<property name="password" value="root" />
				<property name="poolMaximumActiveConnections" value="20" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- 关联sql映射 -->
	<mappers>
		<mapper resource="mapper/InvitationMapper.xml"/>
		<mapper resource="mapper/ReplyDetailMapper.xml"/>
	</mappers>
	

</configuration>

日志配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="true">
    <property name="contextName" value="sys_log"/><!--日志应用名称-->
    <property name="logPath" value="E:/"/><!--日志根路径-->
    <contextName>${contextName}</contextName>
    <property name="LOG_HOME" value="${logPath}/${contextName}"/>
    <property name="LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} %X{reqId} %X{serverIp} %X{serverName} %-5level %logger{100} - %msg%n"/>
    <appender name="mysqllog"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${LOG_HOME}/mysql.log</File>
        <encoder>
            <pattern>
                %d %p (%file:%line\)- %m%n
            </pattern>
            <charset>UTF-8</charset>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/mysql.log.%d.%i</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>64 MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
    </appender>
    <!--配置SQL输出-->
    <logger name="com.accp.myweb" level="DEBUG" additivity="false">
        <appender-ref ref="mysqllog" />
        <appender-ref ref="STDOUT" />
    </logger>

    <root level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

配置了org.mybatis.generator 插件后,能在maven工具栏中的plugins 下能看到该插件,运行后插件会根据数据表结构进行创建代码
在这里插入图片描述

在这里插入图片描述
这样就生成了基本的实体类,CRUD方法
在这里插入图片描述

外链接多表查询

<!-- InvWithReplyMap 方法名 
	Invitation 对象
	replyDetailList 为 Invitation对象中的一个 ReplyDetail 对象集合
 -->
 <resultMap id="InvWithReplyMap" type="Invitation" autoMapping="true">
      <id column="iid" property="id"></id>
      <collection property="replyDetailList" column="id" autoMapping="true">
        <id column="rid" property="id"></id>
      </collection>
    </resultMap>
      <select id="selectInvitationWithReplyDetail" resultMap="InvWithReplyMap">
        select
               i.id iid,i.title ,i.summary ,i.author,i.createdate
                r.id rid,r.invid ,r.content ,r.author

        from Invitation i left join reply_detail r on i.id = r.invid

      </select>

代理模式

组成结构:
客户对象,公共接口,代理对象,委托对象
在这里插入图片描述
例如:
案例分析:

李氏家族有N种户型M套豪宅,他们出租豪宅时总是被客户询问相同的问题,如:豪宅什么户型多少钱一个月,要签订什么合同等等。每次都要不厌其烦的回答。于是,他们想请中介公司帮忙代理租房事宜。
⚠️ 在这个案例中 “李氏家族”则是委托类,中介是代理类,租房的顾客是客户类,而有关房屋租赁的一切例如合同,房源信息情况等都是这个公共接口,这三个类都需要实现这个公共接口

静态代理写法

# 公共接口
public interface ProxyInterface {
	public void method1();
}
# 委托类
public class Target implements ProxyInterface {
	@Override
	public void method1() {
		// 省略一万行
		System.out.println("定制逻辑A......");
	}
}
# 代理类
public class MyProxy implements ProxyInterface {
	
	private Target target;//强关联,组合关系
	
	public MyProxy(Target target) {
		this.target=target;
	}
	@Override
	public void method1() {
		System.out.println("通用逻辑1");
		target.method1();
		System.out.println("通用逻辑2");
	}
}
## 调用
	public static void main(String[] args) {
		// 4.
		// 静态代理
		 ProxyInterface pi=new MyProxy(new Target());
		pi.method1();
	}

利用java 的反射机制实现实现的动态代理

// 1. 公共接口
public interface ProxyInterface {
	public void method1();
}
//2. 委托类 需要实现公共接口
public class Target implements ProxyInterface {

	@Override
	public void method1() {
		
		// 省略一万行
		System.out.println("定制逻辑A......");
		

	}
//3.代理模版类 需要实现java.lang.reflect.InvocationHandler 接口;
public class MyHandler implements InvocationHandler {
	private Object target;
	public MyHandler(Object target) {
		this.target=target;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("通用逻辑1");
		Object returnVal=method.invoke(target, args);
		System.out.println("通用逻辑2");
		return returnVal;
	}
}
	public static void main(String[] args) {
		// 4.
		// 动态代理
		//Target 委托类,MyHandler 为 代理模版类
		Target target = new Target();
		// 必须向下转型接口类型
		ProxyInterface pi = (ProxyInterface) Proxy.newProxyInstance(target.getClass().getClassLoader(),
				target.getClass().getInterfaces(), new MyHandler(target));
		pi.method1();
	}

利用cglib 框架实现动态代理

## 代理工具类,万能代理类
@SuppressWarnings("all")
public class CgLibTransProxyUtil {

	private CgLibTransProxyUtil() {}

	public static <T> T getTransProxyObject(Class superClass) {
		// 1.利用字节码技术动态创建代理对象
		Enhancer enhancer = new Enhancer();
		// 2.设置父类
		enhancer.setSuperclass(superClass);
		// 3.设置回调函数【规则】【非常重要】
		enhancer.setCallback(new TransCallBack());
		// 4.创建对象
		return (T) enhancer.create();
	}
}
## 代理模版类 
public class TransCallBack implements MethodInterceptor {

	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy mp) throws Throwable {
		Object returnVal = null;
		try {
			returnVal = mp.invokeSuper(proxy, args);// 委托对象的方法
			// 以add 或者 remove 或者modify开头的方法将会开启事务
			if (method.getName().startsWith("add") || method.getName().startsWith("remove")
					|| method.getName().startsWith("modify")) {
				SqlSessionUtil.commit();
			}
		} catch (Exception ex) {
			LoggerUtil.error("事务提交失败", ex);
			SqlSessionUtil.rollback();
			throw new RuntimeException(ex.getCause());
		} finally {
			SqlSessionUtil.closeSession();
		}
		return returnVal;
	}

}
//调用类
@Test
	public void testProxyObject() throws Exception {
		PersonBiz biz=CgLibTransProxyUtil.getTransProxyObject(PersonBiz.class);
		biz.findPersonList().forEach(temp->{
			System.out.println(temp);
		});
		
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值