通过Mybatis实现对单表的增删改查-通过定义一个接口实现

来源:互联网 发布:mysql gbk utf8 区别 编辑:程序博客网 时间:2024/04/29 08:31

Pom.xml文件 定义工程项目依赖的软件库

<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/maven-v4_0_0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>org.vincent</groupId>  <artifactId>mybatisweb</artifactId>  <packaging>war</packaging>  <version>0.0.1-SNAPSHOT</version>  <name>mybatisweb Maven Webapp</name>  <url>http://maven.apache.org</url>  <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>4.10</version>      <scope>test</scope>    </dependency>    <dependency>        <groupId>org.mybatis</groupId>        <artifactId>mybatis</artifactId>        <version>3.4.4</version>    </dependency>    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>        <version>5.1.42</version>    </dependency>  </dependencies>  <build>  <!-- 将mybatisweb项目打包成mybatisweb.war自动部署到tomcat服务器的webapps目录下面 -->    <finalName>mybatisweb</finalName>    <plugins>        <plugin>            <!-- 使用 cargo自动化部署 -->            <groupId>org.codehaus.cargo</groupId>            <artifactId>cargo-maven2-plugin</artifactId>            <version>1.4.12</version> <!-- 不能用1.3.2 不然用maven编译不成功 -->            <configuration>                <container>                    <!-- 指明使用的tomcat服务器版本 -->                    <containerId>tomcat8x</containerId>                     <!--指明tomcat服务器的安装目录 -->                    <home>C:\fastDev\Tomcat\apache-tomcat-8.5.14</home>                                 </container>              <configuration>                <type>existing</type>                 <!--指明tomcat服务器的安装目录 -->                <home>C:\fastDev\Tomcat\apache-tomcat-8.5.14</home>                <properties><cargo.servlet.port>9090</cargo.servlet.port></properties>              </configuration>                        </configuration>            <executions>                <execution>                    <id>cargo-run</id>                    <phase>install</phase>                    <goals>                        <goal>run</goal>                    </goals>                </execution>            </executions>        </plugin>    </plugins>  </build></project>

src/main/resources目录下放置了mybatis的所有配置文件该目录下文件可以直接被java代码引用

为了管理,在src/main/resources目录下新建mybatis目录管理所有mybatis相关的配置信息。

mybatis配置数据源信息

MybatisConfig.xml 在src/main/resources/mybatis目录

<?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>    <!-- 给类设置别名, 在mapper文件中可以使用这个别名,就不用使用那么长的类名了。 -->    <typeAliases>        <typeAlias type="org.vincent.model.Student"        alias="Student"/>    </typeAliases>    <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/javaee" />                <property name="username" value="root" />                <property name="password" value="1557862201" />            </dataSource>        </environment>    </environments>      <mappers>     <!-- 注册SQL映射信息文件,Mapper.xml文件,   Mapper.xml位于src/main/resources/mybatis这个包下,因为src/main/resources/为classpath,所以resource写成mybatis/mappers/Student.xml-->        <mapper resource="mybatis/mappers/Student.xml"/>    </mappers></configuration>

设置项目中POJO类和数据库表的映射关系

Student.xml

