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

来源:转载

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 + ",hljs-keyword">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(); }}

分享给朋友:
您可能感兴趣的文章:
随机阅读: