11.2 注解的使用
@select
、@insert
、@update
和@delete
可以完成常见的CRUD
(增删改査)SQL
语句映射。
示例:测试 select,insert,update和delete操作
项目搭建
展开/折叠
G:\workspace_web2\MyADMLTest
├─src\
│ ├─db.properties
│ ├─domain\
│ │ └─User.java
│ ├─fractory\
│ │ └─SqlSessionFactoryTools.java
│ ├─log4j.xml
│ ├─mapper\
│ │ └─UserMapper.java
│ ├─mybatis-config.xml
│ ├─tb_user.sql
│ └─test\
│ ├─DeleteTest.java
│ ├─InsertUserTest.java
│ ├─SelectAllUser.java
│ ├─SelectUserByIdTest.java
│ └─UpdateUserTest.java
└─WebContent\
├─META-INF\
│ └─MANIFEST.MF
└─WEB-INF\
└─lib\
├─ant-1.9.6.jar
├─ant-launcher-1.9.6.jar
├─asm-5.2.jar
├─cglib-3.2.5.jar
├─commons-logging-1.2.jar
├─javassist-3.22.0-CR2.jar
├─log4j-1.2.17.jar
├─log4j-api-2.3.jar
├─log4j-core-2.3.jar
├─mybatis-3.4.5.jar
├─mysql-connector-java-5.1.44-bin.jar
├─ognl-3.1.15.jar
├─slf4j-api-1.7.25.jar
└─slf4j-log4j12-1.7.25.jar
数据库表
/MyADMLTest/src/tb_user.sql1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `tb_user`; CREATE TABLE `tb_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(18) DEFAULT NULL, `sex` char(2) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `tb_user` VALUES ('1', '小明', '男', '21'); INSERT INTO `tb_user` VALUES ('2', '小王', '男', '22'); INSERT INTO `tb_user` VALUES ('3', '小丽', '女', '18'); INSERT INTO `tb_user` VALUES ('4', '小芳', '女', '18'); INSERT INTO `tb_user` VALUES ('5', '小王', '男', '22'); SET FOREIGN_KEY_CHECKS = 1;
|
持久化对象
/MyADMLTest/src/domain/User.java1 2 3 4 5 6 7 8 9 10
| package domain; public class User { private Integer id; private String name; private String sex; private Integer age; }
|
mapper接口
/MyADMLTest/src/mapper/UserMapper.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package mapper; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import domain.User; public interface UserMapper { @Select("select * from tb_user where id=#{id}") @Results({ @Result(column = "id", property = "id", id = true), @Result(column = "name", property = "name"), @Result(column = "sex", property = "sex"), @Result(column = "age", property = "age") }) User selectUserById(Integer id); @Select("select * from tb_user where id=#{id}") User selectUserById2(Integer id); }
|
mybatis-cofig.xml
/MyADMLTest/src/mybatis-config.xml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <?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> <properties resource="db.properties"/> <settings> <setting name="logImpl" value="log4j"/> </settings> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"/> <dataSource type="pooled"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <mapper class="mapper.UserMapper"/> </mappers> </configuration>
|
数据库信息配置文件db.properties
/MyADMLTest/src/db.properties1 2 3 4 5 6
|
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis username=root password=root
|
log4j.xml
/MyADMLTest/src/log4j.xml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration PUBLIC "-//LOG4J//DTD LOG4J//EN" "https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd" >
<log4j:configuration> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%5p [%t] %m%n"/> </layout> </appender> <logger name="domain.User"> <level value="DEBUG"/> </logger> <root> <level value="ERROR"/> <appender-ref ref="STDOUT"/> </root> </log4j:configuration>
|
工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package fractory;
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.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class SqlSessionFactoryTools { private static SqlSessionFactory sqlSessionFactory = null; static { try { InputStream mybatisConfigXML = Resources.getResourceAsStream("mybatis-config.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(mybatisConfigXML); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession getSqlSession() { return sqlSessionFactory.openSession(); } }
|
测试select功能
SelectUserByIdTest.java
/MyADMLTest/src/test/SelectUserByIdTest.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package test; import org.apache.ibatis.session.SqlSession; import domain.User; import fractory.SqlSessionFactoryTools; import mapper.UserMapper; public class SelectUserByIdTest { public static void main(String[] args) { SqlSession sqlSession = null; sqlSession = SqlSessionFactoryTools.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.selectUserById(1); System.out.println("-----------------------------------------"); System.out.println(user); sqlSession.close(); } }
|
运行结果:
1 2 3 4 5
| DEBUG [main] ==> Preparing: select * from tb_user where id=? DEBUG [main] ==> Parameters: 1(Integer) DEBUG [main] <== Total: 1 ----------------------------------------- User [id=1, name=小明, sex=男, age=21]
|
调用selectUserById
方法,会执行@Select
注解中的SQL
语句。
数据表列名和持久化对象属性名相同的情况
@Result
注解用于列和属性之间的结果映射,如果列和属性名称相同,则可以省略@Result
注解,MyBatis
会自动进行映射。
我的持久化类的属性名和数据表的列名完全一致,则上面的查询方法可以写成如下形式:
G:\workspace_web2\MyADMLTest\src\mapper\UserMapper.java1 2
| @Select("select * from tb_user where id=#{id}") User selectUserById2(Integer id);
|
测试:
G:\workspace_web2\MyADMLTest\src\test\SelectUserByIdTest.java1 2 3 4 5 6 7 8 9 10
| public static void main(String[] args) { SqlSession sqlSession = null; sqlSession = SqlSessionFactoryTools.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.selectUserById2(1); System.out.println("-----------------------------------------"); System.out.println(user); sqlSession.close(); }
|
运行结果:
1 2 3 4 5
| DEBUG [main] ==> Preparing: select * from tb_user where id=? DEBUG [main] ==> Parameters: 1(Integer) DEBUG [main] <== Total: 1 ----------------------------------------- User [id=1, name=小明, sex=男, age=21]
|
可以看到运行结果与上面的完全一致。
测试insert
mapper接口方法
在mapper
接口中添加如下方法:
1 2 3 4 5
| @Insert("insert into tb_user(name,sex,age) values(#{name},#{sex},#{age})")
@Options(useGeneratedKeys = true, keyProperty = "id") void insertUser(User user);
|
InsertUserTest.java
G:\workspace_web2\MyADMLTest\src\test\InsertUserTest.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package test; import org.apache.ibatis.session.SqlSession; import domain.User; import fractory.SqlSessionFactoryTools; import mapper.UserMapper; public class InsertUserTest { public static void main(String[] args) { SqlSession sqlSession = null; sqlSession = SqlSessionFactoryTools.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User("小张", "男", 22); System.out.println("插入数据库之前:" + user); System.out.println("--------------------------------------------------"); userMapper.insertUser(user); System.out.println("--------------------------------------------------"); System.out.println("插入数据库之后:" + user); sqlSession.commit(); sqlSession.close(); } }
|
运行结果:
1 2 3 4 5 6 7
| 插入数据库之前:User [id=null, name=小张, sex=男, age=22] -------------------------------------------------- DEBUG [main] ==> Preparing: insert into tb_user(name,sex,age) values(?,?,?) DEBUG [main] ==> Parameters: 小张(String), 男(String), 22(Integer) DEBUG [main] <== Updates: 1 -------------------------------------------------- 插入数据库之后:User [id=6, name=小张, sex=男, age=22]
|
调用insertUser
方法,会执行@insert
注解中的SQL
语句。需要注意的是,insertUser
方法还使用了@Options
注解,@Options
注解的属性
useGeneratedKeys=true
表示使用数据库自动增长的主键,该操作需要底层数据库的支持。
keyProperty="id"
表示把插入数据时数据库生成的主键设置到user
对象的id变量之中。
测试update
在UserMapper
接口中添加如下方法:
G:\workspace_web2\MyADMLTest\src\mapper\UserMapper.java1 2
| @Update("update tb_user set name=#{name},sex=#{sex},age=#{age} where id=#{id}") void updateUser(User user);
|
UpdateUserTest.java
G:\workspace_web2\MyADMLTest\src\test\UpdateUserTest.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package test;
import org.apache.ibatis.session.SqlSession; import domain.User; import fractory.SqlSessionFactoryTools; import mapper.UserMapper;
public class UpdateUserTest { public static void main(String[] args) { SqlSession sqlSession = null; try { sqlSession = SqlSessionFactoryTools.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.selectUserById(6); if (user != null) { System.out.println("更新之前的用户信息:" + user); User user1 = new User(user.getId(), "老张头", "男", 88); userMapper.updateUser(user1); user = userMapper.selectUserById(6); System.out.println("更新之后的用户信息:" + user); sqlSession.commit(); } } catch (Exception e) { e.printStackTrace(); sqlSession.rollback(); } finally { if (sqlSession != null) { sqlSession.close(); } } } }
|
运行结果:
1 2 3 4 5 6 7 8 9 10 11
| DEBUG [main] ==> Preparing: select * from tb_user where id=? DEBUG [main] ==> Parameters: 6(Integer) DEBUG [main] <== Total: 1 更新之前的用户信息:User [id=6, name=小张, sex=男, age=22] DEBUG [main] ==> Preparing: update tb_user set name=?,sex=?,age=? where id=? DEBUG [main] ==> Parameters: 老张头(String), 男(String), 88(Integer), 6(Integer) DEBUG [main] <== Updates: 1 DEBUG [main] ==> Preparing: select * from tb_user where id=? DEBUG [main] ==> Parameters: 6(Integer) DEBUG [main] <== Total: 1 更新之前的用户信息:User [id=6, name=老张头, sex=男, age=88]
|
测试delete
mapper接口方法
G:\workspace_web2\MyADMLTest\src\mapper\UserMapper.java1 2
| @Delete("delete from tb_user where id=#{id}") void deleteUserById(@Param("id") Integer id);
|
调用deleteUser
方法,会执行@Delete
注解中的SQL
语句。deleteUser
方法参数前面的@Param("id")
注解表示给该注解后面的变量取一个参数名称,对应@Delete
注解中的#{id}
。如果没有使用Param
注解,则参数将会以它们的顺序位置来和SQL
语句中的表达式进行映射。
DeleteTest.java
G:\workspace_web2\MyADMLTest\src\test\DeleteTest.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package test;
import org.apache.ibatis.session.SqlSession; import domain.User; import fractory.SqlSessionFactoryTools; import mapper.UserMapper;
public class DeleteTest { public static void main(String[] args) { SqlSession sqlSession = null; try { sqlSession = SqlSessionFactoryTools.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.selectUserById(5); if (user != null) { System.out.println("即将删除记录:" + user); userMapper.deleteUserById(user.getId()); } sqlSession.commit(); } catch (Exception e) { sqlSession.rollback(); e.printStackTrace(); } finally { sqlSession.close(); } } }
|
运行效果:
1 2 3 4 5 6 7
| DEBUG [main] ==> Preparing: select * from tb_user where id=? DEBUG [main] ==> Parameters: 5(Integer) DEBUG [main] <== Total: 1 即将删除记录:User [id=5, name=小王, sex=男, age=22] DEBUG [main] ==> Preparing: delete from tb_user where id=? DEBUG [main] ==> Parameters: 5(Integer) DEBUG [main] <== Updates: 1
|
全部查询
mapper接口方法
1 2
| @Select("select * from tb_user") List<User> seleteAllUser();
|
SelectAllUser.java
/MyADMLTest/src/test/SelectAllUser.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package test; import java.util.List; import org.apache.ibatis.session.SqlSession; import domain.User; import fractory.SqlSessionFactoryTools; import mapper.UserMapper; public class SelectAllUser { public static void main(String[] args) { SqlSession sqlSession = null; sqlSession = SqlSessionFactoryTools.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<User> users = userMapper.seleteAllUser(); users.forEach(user -> System.out.println(" " + user)); sqlSession.close(); } }
|
运行效果:
1 2 3 4 5 6 7 8
| DEBUG [main] ==> Preparing: select * from tb_user DEBUG [main] ==> Parameters: DEBUG [main] <== Total: 5 User [id=1, name=小明, sex=男, age=21] User [id=2, name=小王, sex=男, age=22] User [id=3, name=小丽, sex=女, age=18] User [id=4, name=小芳, sex=女, age=18] User [id=6, name=老张头, sex=男, age=88]
|