<?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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的例如namespace="org.vincent.mapping.Mapper"就是org.vincent.mapping(包名)+Mapper(Mapper.xml文件去除后缀);但是如有需要通过定义一个接口方法定义访问数据库接口方法,那么namespace必须取接口全类名。 --><mapper namespace="org.vincent.model.IStudentOperation">    <!-- 在select标签中编写查询的SQL语句, 设置select标签的id属性为getStudent,id属性值必须是唯一的,不能够重复;    使用parameterType属性指明查询时传递进来使用的参数类型,resultType属性指明查询返回的结果集类型    resultType="org.vincent.domain.Student"就表示将查询结果映射成一个Student类的对象返回    Student类就是student表所对应的实体类    -->    <!--         根据id查询得到一个student对象        org.vincent.model.IStudentOperation.getStudentbyId        id 设置成接口的对应方法名public Student getStudentbyId(int id);        MyBatis会根据结果自动创建一个ResultMap对象,然后基于查找出来的属性名进行键值对封装,         然后再看到返回类型是Student对象,再从ResultMap中取出与Student对象匹配的属性名对应的         键值对进行赋值。        resultType 是     -->    <select id="getStudentbyId" parameterType="int"         resultType="Student"> <!-- 直接使用在Mybatis配置文件中定义的类别名 -->        select * from student where id=#{id}    </select>     <!-- 根据一个id 获取一组记录 -->    <select id="getStudents" parameterType="int"        resultMap="list">            select * from student where id >#{id}     </select>     <!-- Student是设置别名后 的类型;resultMap是为了返回list类型而设置的。被上面的select引用             column 为从数据库查询过来的属性,property属性制定了将从数据库查询过来的属性赋值给对象那个属性。     -->     <resultMap type="Student" id="list">        <id column="id" property="id"/>        <result column="name" property="name"/>        <result column="age" property="age"/>        <result column="address" property="address"/>     </resultMap>     <!-- 插入一条记录 ,     id和parameterType  分别与IUserOperation接口中的insertStudent方法的名字和         参数类型一致。以#{name}的形式引用Student参数的name属性,MyBatis将使用反射读取Student参数         的此属性。#{name}中name大小写敏感。引用其他的gender等属性与此一致。useGeneratedKeys设置         为"true"表明要MyBatis获取由数据库自动生成的主键id;keyProperty="id"指定将获取到的主键值注入         到Student的id属性     -->     <insert id="insertStudent" parameterType="Student" useGeneratedKeys="true" keyProperty="id">        INSERT INTO student(name, age, address) VALUES(#{name}, #{age} ,#{address} )     </insert>     <!-- 更新一条记录 -->     <update id="updateStudent" parameterType="Student" >        update student SET name=#{name} , address=#{address} ,age=#{age} where id=#{id}     </update>     <delete id="deleteStudent" parameterType="int">        delete from student where id =#{id}     </delete></mapper>

POJO 类

package org.vincent.model;/** * 数据库表对应的Java类;POJO对象 * * @ClassName: Student * @Description: TODO(这里用一句话描述这个类的作用) * @author PengRong * @date 2017年6月16日 上午12:35:37 * */public class Student {    private int id;    private String address;    private String name;    private int age;    public int getId() {        return this.id;    }    public void setId(int id) {        this.id = id;    }    public String getAddress() {        return this.address;    }    public void setAddress(String address) {        this.address = address;    }    public String getName() {        return this.name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return this.age;    }    public void setAge(int age) {        this.age = age;    }    @Override    public String toString() {        return "Student [id=" + this.id + ", address=" + this.address                + ", name=" + this.name + ", age=" + this.age + "]";    }}

接口类

