实验目的
- 掌握MyBaits动态代理的使用
 - log4j日志的使用
 - Lombk的使用
 - 单元测试的使用
 - SqlSessionFactory单例模式
 - 预处理语句的使用
 
实验内容
完成学生表的增删改查,学生表信息如下
CREATE TABLE tb_student(  sno  INT AUTO_INCREMENT PRIMARY KEY,  student_name VARCHAR(20) NULL,  student_age  INT         NULL  
);
 
实验步骤
- log4j日志文件的配置与使用
在pom文件中添加下述坐标,获取log4j依赖包 
<dependency>  <groupId>log4j</groupId>  <artifactId>log4j</artifactId>  <version>1.2.16</version>  
</dependency>  
 
在resources目录下添加配置文件log4j.properties,其代码如下
# log4j的全局配置  
log4j.rootLogger=ERROR, stdout  
# MyBatis日志配置 
log4j.logger.com.bjwl=DEBUG  
# 控制台输出格式  
log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n 
 
在mybaits的主配文件中,添加日志的配置,代码如下
<settings>    ...  <!--配置SQL输出文件-->  <setting name="logImpl" value="LOG4J" />  
</settings>  
 
- Lombok的配置与使用
Lombok项目是一个java库,它可以自动插入到编辑器和构建工具中,增强java的性能。不需要再写getter、setter或equals方法,只要有一个注解,就有一个功能齐全的构建器、自动记录变量等。使用Maven坐标导入使用Lombok的依赖包,坐标如下。 
<dependency>  <groupId>org.projectlombok</groupId>  <artifactId>lombok</artifactId>  <version>1.18.24</version>  <scope>compile</scope>  
</dependency>
 
编写实体类时,只需要在类上加@Data注解符,即可,无需程序员编写getter和setter代码,示例代码如下。
@Data  
public class Student {  private Integer sno;  private String studentName;  private Integer studentAge;  
} 
 
- 单元测试junit的使用
使用单元测试工具junit,在pom文件中,增加以下maven坐标,完成依赖包的导入后,在类的方法上加注解夫@test,就可以进行运行测试。maven坐标如下所示 
    <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency>
 
- SqlSessionFactory单例模式
在myBatis框架的使用中,每次执行持久化化访问操作时,需要读入主配文件创建sqlSessionFactory实例,可以将其中共用部分提取到一个公用类,实现复用。由于SqlSessionFactory可以被多个线程共享,避免资源浪费,应该保证SqlSessionFactory的在一个系统中仅有一个实例,其代码如下 
public class BatisUtils {  private static SqlSessionFactory sqlSessionFactory;  private BatisUtils() {};  public static synchronized SqlSessionFactory getSqlSessionFactory() throws IOException {  if (sqlSessionFactory == null) {  InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");  sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  }  return sqlSessionFactory;  }  
}
 
- 定义持久化接口StudentDao ,代码如下:
 
  public interface StudentDao {  List<StudentPOJO> getAllStudent();  int addStudent(StudentPOJO student);  int updateStudent(StudentPOJO student);  int deleteStudent(Integer sno);  }   
 
- 不使用动态代理时,需要开发人员编写持久化接口的实现类,代码如下。
 
 public class StudentDaoImpl implements StudentDao {  private SqlSessionFactory factory;  public StudentDaoImpl(SqlSessionFactory factory) {  this.factory = factory;  }  @Override  public List<Student> getAllStudent() {  SqlSession sqlSession = factory.openSession();  List<Student> students = sqlSession.selectList("com.bjwl.dao.StudentDao.getAllStudent");  return students;  }  @Override  public int addStudent(Student student) {  SqlSession sqlSession = factory.openSession();  Integer flag = sqlSession.insert("com.bjwl.dao.StudentDao.addStudent",student);  sqlSession.commit();  return flag;  }  @Override  public int updateStudent(Student student) {  SqlSession sqlSession = factory.openSession();  Integer flag = sqlSession.update("com.bjwl.dao.StudentDao.updateStudent",student);  sqlSession.commit();  return flag;  }  @Override  public int deleteStudent(Integer sno) {  SqlSession sqlSession = factory.openSession();  Integer flag = sqlSession.delete("com.bjwl.dao.StudentDao.deleteStudent",sno);  sqlSession.commit();  return flag;  }  
} 
 
需要注意的是增加、删除、修改必须使用 sqlSession.commit()提交修改信息,才能将维护信息写入数据库中,编写测试类,代码如下。
//不使用动态代理模式  
public class MyBatisTest0 {  private StudentDao dao;  public MyBatisTest0() throws IOException {  SqlSessionFactory sqlSessionFactory = BatisUtils.getSqlSessionFactory();  this.dao = new StudentDaoImpl(sqlSessionFactory);  }  @Test  public void getAllStudentTest()  {  List<Student> students = dao.getAllStudent();  for (int i = 0; i < students.size(); i++) {  System.out.println(students.get(i).toString());  }  }  @Test  public void addStudentTest() {  Student student = new Student();  student.setStudentName("陆雪琪");  student.setStudentAge(19);  dao.addStudent(student);  }  @Test  public void updateStudentTest()  {  Student student = new Student();  student.setSno(3);  student.setStudentName("黑山老妖");  student.setStudentAge(299);  dao.updateStudent(student);  }  @Test  public void deleteStudentTest()  {  dao.deleteStudent(8);  }  
} 
 
代码中方法上的@Test 注解符,就是使用junit提供的测试功能,运行结果如下图所示。
 
 图中显示的sql语句就是通过log4j在控制台显示的内容
 9. 使用动态代理
 不使用动态代理时,开发人员必须编写每个持久化接口的实现类,分析这些实现类中代码,其执行过程非常相似,如果这部分代码由计算机自动生成,则可大大减轻开发人员的工作量,动态代理方式就是由计算机生成持久化实现类的方式。添加一个测试类MyBatisTest,在此类中直接使用动态代理方式,示例代码如下。
public class MyBaitsTest {  public void getAllStudentTest() throws Exception {  SqlSession session = getSqlSession();  System.out.println(StudentDao.class);  StudentDao dao = session.getMapper(StudentDao.class);  System.out.println(dao.getClass());  List<Student> students = dao.getAllStudent();  for (int i = 0; i < students.size(); i++) {  System.out.println(students.get(i).toString());  }  session.close();  }  private SqlSession getSqlSession() throws IOException {  SqlSessionFactory sqlSessionFactory = BatisUtils.getSqlSessionFactory();  SqlSession session = sqlSessionFactory.openSession();  return session;  }  
} 
 
运行过如下:
 
 由运行图可以看到,通过传入接口com.bjwl.dao.StudentDao,生成的StudentDao 为代理对象,无需开发人员编写接口的实现类。
使用动态代理是使用mybaits框架常用方式,要求必须掌握