注释信息已经包含在代码中,这里就不多做解释了。
参考资料:Mybatis参考资料
包含基本操作(基本篇)和spring事务管理以及懒加载(进阶篇)。
以及开发中常遇到的一对一,一对多情况的配置(collection/association)
首先是maven Dependency:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tch.test</groupId> <artifactId>spring-mybatis</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-mybatis</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <junit-version>4.11</junit-version> <spring-version>3.2.6.RELEASE</spring-version> <log4j-version>1.2.17</log4j-version> <slf4j-version>1.7.5</slf4j-version> <aspectj-version>1.7.4</aspectj-version> <mybatis-version>3.2.2</mybatis-version> <postgresql-version>9.1-901-1.jdbc4</postgresql-version> </properties> <dependencies> <!-- spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring-version}</version> </dependency> <!-- spring-orm --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring-version}</version> </dependency> <!-- log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j-version}</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis-version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> <version>${postgresql-version}</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.1</version> </dependency> </dependencies> </project>
一:基本篇:
applicationContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 启动注入功能 --> <context:annotation-config /> <!-- 启动扫描component功能 --> <context:component-scan base-package="com.tch.test.spring_mybatis" /> <!-- 启动注解实物配置功能 --> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- 数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.postgresql.Driver"></property> <property name="url" value="jdbc:postgresql://localhost:5432/postgres"></property> <property name="username" value="postgres"></property> <property name="password" value="postgres"></property> </bean> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!--读取数据库配置文件 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 如果mapper的xml文件名字和mapper接口的名字一致,并且在同一目录下(例如UserMapper.java和UserMapper.xml),可以不配置mapperLocations, --> <property name="mapperLocations" value="classpath:**/*Mapper.xml" /> <!-- 指定别名,在mapper的xml文件中可以使用别名(例如User/user来代表com.tch.test.spring_mybatis.entity.User),提高开发效率 --> <property name="typeAliasesPackage" value="com.tch.test.spring_mybatis.entity" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 指定mapper接口包名,可以通过动态代理生成代理类,这样就可以在service层直接通过注入的方式进行dao操作了 --> <property name="basePackage" value="com.tch.test.spring_mybatis.mapper" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> </beans>
log4j.properties:
log4j.rootLogger=debug,CONSOLE ################### # Console Appender ################### log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.Threshold=debug log4j.appender.CONSOLE.Target=System.out log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p (%c:%L) - %m%n
数据库创建脚本(注: 我使用的是postgresql,其他数据库可能不一样,根据情况做些修改):
CREATE TABLE _user ( id bigint NOT NULL, age bigint, username character(15), password character(20), CONSTRAINT user_pkey PRIMARY KEY (id) ) WITH ( OIDS=FALSE ); ALTER TABLE _user OWNER TO postgres; CREATE TABLE _order ( orderNum bigint NOT NULL, userId bigint NOT NULL, CONSTRAINT order_pkey PRIMARY KEY (orderNum) ) WITH ( OIDS=FALSE ); ALTER TABLE _order OWNER TO postgres; CREATE TABLE orderDetail ( id bigint NOT NULL, orderNum bigint NOT NULL, itemId bigint NOT NULL, itemNum bigint NOT NULL, CONSTRAINT order_detail_pkey PRIMARY KEY (id) ) WITH ( OIDS=FALSE ); ALTER TABLE orderDetail OWNER TO postgres; CREATE TABLE item ( id bigint NOT NULL, itemName character(15), price bigint, CONSTRAINT item_pkey PRIMARY KEY (id) ) WITH ( OIDS=FALSE ); ALTER TABLE item OWNER TO postgres;
entity:
package com.tch.test.spring_mybatis.entity; public class User { private int id; private String username; private String password; private int age; 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", password=" + password + ", age=" + age + "]"; } }
UserMapper.java和UserMapper.xml在同一个目录下。
UserMapper.java:
package com.tch.test.spring_mybatis.mapper; import com.tch.test.spring_mybatis.entity.User; /** * * 方法名和mapper的xml中的select/insert/delete/update 的id一致, * 方法的输入参数和parameterType一致, * 方法的返回值和resultType一致 * * @author dreamoftch */ public interface UserMapper { User queryUserByID(int id); void insertUser(User user); void deleteUser(User user); void updateUser(User user); }
UserMapper.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"> <!-- 这里的namespace是mapper接口的全路径 --> <mapper namespace="com.tch.test.spring_mybatis.mapper.UserMapper"> <!-- 下面的select/insert/delete/update 的id和mapper接口的方法名一致,parameterType和方法的输入参数一致,resultType和方法的返回值一致 --> <select id="queryUserByID" parameterType="int" resultType="user"> select * from _user where id = #{id} </select> <insert id="insertUser" parameterType="com.tch.test.spring_mybatis.entity.User"> insert into _user(id, username, password, age) values(#{id}, #{username}, #{password}, #{age}) </insert> <delete id="deleteUser" parameterType="com.tch.test.spring_mybatis.entity.User"> delete from _user <where> <if test="id != null"> and id = #{id} </if> <if test="username != null"> and username = #{username} </if> <if test="password != null"> and password = #{password} </if> <if test="age != null"> and age = #{age} </if> </where> </delete> <update id="updateUser" parameterType="com.tch.test.spring_mybatis.entity.User"> update _user <set> <if test="username != null"> username = #{username}, </if> <if test="password != null"> password = #{password}, </if> <if test="age != null"> age = #{age}, </if> </set> <!-- where id = #{id} --> <where> <if test="id != null"> id = #{id} </if> </where> </update> </mapper>
service接口:
package com.tch.test.spring_mybatis.service; import com.tch.test.spring_mybatis.entity.User; public interface IUserService { User queryUserByID(int id) throws Exception; void insertUser(User user) throws Exception; void deleteUser(User user) throws Exception; void updateUser(User user) throws Exception; void raiseException() throws Exception; /** * test transaction * @param user * @throws Exception */ void testTransaction(User user) throws Exception; /** * test transaction2 * @param user * @throws Exception */ void testTransaction2(User user) throws Exception; }
service 实现类:
package com.tch.test.spring_mybatis.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.tch.test.spring_mybatis.entity.User; import com.tch.test.spring_mybatis.mapper.UserMapper; @Service("userService") public class UserServiceImpl implements IUserService { /** * UserMapper接口并没有实现类,这里会注入一个该接口的代理类 */ @Autowired private UserMapper userMapper; public User queryUserByID(int id) throws Exception { return userMapper.queryUserByID(id); } @Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class }) public void insertUser(User user) throws Exception { userMapper.insertUser(user); } @Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class }) public void deleteUser(User user) throws Exception { userMapper.deleteUser(user); } @Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class }) public void updateUser(User user) throws Exception { userMapper.updateUser(user); } @Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class }) public void testTransaction(User user) throws Exception { // delete -> add -> add() user.setId(user.getId() + 1); // new id userMapper.insertUser(user); // insert raiseException(); // raise exception user.setUsername("update username"); userMapper.updateUser(user); } public void raiseException(){ boolean flag = true; if(flag){ throw new IllegalStateException("Duang ..."); } } @Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class }) public void testTransaction2(User user) throws Exception { // delete -> add -> add() user.setId(user.getId() + 1); // new id insertUser(user); raiseException(); // raise exception user.setUsername("update username"); updateUser(user); } }
测试类:
package com.tch.test.spring_mybatis; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.tch.test.spring_mybatis.entity.User; import com.tch.test.spring_mybatis.service.IUserService; /** * Hello world! * */ public class Test { public static void main(String[] args) throws Exception { int userId = 3; ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); IUserService service = (IUserService) context.getBean("userService"); // clear data User user = service.queryUserByID(userId); if(user != null){ service.deleteUser(user); } // insert service.insertUser(createUser(userId)); // select user = service.queryUserByID(userId); System.out.println("result after insert: " + user); // update user.setUsername("张三"); service.updateUser(user); // select user = service.queryUserByID(userId); System.out.println("result after update: " + user); // delete service.deleteUser(user); // select user = service.queryUserByID(userId); System.out.println("result after delete: " + (user == null ? "null" : user)); service.testTransaction2(createUser(userId)); // test transaction context.close(); } private static User createUser(int id) { User user = new User(); user.setId(id); user.setAge(20); user.setPassword("007"); user.setUsername("dreamoftch"); return user; } }
通过service层的testTransaction2方法 测试事务特性(出现异常的时候,是否会回滚)
OK, 自己通过测试这些方法就阔以了。。。
二:进阶篇:
下面是Mybatis 懒加载以及一对一,一对多的配置:
使用懒加载,需要在Mybatis的配置文件中开启懒加载,然后在collection/association的地方,如果需要使用懒加载,则需要指定select属性,也就是真正需要加载的时候,执行的sql statement的id,如果有参数,则通过column指定即可。
UserMapper.xml(同样的是跟UserMapper.java在同一目录下,替换前面的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"> <!-- 这里的namespace是mapper接口的全路径 --> <mapper namespace="com.tch.test.spring_mybatis.mapper.UserMapper"> <!-- 下面的select/insert/delete/update 的id和mapper接口的方法名一致,parameterType和方法的输入参数一致,resultType和方法的返回值一致 --> <resultMap type="com.tch.test.spring_mybatis.entity.User" id="userCumtom"> <id column="_user_id" property="id" /> <result column="username" property="username" /> <result column="password" property="password" /> <result column="age" property="age" /> <collection property="orders" ofType="com.tch.test.spring_mybatis.entity.Order"> <id column="orderNum" property="orderNum" /> <collection property="orderDetails" ofType="com.tch.test.spring_mybatis.entity.OrderDetail"> <id column="detail_id" property="id" /> <result column="orderNum" property="orderNum" /> <result column="item_id" property="itemId" /> <result column="itemNum" property="itemNum" /> <association property="item" javaType="com.tch.test.spring_mybatis.entity.Item"> <id column="item_id" property="id" /> <result column="itemName" property="itemName" /> <result column="price" property="price" /> </association> </collection> </collection> </resultMap> <resultMap type="com.tch.test.spring_mybatis.entity.User" id="lazyUserCumtom"> <id column="_user_id" property="id" /> <result column="username" property="username" /> <result column="password" property="password" /> <result column="age" property="age" /> <!-- 懒加载, 当需要用到该数据的时候,调用getOrdersByUser,并且用查询结果中的_user_id作为查询参数 --> <collection property="orders" ofType="com.tch.test.spring_mybatis.entity.Order" select="getOrdersByUser" column="_user_id"> </collection> </resultMap> <!-- 因为spring中配置了sqlSessionFactory的typeAliasesPackage,所以这里也可以用别名(首字母大小写都可以) --> <resultMap type="order" id="lazyOrderCustom"> <id column="orderNum" property="orderNum" /> <!-- 懒加载, 当需要用到该数据的时候,调用getOrderDetailsByOrderNum,并且用查询结果中的orderNum作为查询参数 --> <collection property="orderDetails" ofType="com.tch.test.spring_mybatis.entity.OrderDetail" select="getOrderDetailsByOrderNum" column="orderNum"> </collection> </resultMap> <resultMap type="com.tch.test.spring_mybatis.entity.OrderDetail" id="lazyOrderDetailCumtom"> <id column="detail_id" property="id" /> <result column="orderNum" property="orderNum" /> <result column="itemId" property="itemId" /> <result column="itemNum" property="itemNum" /> <!-- 懒加载, 当需要用到item属性时, 调用同一namespace下的getItemById的select语句,并且将当前sql查询出来的itemId(如果该字段在多个表中有重名,则需要在sql中指定别名,在这里也使用该别名既可)字段作为输入参数 --> <association property="item" javaType="com.tch.test.spring_mybatis.entity.Item" select="getItemById" column="itemId"> </association> </resultMap> <resultMap type="item" id="lazyItemCumtom"> <id column="item_id" property="id" /> <result column="itemName" property="itemName" /> <result column="price" property="price" /> </resultMap> <select id="queryUserByID" parameterType="int" resultType="user"> select * from _user where id = #{id} </select> <select id="queryAllUserInfo" resultMap="userCumtom"> select u.id _user_id, detail.id detail_id, i.id item_id, * from _user u join _order o on u.id=o.userId join orderDetail detail on o.orderNum=detail.orderNum join item i on detail.itemId=i.id </select> <select id="lazyLoadUserInfo" resultMap="lazyUserCumtom"> select u.id _user_id, u.* from _user u </select> <select id="getOrdersByUser" parameterType="int" resultMap="lazyOrderCustom"> select * from _order where userId = #{userId} </select> <select id="getOrderDetailsByOrderNum" parameterType="int" resultMap="lazyOrderDetailCumtom"> select * from orderDetail where orderNum = #{orderNum} </select> <select id="getAllOrderDetails" resultMap="lazyOrderDetailCumtom"> select id detail_id, * from orderDetail </select> <select id="getItemById" parameterType="int" resultMap="lazyItemCumtom" > select * from item where id = #{id} </select> <insert id="insertUser" parameterType="com.tch.test.spring_mybatis.entity.User"> insert into _user(id, username, password, age) values(#{id}, #{username}, #{password}, #{age}) </insert> <delete id="deleteUser" parameterType="com.tch.test.spring_mybatis.entity.User"> delete from _user <where> <if test="id != null"> and id = #{id} </if> <if test="username != null"> and username = #{username} </if> <if test="password != null"> and password = #{password} </if> <if test="age != null"> and age = #{age} </if> </where> </delete> <update id="updateUser" parameterType="com.tch.test.spring_mybatis.entity.User"> update _user <set> <if test="username != null"> username = #{username}, </if> <if test="password != null"> password = #{password}, </if> <if test="age != null"> age = #{age}, </if> </set> <!-- where id = #{id} --> <where> <if test="id != null"> id = #{id} </if> </where> </update> </mapper>
sqlMapConfig.xml(可以直接放在classpath跟路径下):
<?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> <settings> <setting name="lazyLoadingEnabled" value="true" /> <setting name="aggressiveLazyLoading" value="false" /> </settings> </configuration>
上面的spring的 applicationContext.xml做一点修改:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 启动注入功能 --> <context:annotation-config /> <!-- 启动扫描component功能 --> <context:component-scan base-package="com.tch.test.spring_mybatis" /> <!-- 启动注解实物配置功能 --> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- 数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.postgresql.Driver"></property> <property name="url" value="jdbc:postgresql://localhost:5432/test"></property> <property name="username" value="postgres"></property> <property name="password" value="postgres"></property> </bean> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!--读取数据库配置文件 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 如果mapper的xml文件名字和mapper接口的名字一致,并且在同一目录下(例如UserMapper.java和UserMapper.xml),可以不配置mapperLocations, --> <property name="mapperLocations" value="classpath:**/*Mapper.xml" /> <!-- 指定别名,在mapper的xml文件中可以使用别名(例如User/user来代表com.tch.test.spring_mybatis.entity.User),提高开发效率 --> <property name="typeAliasesPackage" value="com.tch.test.spring_mybatis.entity" /> <!-- 指定mybatis配置文件位置,由于该配置文件中开启了懒加载的功能,所以需要这个配置 --> <property name="configLocation" value="sqlMapConfig.xml"></property> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 指定mapper接口包名,可以通过动态代理生成代理类,这样就可以在service层直接通过注入的方式进行dao操作了 --> <property name="basePackage" value="com.tch.test.spring_mybatis.mapper" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> <!-- <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> --> </beans>
用到的entity:
package com.tch.test.spring_mybatis.entity; import java.util.List; public class User { private int id; private String username; private String password; private int age; private List<Order> orders; 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } public List<Order> getOrders() { return orders; } public void setOrders(List<Order> orders) { this.orders = orders; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", password=" + password + ", age=" + age + ", orders=" + orders + "]"; } }
package com.tch.test.spring_mybatis.entity; import java.util.List; public class Order { private int orderNum; private int userId; private List<OrderDetail> orderDetails; public int getOrderNum() { return orderNum; } public void setOrderNum(int orderNum) { this.orderNum = orderNum; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public List<OrderDetail> getOrderDetails() { return orderDetails; } public void setOrderDetails(List<OrderDetail> orderDetails) { this.orderDetails = orderDetails; } @Override public String toString() { return "Order [orderNum=" + orderNum + ", userId=" + userId + ", orderDetails=" + orderDetails + "]"; } }
package com.tch.test.spring_mybatis.entity; public class OrderDetail { private int id; private int orderNum; private int itemId; private int itemNum; private Item item; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getOrderNum() { return orderNum; } public void setOrderNum(int orderNum) { this.orderNum = orderNum; } public int getItemId() { return itemId; } public void setItemId(int itemId) { this.itemId = itemId; } public int getItemNum() { return itemNum; } public void setItemNum(int itemNum) { this.itemNum = itemNum; } public Item getItem() { return item; } public void setItem(Item item) { this.item = item; } @Override public String toString() { return "OrderDetail [id=" + id + ", orderNum=" + orderNum + ", itemId=" + itemId + ", itemNum=" + itemNum + ", item=" + item + "]"; } }
package com.tch.test.spring_mybatis.entity; public class Item { private int id; private String itemName; private int price; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getItemName() { return itemName; } public void setItemName(String itemName) { this.itemName = itemName; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public String toString() { return "Item [id=" + id + ", itemName=" + itemName + ", price=" + price + "]"; } }
测试懒加载:
package com.tch.test.spring_mybatis; import java.util.List; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.tch.test.spring_mybatis.entity.OrderDetail; import com.tch.test.spring_mybatis.entity.User; import com.tch.test.spring_mybatis.mapper.UserMapper; import com.tch.test.spring_mybatis.service.IUserService; /** * Hello world! * */ public class Test { public static void main(String[] args) throws Exception { int userId = 3; ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); IUserService service = (IUserService) context.getBean("userService"); /*// clear data User user = service.queryUserByID(userId); if(user != null){ service.deleteUser(user); } // insert service.insertUser(createUser(userId)); // select user = service.queryUserByID(userId); System.out.println("result after insert: " + user); // update user.setUsername("张三"); service.updateUser(user); // select user = service.queryUserByID(userId); System.out.println("result after update: " + user); // delete service.deleteUser(user); // select user = service.queryUserByID(userId); System.out.println("result after delete: " + (user == null ? "null" : user));*/ // service.testTransaction2(createUser(userId)); // List<User> users = service.queryAllUserInfo(); // System.out.println(users); // List<OrderDetail> orderDetails = service.getAllOrderDetails(); // for(OrderDetail orderDetail : orderDetails){ // System.out.println(orderDetail.getItemId()); // } List<User> users = service.lazyLoadUserInfo(); for(User user : users){ System.out.println(user); } context.close(); } private static User createUser(int id) { User user = new User(); user.setId(id); user.setAge(20); user.setPassword("007"); user.setUsername("dreamoftch"); return user; } }
通过测试service层的lazyLoadUserInfo方法即可发现,在执行完lazyLoadUserInfo()方法只会,只是执行了select u.id _user_id, * from _user u 这一条SQL。
在循环体中,打印user的时候,由于调用了toString() 方法,此时发出了其他的order, orderDetail, Item 相关的 SQL。也就说明懒加载生效了。
<?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"> <!-- 这里的namespace是mapper接口的全路径 --> <mapper namespace="com.tch.test.spring_mybatis.mapper.BlogMapper"> <!-- 下面的select/insert/delete/update 的id和mapper接口的方法名一致,parameterType和方法的输入参数一致,resultType和方法的返回值一致 --> <!-- choose/when --> <select id="findActiveBlogLike" resultType="com.tch.test.spring_mybatis.entity.Blog"> SELECT * FROM blog WHERE status = 'ACTIVE' <!-- choose: 类似Java里面的switch, 都不为null的时候,哪个在前用哪个。 都为null的时候,忽略该标签 --> <choose> <when test="title != null"> AND title = #{title} </when> <when test="author != null"> AND author = #{author} </when> </choose> </select> <!-- where --> <select id="findActiveBlogLike2" resultType="com.tch.test.spring_mybatis.entity.Blog"> SELECT * FROM blog <!-- where: where 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若最后的内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除 --> <where> <if test="status != null"> AND status = #{status} </if> <if test="title != null"> AND title = #{title} </if> <if test="author != null"> AND author = #{author} </if> </where> </select> <!-- trim --> <select id="findActiveBlogLike3" resultType="com.tch.test.spring_mybatis.entity.Blog"> SELECT * FROM blog <!-- trim: 使用trim来实现和上面的where完全一样的功能 --> <trim prefix="where" prefixOverrides="AND |OR "> <if test="status != null"> AND status = #{status} </if> <if test="title != null"> AND title = #{title} </if> <if test="author != null"> AND author = #{author} </if> </trim> </select> <!-- set --> <update id="updateBlog" parameterType="com.tch.test.spring_mybatis.entity.Blog"> update blog <!-- set: set 元素会动态前置 SET 关键字,同时也会消除无关的逗号,因为用了条件语句之后很可能就会在生成的赋值语句的后面留下这些逗号 --> <set> <if test="status != null"> status = #{status}, </if> <if test="title != null"> title = #{title}, </if> </set> <where> <if test="author != null"> author = #{author} </if> </where> </update> <!-- trim --> <update id="updateBlog2" parameterType="com.tch.test.spring_mybatis.entity.Blog"> update blog <!-- trim: 实现上面set一样的功能 --> <trim prefix="SET" suffixOverrides=","> <if test="status != null"> status = #{status}, </if> <if test="title != null"> title = #{title}, </if> </trim> <where> <if test="author != null"> author = #{author} </if> </where> </update> <!-- foreach --> <select id="findActiveBlogLike4" resultType="com.tch.test.spring_mybatis.entity.Blog"> SELECT * FROM blog WHERE author in <!-- foreach: foreach 元素的功能是非常强大的,它允许你指定一个集合,声明可以用在元素体内的集合项和索引变量。它也允许你指定开闭匹配的字符串以及在迭代中间放置分隔符。这个元素是很智能的,因此它不会偶然地附加多余的分隔符 --> <foreach item="author" index="index" collection="authors" open="(" separator="," close=")"> #{author} </foreach> </select> </mapper>
package com.tch.test.spring_mybatis.entity; public class Blog { private String state; private String title; private String author; public String getState() { return state; } public void setState(String state) { this.state = state; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } @Override public String toString() { return "Blog [state=" + state + ", title=" + title + ", author=" + author + "]"; } }
package com.tch.test.spring_mybatis.mapper; import java.util.List; import org.apache.ibatis.annotations.Param; import com.tch.test.spring_mybatis.entity.Blog; public interface BlogMapper { void updateBlog(@Param("status") String status, @Param("author") String author, @Param("title") String title); void updateBlog2(@Param("status") String status, @Param("author") String author, @Param("title") String title); List<Blog> findActiveBlogLike(@Param("status") String status, @Param("author") String author, @Param("title") String title); List<Blog> findActiveBlogLike2(@Param("status") String status, @Param("author") String author, @Param("title") String title); List<Blog> findActiveBlogLike3(@Param("status") String status, @Param("author") String author, @Param("title") String title); List<Blog> findActiveBlogLike4(@Param("authors") List<String> authors); }
测试:
package com.tch.test.spring_mybatis; import java.util.ArrayList; import java.util.List; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.tch.test.spring_mybatis.entity.Blog; import com.tch.test.spring_mybatis.entity.User; import com.tch.test.spring_mybatis.mapper.BlogMapper; /** * Hello world! * */ public class Test { public static void main(String[] args) throws Exception { int userId = 3; ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); BlogMapper blogMapper = context.getBean(BlogMapper.class); List<String> authors = new ArrayList<String>(); authors.add("chaohui-1"); authors.add("chaohui-2"); List<Blog> blogs = blogMapper.findActiveBlogLike4(authors); System.out.println(blogs); // blogMapper.updateBlog2("ACTIVE", "chaohui-1", "title-1"); /*// clear data User user = service.queryUserByID(userId); if(user != null){ service.deleteUser(user); } // insert service.insertUser(createUser(userId)); // select user = service.queryUserByID(userId); System.out.println("result after insert: " + user); // update user.setUsername("张三"); service.updateUser(user); // select user = service.queryUserByID(userId); System.out.println("result after update: " + user); // delete service.deleteUser(user); // select user = service.queryUserByID(userId); System.out.println("result after delete: " + (user == null ? "null" : user));*/ // service.testTransaction2(createUser(userId)); // List<User> users = service.queryAllUserInfo(); // System.out.println(users); // List<OrderDetail> orderDetails = service.getAllOrderDetails(); // for(OrderDetail orderDetail : orderDetails){ // System.out.println(orderDetail.getItemId()); // } // List<User> users = service.lazyLoadUserInfo(); // for(User user : users){ // System.out.println(user); // } context.close(); } private static User createUser(int id) { User user = new User(); user.setId(id); user.setAge(20); user.setPassword("007"); user.setUsername("dreamoftch"); return user; } }
相关推荐
SSM(Spring、SpringMVC和MyBatis)整合是Java Web开发中常见的技术栈,它结合了Spring框架的强大功能,SpringMVC的优雅请求处理,以及MyBatis的灵活数据库操作。本项目是一个入门级别的实例,旨在帮助初学者理解和...
4. **Spring与MyBatis整合**:Spring MyBatis教程会讲解如何将Spring的依赖注入和事务管理与MyBatis的SQL映射相结合,实现更灵活的数据访问。这包括配置MyBatis的SqlSessionFactory,创建Mapper接口,以及使用`@...
总的来说,《Spring Mybatis入门》这本书涵盖了从基础理论到实战应用的全过程,是学习Spring和Mybatis整合的良好起点。通过学习,你可以掌握如何在Java Web应用中优雅地管理数据库操作,提升开发效率。
9. MyBatis与Spring整合 - 使用Spring的`SqlSessionFactoryBean`来创建SqlSessionFactory。 - 使用`@Autowired`注入Mapper接口,Spring会自动处理Mapper的实例化和依赖注入。 - 配置Mapper扫描,Spring会自动加载...
此外,了解Spring框架整合MyBatis及Spring MVC的细节,对于开发基于Java EE的企业级应用非常关键。Spring MVC负责Web层的请求处理,MyBatis则是持久层框架,能够简化数据库操作。熟练掌握这些框架的整合使用,能够...
【Maven+SpringMVC+MyBatis整合入门Demo】是一个经典的Java Web开发教程,它通过集成这三大框架,帮助初学者快速理解如何构建一个具备基本功能的Web应用。在这个项目中,主要涉及了以下几个核心知识点: 1. **Maven...
3. **SSM整合**:Spring与Mybatis的整合,通常通过Spring的SqlSessionFactoryBean和Mybatis的Mapper接口来实现。Spring会管理Mybatis的SqlSession,提供事务控制,并通过MapperScannerConfigurer扫描包下的Mapper...
以上就是Spring Boot整合Mybatis的基础步骤。这个Demo展示了如何从零开始搭建一个简单的数据查询应用。随着需求的增加,你可以添加更多的Mapper接口和XML文件,以处理更复杂的业务逻辑。同时,Spring Boot还提供了...
这个压缩包提供了一个完整的SSM整合实例,包括了所有必要的Spring库和Mybatis库,对于初学者或者开发者来说,是一个很好的入门资源。 Spring框架是Java企业级应用的核心组件,它提供了依赖注入(Dependency ...
这个实例是初学者了解Spring MVC与MyBatis整合的良好起点,但仍有提升空间。例如,可以进一步封装DAO层,使用MyBatis的注解进行更简洁的配置,或者引入Spring Data JPA来替代MyBatis,简化数据访问层。此外,还可以...
在"Spring和Mybatis整合的demo"中,我们会看到如何将两者结合使用,实现更高效的数据访问: 1. **Mybatis的SqlSessionFactoryBean**:在Spring中配置,用于创建SqlSessionFactory。 2. **MapperScannerConfigurer**...
通过整合Spring框架,可以更好地管理数据库连接和事务,同时也使得MyBatis的应用更加符合企业级开发的标准。集成过程包括配置Spring的XML文件,以及在Spring中配置数据源、事务管理器和MyBatis的SqlSessionFactory等...
本教程通过"spring_mybatis.rar"压缩包,将详细讲解如何将Spring和MyBatis整合,实现数据库的增删改查操作,适合初学者入门。 首先,我们需要理解Spring和MyBatis的整合原理。Spring通过SqlSessionFactoryBean和...
这份文档名为《Java EE 框架整合开发入门到实战——Spring+Spring MVC+MyBatis(微课版)课后习题答案.pdf》,它显然是关于Java EE中流行的三个框架整合使用的教程。这三个框架分别是Spring、Spring MVC和MyBatis,...
《Spring与MyBatis整合详解及1.2.0版本资源包下载指南》 在Java Web开发领域,Spring框架和MyBatis持久层框架的整合是常见且实用的技术栈。Spring以其强大的依赖注入和管理能力,搭配MyBatis的灵活数据库操作,能够...
《Spring与MyBatis整合详解及资源包下载指南》 在Java开发领域,Spring框架以其强大的功能和灵活性,成为企业级应用开发的首选。而MyBatis作为一个优秀的持久层框架,以其简洁高效的SQL操作和对象关系映射能力,...
SSM整合,即Spring MVC、Spring和MyBatis三大框架的集成,是Java Web开发中常用的一种技术栈,尤其适用于构建复杂的企业级应用。这里我们将深入探讨如何将这三个组件结合在一起,实现一个简单的功能,帮助初学者入门...
将 Spring MVC 与 MyBatis 整合,通常我们需要以下步骤: 1. **引入依赖**:在项目中添加 Spring MVC 和 MyBatis 相关的 Maven 或 Gradle 依赖。 2. **配置 Spring**:创建 Spring 配置文件,配置 ...
Mybatis的配置文件会与Spring整合,将Mapper接口和XML配置映射到Spring Bean中,实现DAO层的无代码侵入式操作。 在实际开发中,一般步骤如下: 1. 配置Spring的IoC容器,定义Bean的定义和依赖关系。 2. 配置...