package org.vincent.model;import java.util.List;/** * 只有接口没有实现类,用于Mybatis中查询结果 这里的接口方法名必须和Student.xml中select中id属性一致; * 比如getStudentbyId 必须和<select id="getStudentbyId" parameterType="int" * resultType="Student">一致。 不然测试时候报错说不能绑定异常: * org.apache.ibatis.binding.BindingException: Invalid bound statement (not * found): org.vincent.model.IStudentOperation.getStudent at * org.apache.ibatis.binding * .MapperMethod$SqlCommand.<init>(MapperMethod.java:225) at * org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:48) at * org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:65) * at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:58) at * com.sun.proxy.$Proxy2.getStudent(Unknown Source) at * org.vincent.mybatisweb.StudentTest.testMutiStudent(StudentTest.java:69) at * sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at * sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) * at sun.reflect.DelegatingMethodAccessorImpl.invoke( * DelegatingMethodAccessorImpl.java:43) at * java.lang.reflect.Method.invoke(Method.java:498) at * org.junit.runners.model.FrameworkMethod$1 * .runReflectiveCall(FrameworkMethod.java:45) at * org.junit.internal.runners.model * .ReflectiveCallable.run(ReflectiveCallable.java:15) at * org.junit.runners.model * .FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) at * org.junit.internal * .runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at * org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) at * org.junit.runners * .BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) at * org.junit. * runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) at * org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at * org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at * org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at * org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at * org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at * org.junit.runners.ParentRunner.run(ParentRunner.java:300) at * org.eclipse.jdt.internal * .junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at * org.eclipse * .jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at * org.eclipse * .jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner * .java:467) at * org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests( * RemoteTestRunner.java:683) at * org.eclipse.jdt.internal.junit.runner.RemoteTestRunner * .run(RemoteTestRunner.java:390) at * org.eclipse.jdt.internal.junit.runner.RemoteTestRunner * .main(RemoteTestRunner.java:197) * * * * @ClassName: IStudentOperation * @Description: TODO(这里用一句话描述这个类的作用) * @author PengRong * @date 2017年5月16日 上午11:51:04 * */public interface IStudentOperation {    // 查询一个数    public Student getStudentbyId(int id);    // 查询一列数据    public List<Student> getStudents(int id);    // 插入一条记录    public void insertStudent(Student student);    // 更新一条记录    public void updateStudent(Student student);    // 删除一条记录    public void deleteStudent(int id);}

BaseDao

package org.vincent.dao;import java.io.IOException;import java.io.InputStream;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.apache.log4j.Logger;public interface BaseDao {    // 公共的日志记录器和配置文件配置在接口中。    public Logger logger = Logger.getLogger(BaseDao.class);    public String MybatisConfig = "mybatis/MybatisConfig.xml";    // 打开一个Session    default public SqlSession getSession() throws IOException {        InputStream inputStream = null;        inputStream = Resources.getResourceAsStream(BaseDao.MybatisConfig);        return new SqlSessionFactoryBuilder().build(inputStream).openSession();    }    // 关闭一个Session    default public void closeSession(SqlSession session) {        if (session != null) {            session.close();        }    }    // 获取一个日志记录器    default public Logger getLogger() {        return BaseDao.logger;    }}

Student Dao层

package org.vincent.dao;import java.io.IOException;import java.util.List;import java.util.Objects;import org.apache.ibatis.session.SqlSession;import org.vincent.model.IStudentOperation;import org.vincent.model.Student;import com.mysql.jdbc.StringUtils;/** * Student 表的单表增删改查实现,基于接口 * * @ClassName: StudentInterfaceDaoImpl * @Description: TODO(这里用一句话描述这个类的作用) * @author PengRong * @date 2017年7月23日 上午11:46:00 * */public class StudentInterfaceDaoImpl implements BaseDao, IStudentOperation {    private SqlSession session = null;    public StudentInterfaceDaoImpl() {        try {            this.session = this.getSession();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }// 获取到sqlSession    }    /**     * 关闭Session     *      * @Title: closeSession     * @Description: TODO(这里用一句话描述这个方法的作用)     * @param 设定文件     * @return void 返回类型     * @throws     */    public void closeSession() {        this.closeSession(this.session);    }    // 通关id和匹配到Student.xml中对应的select标签执行单表查询;没用通关Mapper接口    public Student queryBySql(String sql, int id) {        Student result = null;        if (!StringUtils.isNullOrEmpty(sql)) {            result = this.session.selectOne(sql, id);        } else {            result = null;        }        return result;    }    /**     * 通过一条记录的id根据IStudentOperation接口方法映射到sql mapper文件中一个select标签;获取到一条记录,     */    @Override    public Student getStudentbyId(int id) {        // TODO Auto-generated method stub        IStudentOperation operation = this.session                .getMapper(IStudentOperation.class);        Student student = operation.getStudentbyId(id);        BaseDao.logger.debug(student);        return student;    }    // 获取到大于指定id的所有记录    @Override    public List<Student> getStudents(int id) {        // TODO Auto-generated method stub        IStudentOperation operation = this.session                .getMapper(IStudentOperation.class);        // ② 通过接口方法获取一组数据库记录        List<Student> list = operation.getStudents(id);        return list;    }    /**     * 根据一个实例student,将对象插入到数据库中。     */    @Override    public void insertStudent(Student student) {        // TODO Auto-generated method stub        IStudentOperation operation = this.session                .getMapper(IStudentOperation.class);        if (Objects.nonNull(student)) {            operation.insertStudent(student);        } else {            //        }    }    /**     * 更新一条记录的相关属性。     */    @Override    public void updateStudent(Student student) {        // TODO Auto-generated method stub        IStudentOperation operation = this.session                .getMapper(IStudentOperation.class);        operation.updateStudent(student);    }    /**     * 删除一条数据记录     */    @Override    public void deleteStudent(int id) {        // TODO Auto-generated method stub        IStudentOperation operation = this.session                .getMapper(IStudentOperation.class);        operation.deleteStudent(id);    }}

单表增删改查测试类

package org.vincent.mybatisweb;import java.io.IOException;import java.util.List;import org.junit.Test;import org.vincent.dao.StudentInterfaceDaoImpl;import org.vincent.model.Student;/* * ORM Mybatis 数据库单表  增 删  改 查操作的单元测试 * @ClassName: StudentTest * @Description: TODO(这里用一句话描述这个类的作用) * @author PengRong * @date 2017年6月16日 上午1:10:46 * */public class StudentSingleTableTest {    /**     * 根据一个sqlStatement获取到一条记录;使用selcetOne 函数,通过     * sqlStatement字符串直接映射为Student中对应的SQL语句去执行查询。     *     * @Title: test     * @Description: TODO(这里用一句话描述这个方法的作用)     * @param @throws IOException 设定文件     * @return void 返回类型     * @throws     */    @Test    public void test() throws IOException {        // sqlStatement是根据Student.xml 这个mapper映射文件中namespace+ select        // 的id=getStudentbyId 唯一确定的sql字符串        String sqlStatement = "org.vincent.model.IStudentOperation.getStudentbyId";        StudentInterfaceDaoImpl studentInterfaceDaoImpl = new StudentInterfaceDaoImpl();        System.out.println((studentInterfaceDaoImpl                .queryBySql(sqlStatement, 61)));        studentInterfaceDaoImpl.closeSession();    }    // 通过Id获取一条记录    @Test    public void getStudentbyIdTest() {        StudentInterfaceDaoImpl studentInterfaceDaoImpl = new StudentInterfaceDaoImpl();        // ① 通过接口方法,查询一条数据库 记录。        studentInterfaceDaoImpl.getStudentbyId(2);        studentInterfaceDaoImpl.closeSession();    }    /**     * 用接口的方式编程。这种方式,要注意的一个地方就是。在Student.xml 的映射配置文件中。 mapper节点的     * namespace="org.vincent.model.IStudentOperation" ,     * 命名空间非常重要,不能有错,必须与我们定义的接口全类名一致。如果不一致就会出错,     *     * @Title: testMutiStudent     * @Description: TODO(通过接口方法获取到数据库数据)     * @param     * @throws IOException     * @return void 返回类型     * @throws     */    @Test    public void getStudentsTest() throws IOException {        StudentInterfaceDaoImpl impl = new StudentInterfaceDaoImpl();        List<Student> list = impl.getStudents(20);        for (Student student : list) {            System.out.println(student);        }        impl.closeSession();    }    /**     * 插入一条数据     *     * @Title: insertStudentTest     * @Description: TODO(这里用一句话描述这个方法的作用)     * @param @throws IOException 设定文件     * @return void 返回类型     * @throws     */    @Test    public void insertStudentTest() throws IOException {        Student student = new Student();        student.setAddress("深圳市罗湖区红岭北");        student.setAge(27);        student.setName("XX00");        StudentInterfaceDaoImpl impl = new StudentInterfaceDaoImpl();        impl.insertStudent(student);        System.out.println(student);// 能获取到数据库生成得id        impl.closeSession();    }    /**     * 通过id查询一条记录对应的对象,然后更改记录对象,最后通过接口方法更新一条记录     *     * @Title: updateStudent     * @Description: TODO(这里用一句话描述这个方法的作用)     * @param     * @throws IOException     * @return void 返回类型     * @throws     */    @Test    public void updateStudent() throws IOException {        StudentInterfaceDaoImpl impl = new StudentInterfaceDaoImpl();        Student student = impl.getStudentbyId(60);        student.setAddress("东莞市长安街");        impl.updateStudent(student);        impl.closeSession();    }    /**     * 通过数据库id, 删除一条记录。     *     * @Title: deleteStudent     * @Description: TODO     * @param @throws IOException 设定文件     * @return void 返回类型     * @throws     */    @Test    public void deleteStudent() throws IOException {        StudentInterfaceDaoImpl dao = new StudentInterfaceDaoImpl();        dao.deleteStudent(59);        dao.closeSession();    }}
阅读全文
0 0
原创粉丝点击