本文为how2java Mybatis教程的学习笔记,原教程链接如下:http://how2j.cn/k/mybatis/mybatis-tutorial/1087.html#nowhere
通过注解方式实现CRUD
创建Mapper接口
新增加接口CategoryMapper ,并在接口中声明的方法上,加上CRUD的注解。对比之前的配置文件Category.xml,其实就是把SQL语句从XML挪到了注解上来。
package com.how2java.mapper;
public interface CategoryMapper {
@Insert(" insert into category_ ( name ) values (#{name}) ")
public int add(Category category);
@Delete(" delete from category_ where id= #{id} ")
public void delete(int id);
@Select("select * from category_ where id= #{id} ")
public Category get(int id);
@Update("update category_ set name=#{name} where id=#{id} ")
public int update(Category category);
@Select(" select * from category_ ")
public List<Category> list();
}
修改mybatis-config.xml
在mybatis-config.xml中增加对CategoryMapper映射,原来的XML映射可以保留。
- 注解mapper标签属性名为class,xml映射文件mapper标签属性名为resource。
<mappers>
<mapper resource="com/how2java/pojo/Category.xml"/>
<mapper class="com.how2java.mapper.CategoryMapper"/>
...
</mappers>
测试
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 session = sqlSessionFactory.openSession();
CategoryMapper mapper = session.getMapper(CategoryMapper.class);
add(mapper);
delete(mapper);
get(mapper);
update(mapper);
session.commit();
session.close();
}
private static void update(CategoryMapper mapper) {
Category c= mapper.get(8);
c.setName("修改了的Category名稱");
mapper.update(c);
listAll(mapper);
}
private static void get(CategoryMapper mapper) {
Category c= mapper.get(8);
System.out.println(c.getName());
}
private static void delete(CategoryMapper mapper) {
mapper.delete(2);
listAll(mapper);
}
private static void add(CategoryMapper mapper) {
Category c = new Category();
c.setName("新增加的Category");
mapper.add(c);
listAll(mapper);
}
private static void listAll(CategoryMapper mapper) {
List<Category> cs = mapper.list();
for (Category c : cs) {
System.out.println(c.getName());
}
}
通过CategoryMapper mapper = session.getMapper(CategoryMapper.class);
创建mapper对象,然后通过mapper对应的增删改查方法执行增删改查操作。
一对多
数据库中Category与Product之间一对多的关系通过product_表的cid字段来表示。现在要实现的功能是如何通过数据库的表结构,来填充Category实体类中products集合。
List<Product> products;
修改CategoryMapper
package com.how2java.mapper;
public interface CategoryMapper {
@Select(" select * from category_ ")
@Results({
@Result(property = "id", column = "id"),
@Result(javaType = List.class,
column = "id",
many = @Many(select =
"com.how2java.mapper.ProductMapper.listByCategory"))
})
public List<Category> list();
}
@Results 通过@Result和@Many中调用ProductMapper.listByCategory()方法相结合,来获取一对多关系。property属性代表的是实体类Category的属性(“id”和“products”),column属性代表的是数据库中列名(“id”)。
新增ProductMapper
package com.how2java.mapper;
public interface ProductMapper {
@Select(" select * from product_ where cid = #{cid}")
public List<Product> listByCategory(int cid);
}
修改mybatis-config.xml
添加ProductMapper映射。
<mappers>
<mapper resource="com/how2java/pojo/Category.xml"/>
<mapper class="com.how2java.mapper.CategoryMapper"/>
<mapper class="com.how2java.mapper.ProductMapper"/>
</mappers>
测试
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 session = sqlSessionFactory.openSession();
CategoryMapper mapper = session.getMapper(CategoryMapper.class);
listAll(mapper);
session.commit();
session.close();
}
private static void listAll(CategoryMapper mapper) {
List<Category> cs = mapper.list();
for (Category c : cs) {
System.out.println(c.getName());
List<Product> ps = c.getProducts();
for (Product p : ps) {
System.out.println("\t"+p.getName());
}
}
}
运行结果:
多对一
数据库中Product与Category之间多对一的关系通过product_表的cid字段来表示。现在要实现的功能是如何通过数据库的表结构,来填充Product实体类中的category字段(数据库中存储的是int类型的id,实体类中是Category类型,因而不能直接导入)。
private Category category;
修改CategoryMapper
package com.how2java.mapper;
public interface CategoryMapper {
@Select(" select * from category_ where id = #{id}")
public Category get(int id);
}
修改ProductMapper
package com.how2java.mapper;
public interface ProductMapper {
@Select(" select * from product_ ")
@Results({
@Result(property="category",column="cid",
one=@One(select="com.how2java.mapper.CategoryMapper.get"))
})
public List<Product> list();
}
测试
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 session = sqlSessionFactory.openSession();
CategoryMapper mapper = session.getMapper(CategoryMapper.class);
listAll(mapper);
session.commit();
session.close();
}
private static void listAll(CategoryMapper mapper) {
List<Category> cs = mapper.list();
for (Category c : cs) {
System.out.println(c.getName());
List<Product> ps = c.getProducts();
for (Product p : ps) {
System.out.println("\t"+p.getName());
}
}
}
运行结果:
多对多
多对多是多对一和一对多的结合:对OrderItem和Product之间建立多对一关系,对Order和OrderItem建立一对多关系。即可建立Product和Order之间多对多的关系。
修改ProductMapper
package com.how2java.mapper;
public interface ProductMapper {
@Select("select * from product_ where id = #{id}")
public Product get(int id);
}
新增OrderItemMapper
新增OrderItemMapper,提供listByOrder方法。这里会与Product建立多对一关系。
package com.how2java.mapper;
public interface OrderItemMapper {
@Select(" select * from order_item_ where oid = #{oid}")
@Results({
@Result(property="product",column="pid",
one=@One(select="com.how2java.mapper.ProductMapper.get"))
})
public List<OrderItem> listByOrder(int oid);
}
新增OrderMapper
新增OrderMapper,提供list方法,这里会与OrderItem建立一对多关系。
package com.how2java.mapper;
public interface OrderMapper {
@Select("select * from order_")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "orderItems",
javaType = List.class,
column = "id",
many = @Many(select =
"com.how2java.mapper.OrderItemMapper.listByOrder"))
})
public List<Order> list();
}
修改mybatis-config.xml
<mappers>
...
<mapper class="com.how2java.mapper.OrderItemMapper"/>
<mapper class="com.how2java.mapper.OrderMapper"/>
...
</mappers>
测试
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 session = sqlSessionFactory.openSession();
listOrder(session);
session.commit();
session.close();
}
private static void listOrder(SqlSession session) {
OrderMapper mapper =session.getMapper(OrderMapper.class);
List<Order> os = mapper.list();
for (Order o : os) {
System.out.println(o.getCode());
List<OrderItem> ois= o.getOrderItems();
if(null!=ois){
for (OrderItem oi : ois) {
System.out.format("\t%s\t%f\t%d%n", oi.getProduct().getName(),oi.getProduct().getPrice(),oi.getNumber());
}
}
}
}
运行结果:
补充
注意:由于未建立OrderItem和Order的多对一关系,因而此时OrderItem中只填充了Product而没有填充Order。
上面从Order的角度获得和Product多对多的关系,要想从Product角度获得和Order多对多的关系,则要建立Product和OrderItem之间一对多的关系、OrderItem和Order之间多对一的关系。
Product实体类添加:
List<OrderItem> orderItems;
ProductMapper映射类添加:
@Select("select * from product_")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "orderItems",
javaType = List.class,
column = "id",
many = @Many(select =
"com.how2java.mapper.OrderItemMapper.listByProduct"))
})
public List<Product> list();
OrderItemMapper映射类添加:
@Select(" select * from order_item_ where pid = #{pid}")
@Results({
@Result(property="order",column="oid",
one=@One(select="com.how2java.mapper.OrderMapper.get"))
})
public List<OrderItem> listByProduct(int pid);
OrderMapper映射类添加:
@Select("select * from order_ where id = #{id}")
public Order get(int id);
测试代码:
ProductMapper mapper1 =session.getMapper(ProductMapper.class);
List<Product> ps = mapper1.list();
for (Product p : ps) {
System.out.println(p.getName());
List<OrderItem> pis= p.getOrderItems();
if(null!=pis){
for (OrderItem oi : pis) {
if(oi.getOrder()!=null){
System.out.println("\t" + oi.getOrder().getCode());
}
}
}
}
运行结果:
动态SQL
待补充