这几年来注解开发越来越流行,MyBatis也可以使用注解开发方式,这样我们就可以减少编写Mapper映射文件了
@Insert: 实现新增 @Update: 实现更新 @Delete: 实现删除 @Select: 实现查询 @Result: 实现结果集封装 @Results: 可以与@Result一起使用,封装多个结果集 @One: 实现一对一结果集封装 @Many: 实现一对多结果集封装
第一步: 在src/main/java目录,右键java目录,新建com.huanf.domain.User类,写入如下
public class User {
private int id;
private String username;
private String password;
private Date birthday;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", birthday=" + birthday +
'}';
}
}
第二步: 在src/main/java目录,右键java目录,新建com.huanf.mapper.UserMapper接口
xxxxxxxxxx
public interface UserMapper {
public void save(User user);
public void update(User user);
public void delete(int id);
public User findById(int id);
public List<User> findAll();
}
第三步: 在src/main/resources目录,右键resources目录,新建File,文件名为jdbc.properties,写入如下
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=228675
第四步: 在src/main/resources目录,右键resources目录,新建File,文件名为log4j.properties,写入如下
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout
第五步: 在src/main/resources目录,右键resources目录,新建File,文件名为sqlMapConfig.xml,写入如下
xxxxxxxxxx
<configuration>
<!--通过properties标签加载外部(resources目录)配置的properties文件-->
<properties resource="jdbc.properties"></properties>
<!--为UserMapper.xml里面的resultType、parameterType属性需要的全限定名,设置别名为user-->
<typeAliases>
<typeAlias type="com.huanf.domain.User" alias="user"></typeAlias>
</typeAliases>
<!--配置数据源环境。default表示默认情况下使用的是哪个环境,例如development,环境名是自定义的-->
<!--transactionManager指的是你要用哪种事务管理器,例如原生JDBC。dataSource指的是你要用哪种数据源,例如连接池POOLED-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<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="com/huanf/mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
第六步: 在src/main/resources目录,右键resources目录,新建Package,包名为com/huanf/mapper,右键com/huanf/mapper,新建File,文件名为UserMapper.xml,写入如下
xxxxxxxxxx
<mapper namespace="com.huanf.mapper.UserMapper">
<!--增-->
<insert id="save" parameterType="user">
insert into user values(#{id},#{username},#{password},#{birthday})
</insert>
<!--改-->
<update id="update" parameterType="user">
update user set username=#{username},password=#{password} where id=#{id}
</update>
<!--删-->
<delete id="delete" parameterType="int">
delete from user where id=#{id}
</delete>
<!--查,根据id查-->
<select id="findById" parameterType="int" resultType="user">
select * from user where id=#{id}
</select>
<!--查,查询全部-->
<select id="findAll" resultType="user">
select * from user
</select>
</mapper>
第七步: 在pom.xml写入如下
<dependencies>
<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
<!--引入MyBatis坐标-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!--引入Junit坐标,用于测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--引入log4j,用于打印日志-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
第八步: 在src.test.java目录下,新建com.huanf.test.MyBatisTest类,写入如下,并分别执行5个test方法
public class MyBatisTest {
private UserMapper mapper;
//@Before注解表示前置增强。作用: 由于下面每个@Test测试都要写’获得Mapper代理对象‘的代码,所以就把’获得Mapper代理对象‘的代码抽取出来
public void before() throws IOException {
//获得核心配置文件。注意写的是相对路径,也就是src/main/resources/sqlMapConfig.xml
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session会话对象,true表示自动提交事务
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//使用getMapper获得mapper代理对象
mapper = sqlSession.getMapper(UserMapper.class);
}
public void testSave(){//增
User user = new User();
user.setUsername("testSave方法");
user.setPassword("abc");
mapper.save(user);
}
public void testUpdate(){//改
User user = new User();
user.setId(2);
user.setUsername("修改id为2的姓名");
user.setPassword("abc");
mapper.update(user);
}
public void testDelete(){//删
mapper.delete(7);
}
public void testFindById(){//根据id查询
User user = mapper.findById(2);
System.out.println(user);
}
public void testFindAll(){//查询全部数据
List<User> all = mapper.findAll();
for (User user : all) {
System.out.println(user);
}
}
}
上面我们已经用注解完成了一次完整的配置,可以实现增删改查。现在开始我们将用注解,来替换掉UserMapper.xml里面配置的代码
@Insert: 实现新增 @Update: 实现更新 @Delete: 实现删除 @Select: 实现查询 @Result: 实现结果集封装 @Results: 可以与@Result一起使用,封装多个结果集 @One: 实现一对一结果集封装 @Many: 实现一对多结果集封装
具体操作如下:
第一步: 删掉src/main/java目录下的com/huanf/mapper目录、UserMapper.xml文件。如果不删,选择注释的话,就只留下如下即可
xxxxxxxxxx
<mapper namespace="com.huanf.mapper.UserMapper">
</mapper>
第二步: 删掉sqlMapConfig.xml文件里面的'加载映射文件'的三行代码。不删的话,注释也可
第三步: 最重要的一步,就是在UserMapper接口,修改为如下。可以发现我们把原先在UserMapper.xml写的sql语句搬到这里来了,注意这里就是注解的形式
public interface UserMapper {
"insert into user values(#{id},#{username},#{password},#{birthday})") (
public void save(User user);
"update user set username=#{username},password=#{password} where id=#{id}") (
public void update(User user);
"delete from user where id=#{id}") (
public void delete(int id);
"select * from user where id=#{id}") (
public User findById(int id);
"select * from user") (
public List<User> findAll();
}
第四步: 在sqlMapConfig.xml里面添加如下
<!--加载映射关系-->
<mappers>
<!--指定接口所在的包,然后就会自动扫描接口用到的注解-->
<package name="com.huanf.mapper"/>
</mappers>
第五步: 在MyBatisTest类进行测试,分别执行5个test方法执行
上面我们演示了基于MyBatis注解的简单查询,这里就演示复制查询
之前xml的时候,实现复杂关系映射,一般是在映射文件中通过配置
注解 | 说明 |
---|---|
@Results | 代替的是 |
@Result | 代替的是 |
@One | 该注解用于一对一查询。代替的是 |
@Many | 该注解用于多对一查询。代替的是 |
接下来是对上面4个注解进行具体的演示
需求: 查询订单的同时,查询出跟订单关联的用户
具体操作如下:
第一步: 在src/main/java/com.huanf/domain目录下新建Order类,写入如下
//订单的实体类,对应的是数据库的orders表
public class Order {
private int id;
private Date ordertime;
private double total;
private User user; //这个表示的是orders的uid外键(订单属于user表的用户)
//get和set方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getOrdertime() {
return ordertime;
}
public void setOrdertime(Date ordertime) {
this.ordertime = ordertime;
}
public double getTotal() {
return total;
}
public void setTotal(double total) {
this.total = total;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
//toString方法
public String toString() {
return "Order{" +
"id=" + id +
", ordertime=" + ordertime +
", total=" + total +
", user=" + user +
'}';
}
}
第二步: 在src/main/java/com.huanf/mapper目录下新建OrderMapper接口,写入如下
//两张表一起查
public interface OrderMapper {
"select *,o.id oid from orders o,user u where o.uid=u.id") (
({
//column是上面那条查询语句查询出来的字段,property是Order类的成员变量
column = "oid",property = "id"), (
column = "ordertime",property = "ordertime"), (
column = "total",property = "total"), (
column = "uid",property = "user.id"), (
column = "username",property = "user.username"), (
column = "password",property = "user.password") (
})
public List<Order> findAll();
}
第三步: 在src/test/java/com.huanf.test目录下新建MyBatisTest2类,写入如下,并执行测试
public class MyBatisTest2 {
private OrderMapper mapper;
//@Before注解表示前置增强。作用: 由于下面每个@Test测试都要写’获得Mapper代理对象‘的代码,所以就把’获得Mapper代理对象‘的代码抽取出来
public void before() throws IOException {
//获得核心配置文件。注意写的是相对路径,也就是src/main/resources/sqlMapConfig.xml
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session会话对象,true表示自动提交事务
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//使用getMapper获得mapper代理对象
mapper = sqlSession.getMapper(OrderMapper.class);
}
public void test_zidingyi(){//基于注解,一对一查询,两张表一起查
List<Order> all = mapper.findAll();
for (Order order : all) {
System.out.println(order);
}
}
}
具体操作:
第一步: 在OrderMapper接口,添加如下
//两张表分开查,例如执行下面那条语句,那么肯定会查询出来uid,由于uid不是orders表的字段,而是user表的字段,所以这时就要用到比较复杂的@Result注解
"select * from orders") (
({
//column是上面那条查询语句查询出来的字段,property是Order类的成员变量
column = "id",property = "id"), (
column = "ordertime",property = "ordertime"), (
column = "total",property = "total"), (
(
property = "user", //表示要封装的属性名,例如Order类的user成员变量
column = "uid", //表示根据哪个字段去查user表的数据
javaType = User.class, // 表示要封装的实体类型,例如User类
//一对一查询语法,其中select属性表示要查询哪个接口的方法(例如UserMapper接口的findById方法)去获得对应的数据
one = (select = "com.huanf.mapper.UserMapper.findById")
)
})
public List<Order> findAll_two();
第二步: 在MyBatisTest2类,添加如下,并执行测试
public void test_zidingyi2(){//基于注解,一对一查询,两张表分开查
List<Order> all = mapper.findAll_two();
for (Order order : all) {
System.out.println(order);
}
}
需求: 查询一个用户,并查询出该用户具有的订单
具体操作:
第一步: 在User类添加如下,并自行添加相应的get和set方法、toString方法
//描述的是当前用户具有的订单
private List<Order> orderList;
第二步: 在OrderMapper接口添加如下
//一对多查询
"select * from orders where uid=#{uid}") (
public List<Order> findByUid(int uid);
第三步: 在UserMapper接口添加如下
//一对多查询,查两张表
Select("select * from user")
({
//column是上面那条查询语句查询出来的字段,property是User类的成员变量
id=true, column = "id",property = "id"), //id=true表示column填入的id是主键 (
column = "username",property = "username"), (
column = "password",property = "password"), (
(
property = "orderList",
column = "id",
javaType = List.class,
//一对多查询
many = (select = "com.huanf.mapper.OrderMapper.findByUid")
)
})
public List<User> findUserAndOrderAll();
第四步: 在src/test/java/com.huanf.test目录下新建MyBatisTest3类,写入如下,并执行测试
public class MyBatisTest3 {
private UserMapper mapper;
@Before //@Before注解表示前置增强。作用: 由于下面每个@Test测试都要写’获得Mapper代理对象‘的代码,所以就把’获得Mapper代理对象‘的代码抽取出来
public void before() throws IOException {
//获得核心配置文件。注意写的是相对路径,也就是src/main/resources/sqlMapConfig.xml
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session会话对象,true表示自动提交事务
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//使用getMapper获得mapper代理对象
mapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void test_suibianxie(){//基于注解,一对多查询
List<User> userAndOrderAll = mapper.findUserAndOrderAll();
for (User user : userAndOrderAll) {
System.out.println(user);
}
}
}
需求: 查询用户,同时查询出该用户的所有角色
具体操作:
第一步: 在src/main/java/com.huanf.domain目录下新建Role类,写入如下
//对应的是数据库的sys_role角色表
public class Role {
private int id;
private String roleName;
private String roleDesc;
//get和set方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
public String toString() {
return "Role{" +
"id=" + id +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
'}';
}
}
第二步: 在User类添加如下,并自行添加相应的get和set方法、toString方法
//描述当前用户具备哪些角色
private List<Role> roleList;
第三步: 在UserMapper接口添加如下
//多对多查询,查三张表
"select * from user") (
({
id=true,column = "id",property = "id"), (
id=true,column = "username",property = "username"), (
id=true,column = "password",property = "password"), (
(
property = "roleList",
column = "id",
javaType = List.class,
//一对多查询
many = (select="com.huanf.mapper.RoleMapper.findByUserId")
)
})
public List<User> findUserAndRoleAll();
第四步: 在src/main/java/com.huanf.mapper目录下新建RoleMapper接口,写入如下
public interface RoleMapper {
"select * from sys_user_role ur,sys_role r where ur.roleId=r.id and ur.userId=#{uid}") (
public List<Role> findByUserId(int uid);
}
第五步: 在src/test/java/com.huanf.test目录下新建MyBatisTest4类,写入如下,并执行测试
public class MyBatisTest4 {
private UserMapper mapper;
//@Before注解表示前置增强。作用: 由于下面每个@Test测试都要写’获得Mapper代理对象‘的代码,所以就把’获得Mapper代理对象‘的代码抽取出来
public void before() throws IOException {
//获得核心配置文件。注意写的是相对路径,也就是src/main/resources/sqlMapConfig.xml
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session会话对象,true表示自动提交事务
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//使用getMapper获得mapper代理对象
mapper = sqlSession.getMapper(UserMapper.class);
}
public void test_suibianxiee(){//基于注解,一对多查询
List<User> userAndRoleAll = mapper.findUserAndRoleAll();
for (User user : userAndRoleAll) {
System.out.println(user);
}
}
}