MaBatis(5)输入/输出映射
本次全部学习内容:MyBatisLearning
输入映射:
通过parameType指定输入参数的类型,类型可以是简单类型,hashmap,pojo等
传递pojo的包装对象
需求:
即使一个综合查询,需要传入多个查询的条件
开始敲代码了......
在这次使实践里面,需要新建两个类,和使用之前的的测试类进行测试
新建UserCustomer.java主要是继承User.java其他的代码不写
public class UserCustomer extends User{ }
在UserView.java中:
//在这里包装所需要的查询条件 //用户综合查询查询条件 private UserCustomer userCustomer; public UserCustomer getUserCustomer() { return userCustomer; } public void setUserCustomer(UserCustomer userCustomer) { this.userCustomer = userCustomer; }
在UserMapper.java中定义综合查询的方法
//综合查询 public List<User> findBySelect(UserView userView) throws Exception;
在UserMapper.xml文件中实现查询的代码:
<!-- 综合查询 -->
<select id="findBySelect" parameterType="com.MrChengs.po.UserView" resultType="com.MrChengs.po.UserCustomer" >
select * from user where user.id=#{userCustomer.id} and user.username like '%${userCustomer.username}%'
</select>
讲解:parameterType这个是我们输入参数的类型,#{userCustomer.id}由此可以定位到UserView.java这个类面,在进行定位就是userCustomer,
对userCustomer在进一步就是UserCustomer这个类,他是继承User这个类,此时到User这个类,已经到底,我们可以发现id这和属性,这个userCustomer.id相当于一个连点的方法
resultType:使我们综合查询的类型,此时使userCustomer
测试类中:
//综合查询 @Test public void testfindBySelect() throws Exception{ SqlSession sqlSession = getSqlSessionFactory().openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserView userView = new UserView(); UserCustomer userCustomer = new UserCustomer(); userCustomer.setId(16); userCustomer.setUsername("小明"); userView.setUserCustomer(userCustomer); List<User> user = mapper.findBySelect(userView); for(User u : user){ System.out.println(u); } sqlSession.close(); }
查询成功:
DEBUG [main] - ==> Preparing: select * from user where user.id=? and user.username like '%小明%' DEBUG [main] - ==> Parameters: 16(Integer) DEBUG [main] - <== Total: 1 User [id=16, username=张小明, birthday=null, sex=1, address=河南郑州]
生成的动态代理对象中是根据mapper方法的返回值类型确定是调用selectOne(返回单个对象调用)还是selectList (返回集合对象调用 ).
输出映射:
对于resultType:
使用此属性进行输出映射时,只有在查询出来的列和pojo中的属性名一致,该列才可以映射成功
若查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象
只要查询出来的列名和pojo中的属性名有一个一致,就会创建pojo对象
现在来实现一个测试的例子:
在UserMapper.java的接口类中:
//擦寻用户信息总数 public int findUserCount(UserView userView) throws Exception;
在UserMapper.xml文件中:
<!-- 输出映射查询用户信息总数 -->
<select id="findUserCount" parameterType="com.MrChengs.po.UserView" resultType="int">
select count(*) From user where sex=#{userCustomer.sex} and user.username like '%${userCustomer.username}%'
</select>
在测试类中进行测试:
//查询用户信息总数 @Test public void testfindUserCount() throws Exception{ SqlSession sqlSession = getSqlSessionFactory().openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserView userView = new UserView(); UserCustomer userCustomer = new UserCustomer(); userCustomer.setSex(1); userCustomer.setUsername("小明"); userView.setUserCustomer(userCustomer); int count = mapper.findUserCount(userView); System.out.println(count); sqlSession.close(); }
结果:
DEBUG [main] - Opening JDBC Connection DEBUG [main] - Created connection 963522361. DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@396e2f39] DEBUG [main] - ==> Preparing: select count(*) From user where sex=? and user.username like '%小明%' DEBUG [main] - ==> Parameters: 1(Integer) DEBUG [main] - <== Total: 1 3 DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@396e2f39]
输出pojo对象和输出pojo列表在sql中定义的resultType是一样的。
返回单个pojo对象要保证sql查询出来的结果集为单条,内部使用session.selectOne方法调用,mapper接口使用pojo对象作为方法返回值。
返回pojo列表表示查询出来的结果集可能为多条,内部使用session.selectList方法,mapper接口使用List<pojo>对象作为方法返回值。
resultMap:
resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
下面是代码的实践:
测试:
在UserMapper.java接口中:
//测试resultMap public User findByMap(int id) throws Exception;
在UserMapper.xml中:
<!-- 简单测试resultMap的使用 --> <!-- type:resultMap最终映射的java 对象类型,可以使用别名/全类名 --> <!-- id:使当前resultMap的唯一标识 --> <resultMap type="com.MrChengs.po.User" id="ByMap"> <!-- id标识查询结果的唯一标识 --> <!-- column:查询出来的列名 --> <!-- property:type指定类型的pojo类型的映射属性,最终resultMap对cloumn和property做出一对一的映射 --> <id column="_id" property="id"/> <!-- result:对普通列名的映射 --> <!-- column:查询出来的列名 --> <!-- property:和type的类型一一映射 --> <result column="_username" property="username"/> </resultMap> <select id="findByMap" parameterType="int" resultMap="ByMap"> select id _id,username _username from user where id=#{id} </select>
可以在sql软件中测试select id _id,username _username from user where id=? 查看我们得到的结果。
<id />:此属性表示查询结果集的唯一标识,非常重要。如果是多个字段为复合唯一约束则定义多个<id />。
Property:表示person类的属性。
Column:表示sql查询出来的字段名。
Column和property放在一块儿表示将sql查询出来的字段映射到指定的pojo类属性上。
<result />:普通结果,即pojo的属性。
在测试类中:
//测试resultMap @Test public void testfindByMap() throws Exception{ SqlSession sqlSession = getSqlSessionFactory().openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.findByMap(1); System.out.println(user); sqlSession.close(); }
结果:
DEBUG [main] - Opening JDBC Connection DEBUG [main] - Created connection 2050835901. DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7a3d45bd] DEBUG [main] - ==> Preparing: select id _id,username _username from user where id=? DEBUG [main] - ==> Parameters: 1(Integer) DEBUG [main] - <== Total: 1 User [id=1, username=王五, birthday=null, sex=0, address=null]
小结:
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。