首先,我这里用的是创建的 maven 项目,所以要导入以下依赖(pom.xml):
<dependencies>
<!--测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- MyBatis核心Jar包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- MySql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- Lombok工具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<!-- Spring核心-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
</dependency>
<!-- Spring-test测试-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.20</version>
</dependency>
<!-- slf4j日志包-->
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- druid数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.11</version>
</dependency>
<!-- Spring整合ORM-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.3.20</version>
</dependency>
<!-- Spring整合MyBatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
</dependencies>
接下来是创建的一些需要的静态资源文件(步骤1):
我的工程目录结构如下(本文是以dynamic_D 为例):
1) jdbc.properties(我这里使用的是mysql 8以上的版本配置)
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url= jdbc:mysql://localhost:3306/esms(要连接的数据库名称)?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
jdbc.username=root(自己的数据库登录名)
jdbc.password=XXXX(自己的数据库链接密码)
2)log4j.properties(需要以下这些已经足够)
log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
3)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>
<settings>
<!-- 设置启用懒加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 设置启用缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration>
4)spring-config.xml(这里引入了context 的命名空间)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--导入jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties" file-encoding="UTF-8"/>
<!--设置扫描的包路径名:扫描@Component注解-->
<context:component-scan base-package="com.czh.dynamic_D"/>
<!--配置druid数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置SqlSessionFactoryBean(MyBatis)-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.czh.dynamic_D.entity"/>
<property name="configLocation" value="classpath:mybatis.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.czh.dynamic_D.mapper"/>
</bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
</beans>
接下来是根据自己的需求创建实体类(Manager),对数据库进行操作的接口(MamagerMapper)和该接口的实现类(ManagerMapperImpl),然后就是创建一个代理工厂类 (ObjectProxyFactory) 实现动态生成代理对象。(步骤2):
1)创建实体类(Manager)
package com.czh.dynamic_D.entity;
import lombok.Data;
import java.io.Serializable;
@Data
public class Manager implements Serializable {
private Integer id;
private String name;
private String password;
private String rname;
private String sex;
private Integer age;
private String tel;
}
2)创建接口(ManagerMapper)以下的操作按照需求自己操作
package com.czh.dynamic_D.mapper;
import com.czh.dynamic_D.entity.Manager;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface ManagerMapper {
@Select("select * from t_manager")
@Results(id = "managerMap",value = {
@Result(property = "id" ,column = "id",id = true),
@Result(property = "rname",column = "realname")
})
List<Manager> selectAll();
@Select("select * from t_manager where name=#{name}")
@ResultMap("managerMap")
Manager selectOneManager(@Param("name") String name);
@Insert("insert into t_manager values(null,#{name},#{password},#{rname},#{sex},#{age},null,#{tel},default,1,1,2)")
Integer insertManager(Manager manager);
@Update("update t_manager set name=#{name},password=#{password},realname=#{rname},sex=#{sex},tel=#{tel} where id=#{id}")
Integer updateManagerTwo(Manager manager);
@Delete("delete from t_manager where id = #{id}")
Integer deleteManager(Integer id);
}
3)创建接口的实现类(ManagerMapperImpl)
package com.czh.dynamic_D.mapper.impl;
import com.czh.dynamic_D.entity.Manager;
import com.czh.dynamic_D.mapper.ManagerMapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository("managerMapperImpl")
public class ManagerMapperImpl implements ManagerMapper {
@Autowired
@Qualifier("sqlSessionTemplate")
SqlSessionTemplate sst;
@Override
public List<Manager> selectAll() {
return sst.selectList("com.czh.dynamic_D.mapper.ManagerMapper.selectAll");
}
@Override
public Manager selectOneManager(String name) {
return sst.selectOne("com.czh.dynamic_D.mapper.ManagerMapper.selectOneManager",name);
}
@Override
public Integer insertManager(Manager manager) {
return sst.insert("com.czh.dynamic_D.mapper.ManagerMapper.insertManager",manager);
}
@Override
public Integer updateManagerTwo(Manager manager) {
return sst.update("com.czh.dynamic_D.mapper.ManagerMapper.updateManagerTwo",manager);
}
@Override
public Integer deleteManager(Integer id) {
return sst.delete("com.czh.dynamic_D.mapper.ManagerMapper.deleteManager",id);
}
}
4)创建代理工厂类(ObjectProxyFactory)
package com.czh.dynamic_D.porxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Date;
public class ObjectProxyFactory {
public static <T>T createProxy(T t){
return (T)Proxy.newProxyInstance(t.getClass().getClassLoader(),t.getClass().getInterfaces(),new THandler(t));
}
private static class THandler<T> implements InvocationHandler {
private T t;
public THandler(T t) {
this.t = t;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("==============="+method.getName()+"===============");
long time = new Date().getTime();
Object invoke = method.invoke(t, args);
long time1 = new Date().getTime();
System.out.println("参数:"+ Arrays.toString(args));
System.out.println("结果:\n"+invoke);
System.out.println(method.getName()+"()用时:"+(time1-time));
return invoke;
}
}
}
最后就是运行测试了(步骤3):
创建一个测试类(必需依赖:spring-context,spring-test):
package com.czh.dynamic_D.porxy;
import com.czh.dynamic_D.entity.Manager;
import com.czh.dynamic_D.mapper.ManagerMapper;
import com.czh.dynamic_D.mapper.impl.ManagerMapperImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration("classpath:spring-config.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class ObjectProxyFactoryTest {
@Qualifier("managerMapperImpl")
@Autowired
private ManagerMapper mapper;
@Test
public void test1(){
ManagerMapper proxy = ObjectProxyFactory.createProxy(mapper);
proxy.selectAll();
proxy.selectOneManager("list");
Manager m = new Manager();
m.setName("葫芦侠客");
m.setAge(23);
m.setPassword("123qwe");
m.setRname("胡图图One");
m.setSex("男");
m.setTel("18767789980");
proxy.insertManager(m);
Manager mana1 = proxy.selectOneManager("葫芦侠客");
mana1.setPassword("123456");
mana1.setRname("Java初学者");
proxy.updateManagerTwo(mana1);
}
}
运行结果:
"C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\Users\admin\IntelliJ IDEA 2022.1.3\lib\idea_rt.jar=11894:D:\Users\admin\IntelliJ IDEA 2022.1.3\bin" -Dfile.encoding=UTF-8 -classpath "D:\Users\admin\IntelliJ IDEA 2022.1.3\lib\idea_rt.jar;D:\Users\admin\IntelliJ IDEA 2022.1.3\plugins\junit\lib\junit5-rt.jar;D:\Users\admin\IntelliJ IDEA 2022.1.3\plugins\junit\lib\junit-rt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\rt.jar;D:\homework\SpringStudy\spring-0722\target\test-classes;D:\homework\SpringStudy\spring-0722\target\classes;D:\Users\admin\apache-maven-3.8.1\repository\junit\junit\4.13.2\junit-4.13.2.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;D:\Users\admin\apache-maven-3.8.1\repository\cglib\cglib\3.3.0\cglib-3.3.0.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\ow2\asm\asm\7.1\asm-7.1.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\mybatis\mybatis\3.5.9\mybatis-3.5.9.jar;D:\Users\admin\apache-maven-3.8.1\repository\mysql\mysql-connector-java\8.0.27\mysql-connector-java-8.0.27.jar;D:\Users\admin\apache-maven-3.8.1\repository\com\google\protobuf\protobuf-java\3.11.4\protobuf-java-3.11.4.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\projectlombok\lombok\1.18.24\lombok-1.18.24.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\springframework\spring-context\5.3.20\spring-context-5.3.20.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\springframework\spring-aop\5.3.20\spring-aop-5.3.20.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\springframework\spring-beans\5.3.20\spring-beans-5.3.20.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\springframework\spring-core\5.3.20\spring-core-5.3.20.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\springframework\spring-jcl\5.3.20\spring-jcl-5.3.20.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\springframework\spring-expression\5.3.20\spring-expression-5.3.20.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\springframework\spring-test\5.3.20\spring-test-5.3.20.jar;D:\Users\admin\apache-maven-3.8.1\repository\log4j\log4j\1.2.17\log4j-1.2.17.jar;D:\Users\admin\apache-maven-3.8.1\repository\com\alibaba\druid\1.2.11\druid-1.2.11.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\springframework\spring-orm\5.3.20\spring-orm-5.3.20.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\springframework\spring-jdbc\5.3.20\spring-jdbc-5.3.20.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\springframework\spring-tx\5.3.20\spring-tx-5.3.20.jar;D:\Users\admin\apache-maven-3.8.1\repository\org\mybatis\mybatis-spring\2.0.7\mybatis-spring-2.0.7.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.czh.dynamic_D.porxy.ObjectProxyFactoryTest,test1
七月 24, 2022 7:55:31 下午 org.springframework.test.context.support.AbstractTestContextBootstrapper getDefaultTestExecutionListenerClassNames
信息: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.event.ApplicationEventsTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.test.context.event.EventPublishingTestExecutionListener]
七月 24, 2022 7:55:31 下午 org.springframework.test.context.support.AbstractTestContextBootstrapper getTestExecutionListeners
信息: Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@5025a98f, org.springframework.test.context.event.ApplicationEventsTestExecutionListener@49993335, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@20322d26, org.springframework.test.context.support.DirtiesContextTestExecutionListener@192b07fd, org.springframework.test.context.transaction.TransactionalTestExecutionListener@64bfbc86, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@64bf3bbf, org.springframework.test.context.event.EventPublishingTestExecutionListener@55d56113]
===============selectAll===============
INFO 2022-07-24 19:55:33,200 com.alibaba.druid.pool.DruidDataSource: {dataSource-1} inited
参数:null
结果:
[Manager(id=1, name=admin, password=123456, rname=超级管理员, sex=无, age=100, tel=111099898), Manager(id=2, name=list, password=123456, rname=李四, sex=男, age=18, tel=12246779988), Manager(id=3, name=mary, password=123qwe, rname=玛丽亚。。, sex=男, age=21, tel=13566567876), Manager(id=4, name=lis, password=666666, rname=阿贾克斯One, sex=女, age=null, tel=17767879908), Manager(id=5, name=102, password=666666, rname=特斯拉.。。, sex=男, age=null, tel=13455456545), Manager(id=6, name=103, password=666666, rname=电大大师傅大师傅, sex=男, age=null, tel=13455456545), Manager(id=7, name=葫芦侠, password=123456, rname=胡图图, sex=男, age=23, tel=18767789980)]
selectAll()用时:526
===============selectOneManager===============
参数:[list]
结果:
Manager(id=2, name=list, password=123456, rname=李四, sex=男, age=18, tel=12246779988)
selectOneManager()用时:4
===============selectOneManager===============
参数:[葫芦侠]
结果:
Manager(id=7, name=葫芦侠, password=123456, rname=胡图图, sex=男, age=23, tel=18767789980)
selectOneManager()用时:3
===============updateManagerTwo===============
参数:[Manager(id=7, name=葫芦侠, password=123456, rname=胡图图, sex=男, age=23, tel=18767789980)]
结果:
1
updateManagerTwo()用时:2
INFO 2022-07-24 19:55:33,549 com.alibaba.druid.pool.DruidDataSource: {dataSource-1} closing ...
INFO 2022-07-24 19:55:33,562 com.alibaba.druid.pool.DruidDataSource: {dataSource-1} closed
Process finished with exit code 0
总结:这是我的第一篇笔记,还存在许多不足希望得到大家的指正,可用作参考,互相学习,谢谢!!