1.关联查询
l 创建一个Customer类,Order类
public class Customer { private Integer id; private String name; private Integer age; private Set<Order> orders; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Set<Order> getOrders() { return orders; } public void setOrders(Set<Order> orders) { this.orders = orders; } @Override public String toString() { return "Customer [id=" + id + ", name=" + name + ", age=" + age + ", orders=" + orders + "]"; } }
package mybatis.entity; public class Order { private Integer id; private String orderNumber; private Integer price; private Customer customer; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getOrderNumber() { return orderNumber; } public void setOrderNumber(String orderNumber) { this.orderNumber = orderNumber; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } @Override public String toString() { return "Order [id=" + id + ", orderNumber=" + orderNumber + ", price=" + price + "]"; } }
l 创建客户表和订单表
CREATE TABLE `t_customer` ( `id` int(5) NOT NULL auto_increment, `name` varchar(20) default NULL, `age` int(2) default NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
CREATE TABLE `t_order` ( `id` int(5) NOT NULL auto_increment, `orderNumber` varchar(20) default NULL, `price` int(10) default NULL, `customer_id` int(5) default NULL, PRIMARY KEY (`id`), KEY `customer_id` (`customer_id`), CONSTRAINT `t_order_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `t_customer` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
1.1 根据id查询客户,关联查询订单
第一步:创建一个CustomerMapper.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="mybatis.entity.Customer"> <resultMap type="Customer" id="customerWithOrder"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <collection property="orders" ofType="Order"> <!-- <id property="id" column="id"/> --> <id property="id" column="oid"/> <result property="orderNumber" column="orderNumber"/> <result property="price" column="price" /> </collection> </resultMap> <!--可以正常的查出信息,但是由于返回类型的原因,订单信息无法封装到Customer中,解决办法如下:queryById2 --> <select id="queryById" resultType="Customer"> select c.*, o.* from t_customer c left outer join t_order o on c.id=o.customer_id where c.id = #{id} </select> <!--两个个表的id同名,会造成一些错误,例如没有订单信息的会有一个空的订单记录,有多个订单信息得只能查出来一条,解决办法如下:queryById3 --> <select id="queryById2" resultMap="customerWithOrder"> select c.*, o.* from t_customer c left outer join t_order o on c.id=o.customer_id where c.id = #{id} </select> <select id="queryById3" resultMap="customerWithOrder"> select c.*, o.*,o.id as oid from t_customer c left outer join t_order o on c.id=o.customer_id where c.id = #{id} </select> </mapper>
第二步:将sql映射文件注册到sqlMapConfig.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> <typeAliases> <typeAlias type="mybatis.entity.User" alias="User"/> <typeAlias type="mybatis.entity.Book" alias="Book"/> <typeAlias type="mybatis.entity.Customer" alias="Customer"/> <typeAlias type="mybatis.entity.Order" alias="Order"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <!-- <property name="driver" value="com.mysql.jdbc.Driver" /> --> <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis_demo" /> <property name="username" value="root" /> <property name="password" value="root" /> </dataSource> </environment> </environments> <mappers> <mapper resource="mybatis/entity/UserMapper.xml"/> <mapper resource="mybatis/entity/BookMapper.xml"/> <mapper resource="mybatis/entity/CustomerMapper.xml"/> <mapper resource="mybatis/entity/OrderMapper.xml"/> </mappers> </configuration>
第三步:使用mybatis提供的api,操作数据库
package mybatis; import java.io.IOException; import java.io.InputStream; import java.util.List; 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 org.junit.Before; import org.junit.Test; import mybatis.entity.Customer; import mybatis.entity.Order; public class AssociationQueryTest { static final String CUSTOMER_NAMESPAC = "mybatis.entity.Customer"; static final String ORDER_NAMESPAC = "mybatis.entity.Order"; SqlSession sqlSession = null; @Before public void createSqlSesion() throws IOException { InputStream asStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(asStream); sqlSession = sqlSessionFactory.openSession(); } // 根据Customer查询Order @Test public void testQuery() { List<Customer> customers = sqlSession.selectList(CUSTOMER_NAMESPAC + ".queryById", 1); for (Customer customer2 : customers) { System.out.println(customer2); } sqlSession.close(); } @Test public void testQuery2() { Customer customer = sqlSession.selectOne(CUSTOMER_NAMESPAC + ".queryById2", 1); System.out.println(customer); sqlSession.close(); } @Test public void testQuery3() { Customer customer = sqlSession.selectOne(CUSTOMER_NAMESPAC + ".queryById3", 1); System.out.println(customer); sqlSession.close(); } }
2.1 根据id查询订单,关联查询客户
第一步:创建一个OrderMapper.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="mybatis.entity.Order"> <resultMap type="Order" id="orderColumns4Map"> <id property="id" column="id" /> <result property="orderNumber" column="orderNumber" /> <result property="price" column="price" /> <association property="customer" javaType="Customer"> <id property="id" column="cid" /> <result property="name" column="name" /> <result property="age" column="age" /> </association> </resultMap> <select id="queryById" resultMap="orderColumns4Map"> select o.*,c.*,c.id as cid from t_order o left outer join t_customer c on o.customer_id=c.id where o.id=#{id} </select> </mapper>
第二步:将sql映射文件注册到sqlMapConfig.xml中
第三步:使用框架提供的api操作数据库:
// 根据Order查询Customer @Test public void testQueryOrder() { Order order = sqlSession.selectOne(ORDER_NAMESPAC+".queryById", 2); System.out.println(order); System.out.println(order.getCustomer()); sqlSession.close(); }
3. 动态sql
3.1 查询
<select id="queryByCondition" resultType="User" parameterType="User"> select <include refid="userColumns" /> from t_user <!-- where 1=1 --> <where> <if test="id!=null"> and id=#{id} </if> <if test="name!=null"> and name=#{name} </if> <if test="age!=null"> and age=#{age} </if> </where> </select>
@Test public void queryUserByCondition() { User user2 = new User(); user2.setId(1); user2.setAge(23); user2.setName("张三"); List<User> users = sqlSession.selectList(NAMESPACE + ".queryByCondition", user2); for (User user : users) { System.out.println(user); } sqlSession.close(); }
3.2 更新
<!-- 有必要使用set标签,不然在进行属性是否为空的判断中容易因为‘,’出错 --> <update id="modifyByCondition" parameterType="User"> update t_user <set> <if test="name!=null"> name=#{name}, </if> <if test="age!=null"> age=#{age}, </if> <if test="address!=null"> address=#{address} </if> </set> where id=#{id} </update>
@Test public void modifyUserByCondition() { User user2 = new User(); user2.setId(1); user2.setAge(23); user2.setName("张三"); int num = sqlSession.update(NAMESPACE + ".modifyByCondition", user2); System.out.println(num); sqlSession.close(); }
4. 批量操作
4.1 批量插入数据
在sql映射文件中:
<insert id="insertDataList"> insert into t_user ( <include refid="userColumns" /> ) values <foreach collection="collection" item="user" separator=","> (null,#{user.name},#{user.age},#{user.address}) </foreach> </insert>
@Test public void insertUserList() { Set<User> userSets = new HashSet<User>(); for (int i = 0; i < 3; i++) { User user = new User("Name:"+i, 20+i, "北京:"+i); userSets.add(user); } int num = sqlSession.update(NAMESPACE + ".insertDataList", userSets); sqlSession.commit(); System.out.println(num); sqlSession.close(); }
4.2 根据id集合查询多条数据
Sql映射文件中:
<select id="queryInList" resultType="User"> select <include refid="userColumns" /> from t_user <if test="collection != null & collection.size() > 0"> where id in <foreach collection="collection" item="user" separator="," open="(" close=")"> #{user.id} </foreach> </if> </select>
@Test public void queryUserList() { Set<User> userSets = new HashSet<User>(); for (int i = 1; i <=5; i++) { User user = new User(); user.setId(i); userSets.add(user); } List<User> users= sqlSession.selectList(NAMESPACE + ".queryInList", userSets); for (User user : users) { System.out.println(user); } sqlSession.close(); }