原文网址:http://blog.****.net/sinat_34596644/article/details/61413812
前言:前面我写了《利用JDBC访问MySQL数据库》这篇文章,其中讲述了如何利用Java提供的标准化API屏蔽底层数据库实现并操作数据库的方法,在最后提到了利用JDBC仍旧存在的几个局限性:
- 在应用程序中存在的大量代码冗余。
- 业务代码与数据库访问代码混杂在一起。
- SQL语句与Java代码混杂在一起。
- JDBC抛出费力难懂的checked异常,需要程序员花费精力小心处理。
- 需要程序员自行解决ORM映射。
一、MyBatis是什么?MyBatis有什么特点?
简而言之,MyBatis是一个开源的轻量级持久化框架,与hibernate类似,面向的问题是ORM映射的处理。具有如下的特点:
- 它是一个开源的优秀持久层框架。
- SQL语句与代码分离。
- 面向配置编程(AOP思想)。
- 良好支持复杂数据的映射。
- 采用动态SQL替换了SQL语句的拼装,降低SQL注入的风险,增强了安全性。
二、MyBatis的一个简单示例(Maven工程)
具体如何搭建Maven项目,请参照《用idea创建一个maven web项目》一文。先提供了一下整个项目的目录结构截图
1.建立MySQL数据库,这里我建立了一张名为students的表,用来存储学生信息,建表语句如下:
[sql] view plain copy- <span style="font-size:18px;"> CREATE TABLE `students` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `name` varchar(20) NOT NULL,
- `age` int(11) NOT NULL,
- `gender` varchar(255) DEFAULT NULL,
- `number` varchar(20) DEFAULT NULL,
- `status` int(11) NOT NULL DEFAULT '1',
- PRIMARY KEY (`id`),
- UNIQUE KEY `number` (`number`)
- )</span>
2.在pom.xml中引入MyBatis相关的依赖,因为MyBatis底层运用了JDBC,因此需要导入JDBC的MySQL实现。
[html] view plain copy- <span style="font-size:18px;"><!--mysql的JDBC实现-->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.38</version>
- </dependency>
- <!--mybatis依赖-->
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.4.1</version>
- </dependency></span>
3.接下来编写MyBatis两个重要的配置文件。第一个是MyBatis的全局配置文件,第二个是MyBatis实现SQL语句映射的映射文件。
[html] view plain copy- <span style="font-size:18px;"><?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>
- <!--声明了类的别名-->
- <typeAliases>
- <typeAlias alias="Student" type="cn.edu.jnu.mybatis.model.Student"/>
- </typeAliases>
- <!--mybatis使用的数据库驱动和数据源配置-->
- <environments default="development">
- <environment id="development">
- <transactionManager type="jdbc"/>
- <dataSource type="POOLED">
- <property name="driver" value="com.mysql.jdbc.Driver"/>
- <property name="url" value="jdbc:mysql://localhost:3306/study"/>
- <property name="username" value="登录数据库的用户"/>
- <property name="password" value="登录数据库的密码"/>
- </dataSource>
- </environment>
- </environments>
- <!--指定映射文件的路径-->
- <mappers>
- <mapper resource="mappers/StudentMapper.xml"/>
- </mappers>
- </configuration></span>
[html] view plain copy
- <span style="font-size:18px;"><?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="cn.edu.jnu.mybatis.dao.StudentDAO">
- <!--往students表中插入学生信息-->
- <insert id="insertStudent" parameterType="Student" keyProperty="id" useGeneratedKeys="true">
- insert into students(name,age,gender,number) values(#{name},#{age},#{gender,typeHandler=org.apache.ibatis.type.EnumTypeHandler},#{number})
- </insert>
- <!--根据学号删除相关的学生信息-->
- <delete id="deleteStudentByNumber">
- delete from students where number=#{number}
- </delete>
- <!--根据学号更新相关的学生信息-->
- <update id="updateStudentByNumber" parameterType="Student">
- update students set name=#{name},age=#{age,jdbcType=VARCHAR},gender=#{gender,typeHandler=org.apache.ibatis.type.EnumTypeHandler} where number=#{number}
- </update>
- <!--根据学号查询相关的学生信息-->
- <select id="getStudentByNumber" resultType="Student">
- select * from students where number=#{number}
- </select>
- </mapper></span>
3.至此,最重要的两个步骤就完成了。接下来是一个Model类Student.java,用以承载数据库中的学生信息。一个DAO层的接口StudentDAO.java,用以提供访问数据库的规范。这里顺便把枚举类也贴出来。。
Student.java [java] view plain copy- <span style="font-size:18px;">public class Student {
- //姓名
- private String name;
- //年龄
- private int age;
- //性别
- private GenderEnum gender;
- //学号
- private String number;
- public Student(){
- }
- //setters and getters...
- }</span>
StudentDAO.java。这些方法就是通过映射文件与SQL语句对应起来的! [java] view plain copy
- <span style="font-size:18px;">public interface StudentDAO {
- //增加学生信息
- public void insertStudent(Student student);
- //根据学号删除学生信息
- public void deleteStudentByNumber(String number);
- //根据学号更新学生信息
- public void updateStudentByNumber(Student student);
- //通过学号获取学生信息
- public Student getStudentByNumber(String number);
- }</span>
GenderEnum.java [java] view plain copy
- <span style="font-size:18px;">public enum GenderEnum {
- MALE("男"),
- FEMALE("女");
- private String desc;
- private GenderEnum(String desc) {
- this.desc = desc;
- }
- public String getDesc() {
- return desc;
- }
- }</span>
4.上面讲到的接口方法到SQL语句的映射是MyBatis帮我们完成的,这一步我们需要做的是获取MyBatis暴露给客户端程序员的接口,这样才能驱动MyBatis实际工作。这就涉及到MyBatis中两个重要的类,SqlSessionFactory和SqlSession。
MyBatisUtil.java [java] view plain copy- <span style="font-size:18px;">public class MyBatisUtil {
- private static final SqlSessionFactory sqlSessionFactory;
- static{
- String resource="mybatis-config.xml";
- Reader reader=null;
- try {
- reader=Resources.getResourceAsReader(resource);
- } catch (IOException e) {
- e.printStackTrace();
- }
- sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
- }
- public static SqlSessionFactory getSqlSessionFactory(){
- return sqlSessionFactory;
- }
- }</span>
5.进行实际的测试,下面四个方法可以依次测试。
[java] view plain copy- <span style="font-size:18px;">public class Test {
- private static SqlSessionFactory sqlSessionFactory= MyBatisUtil.getSqlSessionFactory();
- public static void main(String args[]){
- //插入学生信息
- //insertStudent();
- //根据学号删除学生信息
- //deleteStudentByNumber("1960053011");
- //根据学号更新学生信息
- updateStudentByNumber("1960053012");
- //根据学号查询学生信息
- //getStudentByNumber("2013053011");
- }
- public static void getStudentByNumber(String number){
- SqlSession sqlSession=sqlSessionFactory.openSession();
- StudentDAO studentDAO=sqlSession.getMapper(StudentDAO.class);
- Student student=studentDAO.getStudentByNumber(number);
- System.out.println("姓名:"+student.getName());
- System.out.println("年龄:"+student.getAge());
- System.out.println("性别:"+student.getGender());
- System.out.println("学号:"+student.getNumber());
- }
- public static void insertStudent(){
- SqlSession sqlSession=sqlSessionFactory.openSession();
- StudentDAO studentDAO=sqlSession.getMapper(StudentDAO.class);
- Student student=new Student();
- student.setName("赵四");
- student.setAge(60);
- student.setGender(GenderEnum.MALE);
- student.setNumber("1960053011");
- studentDAO.insertStudent(student);
- sqlSession.commit();
- }
- public static void deleteStudentByNumber(String number){
- SqlSession sqlSession=sqlSessionFactory.openSession();
- StudentDAO studentDAO=sqlSession.getMapper(StudentDAO.class);
- studentDAO.deleteStudentByNumber(number);
- sqlSession.commit();
- }
- public static void updateStudentByNumber(String number){
- SqlSession sqlSession=sqlSessionFactory.openSession();
- StudentDAO studentDAO=sqlSession.getMapper(StudentDAO.class);
- Student student=new Student();
- student.setName("刘能");
- student.setAge(60);
- student.setGender(GenderEnum.MALE);
- student.setNumber(number);
- studentDAO.updateStudentByNumber(student);
- sqlSession.commit();
- }
- }</span>