一. 编写接口
在以往的操作中,我们的项目的持久层都是以DAO结尾,使用Mybatis后,建议以Mapper结尾,如下图:
二. 编写BookMapper.xml
虽然这么说不太严禁,但是我们可以把BookMapper.xml看做成以往项目中的持久层接口的实现类,也就是BookDaoImpl.java
使用Mybatis后,我们便无需再编写实现类,直接在BookMapper.xml文件中专注于sql语句即可。
<?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="io.zhangjia.mapper.BookMapper"> <insert id="doInsert"> INSERT INTO BOOK (NAME, AUTHOR, PRICE) VALUE (#{name}, #{author}, #{price}); </insert> <delete id="doDelete"> DELETE FROM BOOK WHERE BOOK_ID = #{bookId} </delete> <update id="doUpdate"> UPDATE BOOK SET NAME = #{name}, AUTHOR= #{author}, PRICE = #{price} WHERE BOOK_ID = #{bookId}; </update> <select id="queryById" resultType="io.zhangjia.entity.Book"> SELECT * FROM BOOK WHERE BOOK_ID = #{BOOK_ID}; </select> <select id="queryAll" resultType="io.zhangjia.entity.Book"> SELECT * FROM BOOK; </select> </mapper>
增删改操作和查询不同,没有resultType,但是较老的Mybatis版本中,需要为增删改添加parameterType:
<insert id="doInsert" parameterType="io.zhangjia.entity.Book"> INSERT INTO BOOK (NAME, AUTHOR, PRICE) VALUE (#{name}, #{author}, #{price}); </insert> <delete id="doDelete" parameterType="int"># int代表Integer,如果想使用int,则设置为parameterType="_int" DELETE FROM BOOK WHERE BOOK_ID = #{bookId} </delete> <update id="doUpdate" parameterType="io.zhangjia.entity.Book"> UPDATE BOOK SET NAME = #{name}, AUTHOR= #{author}, PRICE = #{price} WHERE BOOK_ID = #{bookId}; </update> <select id="queryById" resultType="io.zhangjia.entity.Book"> SELECT * FROM BOOK WHERE BOOK_ID = #{BOOK_ID}; </select> <select id="queryAll" resultType="io.zhangjia.entity.Book"> SELECT * FROM BOOK; </select>
可以看到io.zhangjia.entity.Book用到了多次,每次都要写一遍,非常的麻烦,我们便可以为其设置别名:
在mybatis-config.xml文件中添加下面的内容,即可将io.zhangjia.entity.Book的别名设置为book:
<typeAliases> <!-- 设置类型别名,将Book类设置book--> <typeAlias type="io.zhangjia.entity.Book" alias="book" /> </typeAliases>
此时便可以将BookMapper.xml中的io.zhangjia.entity.Book,都替换为book:
<?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="io.zhangjia.mapper.BookMapper"> <insert id="doInsert" parameterType="book"> INSERT INTO BOOK (NAME, AUTHOR, PRICE) VALUE (#{name}, #{author}, #{price}); </insert> <delete id="doDelete" parameterType="int"># int代表Integer,如果想使用int,则设置为parameterType="_int" DELETE FROM BOOK WHERE BOOK_ID = #{bookId} </delete> <update id="doUpdate" parameterType="book"> UPDATE BOOK SET NAME = #{name}, AUTHOR= #{author}, PRICE = #{price} WHERE BOOK_ID = #{bookId}; </update> <select id="queryById" resultType="book"> SELECT * FROM BOOK WHERE BOOK_ID = #{BOOK_ID}; </select> <select id="queryAll" resultType="book"> SELECT * FROM BOOK; </select> </mapper>
另外如果一个包下有多个类,比如entity下有十个类,我们除了采用上面的方式挨个设置外,还可以直接采用下面的方法,一次为所有的类设置别名,别名默认为类名首字母小写,比如Book就是book,User就是user:
<typeAliases> <package name="io.zhangjia.entity"/> </typeAliases>
更多别名简写信息可以查看官方文档:类型别名(typeAliases)
另外如果我们的接口中的抽象方法中的参数是一个Java类,比如Book,那么占位符的设置则必须遵守驼峰命名的规范,如果Book类的name属性修改为userName,那么insert也应该修改为:
<insert id="doInsert" parameterType="book"> INSERT INTO BOOK (NAME, AUTHOR, PRICE) VALUE (#{userName}, #{author}, #{price}); </insert>
如果参数是一个Map,则占位符应该为map的key值。而如果接口中的抽象方法中的参数是简单类型,比如Integer,那么占位符可以设置为任意字符,比如设置为gagagaga
<select id="queryById" resultType="io.zhangjia.entity.Book"> SELECT * FROM BOOK WHERE BOOK_ID = #{gagagaga}; </select>
虽然说这样操作并不会报错,但是并不建议这样做,简单类型的占位符依旧建议遵循相关规范。
三. 编写测试类:
和之前的Oracle操作不同,这里我们在执行DML语句的时候,最后需要手动commit。
(注意:如果不想手动commit,可以将 build.openSession(true)的参数设置为true,则系统会为我们自动提交)
package io.zhangjia.util; import io.zhangjia.mapper.BookMapper; import io.zhangjia.entity.Book; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; import java.util.List; public class Main { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); Book book = new Book(); book.setAuthor("张甲"); book.setName("无名"); book.setPrice(250.0); int i = mapper.doInsert(book); //增 System.out.println("增 = " + i); Book book1 = mapper.queryById(8); //查 System.out.println("book1 = " + book1); book1.setPrice(123.0); int x = mapper.doUpdate(book1);//改 System.out.println("改 = " + x); /* int j = mapper.doDelete(4); //删 System.out.println("删 = " + j); */ sqlSession.commit(); List<Book> books = mapper.queryAll(); for (Book b : books) { System.out.println("b = " + b); } sqlSession.close(); inputStream.close(); } }
四. 解决乱码等问题
在《MyBatis:简单使用》一文中,我们是这样配置的mybatis-config.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> <!-- 开启自动驼峰命名转换为数据库的命名方式,如果不开启,那么bookId将无法获取,一直是nul --> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <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/数据库名"/> <property name="username" value="数据库用户名"/> <property name="password" value="数据库密码"/> </dataSource> </environment> </environments> <mappers> <!-- 如果有路径,需要这样配置: <mapper resource="xxx/xxx/.../BlogMapper.xml"/>--> <mapper resource="xxx/xxx/.../项目名Mapper.xml"/> </mappers> </configuration>
但是上面的配置方式有可能引发乱码等问题,所以我们建议在数据库名后面添加以下配置信息:
<property name="url" value="jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8"/>
其中的&是&字符的转义,除了上面的这种配置方式,我们还可以单独新建一个文件来保存我们的配置信息:
右击src,新建properties文件:
输入文件名:jdbc,点击OK
在新添加的jdbc.properties文件中,添加以下内容:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8 jdbc.username=root jdbc.password=zhangjia
这里的url中的&符不再需要转义,接下来将jdbc.properties导入mybatis-config.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> <!-- 引入jdbc.properties--> <properties resource="jdbc.properties" /> <!-- 开启自动驼峰命名转换为数据库的命名方式,如果不开启,那么bookId将无法获取,一直是nul --> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="BookMapper.xml"/> <!-- 如果不是同级目录,需要这样配置: <mapper resource="xxx/xxx/.../Mapper.xml"/>--> </mappers> </configuration>
五. 使用注解来代替Mapper.xml
Mapper.xml是我们常用的一种方式,除了使用Mapper.xml外,我们还可以使用注解,但是该方法使用的并不多,仅供了解即可。
使用注解可以完全舍弃Mapper.xml文件,直接在接口上添加对应注解即可:
package io.zhangjia.mapper; import io.zhangjia.entity.Book; import org.apache.ibatis.annotations.*; import java.util.List; @Mapper public interface BookMapper { @Update("UPDATE BOOK SET NAME = #{name}, AUTHOR= #{author},PRICE = #{price} WHERE BOOK_ID = #{bookId};") int doUpdate(Book book); @Insert("INSERT INTO BOOK (NAME, AUTHOR, PRICE) VALUE (#{name}, #{author}, #{price})") int doInsert(Book book); @Delete("DELETE FROM BOOK WHERE BOOK_ID = #{bookId}") int doDelete(Integer bookId); @Select("SELECT * FROM BOOK WHERE BOOK_ID = #{BOOK_ID}") Book queryById(Integer bookeId); @Select("SELECT * FROM BOOK") List<Book> queryAll(); }
接下来将mybatis-config.xml文件中的 <mappers>标签替换为以下内容即可:
<mappers> <!-- 方法一--> <mapper class="io.zhangjia.mapper.BookMapper" /> <!-- 方法二--> <package name ="io.zhangjia.mapper" /> </mappers>
请登录之后再进行评论