mybatis简单入门
2016-10-10 14:52
411 查看
之前我们学习了hibernate,今天我们来学习下mybatis。网上对于这两个orm框架的争论可以说很激烈,这里我们不做瑜亮之争,只是单纯的学习mybatis。
mybatis的有点:1.学习简单;2.mybatis需要手写sql(半自动化),所以调优会很简单。3.作为一个orm框架,使用方便是肯定的了。
下面我们来进行简单的学习使用mybatis。
pom.xml
mybatis的mapper文件
<?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="User">
<resultMap type="com.julyday.test_mybatis.entity.User" id="UserResult">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="age" jdbcType="INTEGER" property="age" />
</resultMap>
<sql id="col">
id,name,age
</sql>
<insert id="insert" useGeneratedKeys="true" >
insert into user(name,age) values (#{name,jdbcType=VARCHAR},#{age,jdbcType=INTEGER})
</insert>
<select id="find" resultMap="UserResult">
SELECT <include refid="col"/> FROM user WHERE id = #{id,jdbcType=INTEGER}
</select>
<select id="selectOrder" resultMap="UserResult">
SELECT <include refid="col"/> FROM user order by ${_parameter}
</select>
<select id="getList" parameterType="com.julyday.test_mybatis.entity.User" resultMap="UserResult">
SELECT <include refid="col"/> FROM user
<where>
<if test="name != null and !"".equals(name.trim())">
name = #{name,jdbcType=VARCHAR}
</if>
<if test="age > 0">
and age = #{age,jdbcType=INTEGER}
</if>
</where>
</select>
<select id="sqlInject" parameterType="User" resultMap="UserResult">
SELECT <include refid="col"/> FROM user
<where>
<if test="name != null and !"".equals(name.trim())">
name = ${name}
</if>
<if test="age > 0">
and age = #{age,jdbcType=INTEGER}
</if>
</where>
</select>
<update id="update">
update user
<set>
<if test="name != null and !"".equals(name.trim())">
name = #{name,jdbcType=VARCHAR},
</if>
<if test="age > 0">
age = #{age,jdbcType=INTEGER}
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<delete id="delete">
delete from user where id = #{id,jdbcType=INTEGER}
</delete>
</mapper>
resultMap:返回结果,type对应我们的实体,id别名。
id:表示主键
column:数据库对应字段
jdbcType:表示对应的jdbc类型,写jdbc的同学可能比较熟悉(java.sql.Types),对象的数据库类型有个对应关系,这里不多说了。
property:实体中的属性字段
sql:不是我们通常意义上的sql,他是为了简便字段使用的,当字段个数较多是很有用,同时也不会有n+1的情况出现。
insert,select,update,delete:对应的数据库操作。select中<include refid="col"/>,就是用到我们之前的sql了。
where:对应了数据库中的关键字,在这里,如果里面没有查询条件就不含where关键字,同样如果第一个含有and或者or他会去除,我们这如果name没值,age前的and会去除。
set:同where。
${}和#{}的区别:select * from user where name = ${name},当参数为字符串类型时,${name}是“julyday”,结果是select * from user where name = julyday,而#{name}的结果是select
* from user where name = 'julyday',这个就像我们在jdbc中直接字符串+ 和 setString()的对比一样,前者会出现sql注入的风险,name的传值是“'' or 1=1”,这样前一个就查了全表,后一个查询结果是0条。当然在order by的后面我们是需要用#{},不然排序是不起作用的。
这里为方便我们排查错误我们可以查看日志,但是mybatis没有像hibernate一样提供自己的日志服务,我们需要第三方的log4j来打印日志。
log4j.rootLogger=debug,stdout,logfile
### 把日志信息输出到控制台 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
### 把日志信息输出到文件:jbit.log ###
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=D:/test.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=[test_mybatis][%p] %d{yyyy-MM-dd HH:mm:ss} %F %m%n
###显示SQL语句部分
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUGlog4j的配置这里就不再赘述了。
当然mapper这个文件可以在源码的找到,不会写的朋友可以自己下载源码看下,~\src\test\java\org\apache\ibatis\submitted\complex_property下,包括下面的Configuration.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>
<!--
<settings>
<setting name="useGeneratedKeys" value="false"/>
<setting name="useColumnLabel" value="true"/>
</settings>
-->
<typeAliases>
<typeAlias alias="User" type="com.julyday.test_mybatis.entity.User"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="" value=""/>
</transactionManager>
<dataSource type="UNPOOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mybatis/User.xml"/>
</mappers>
</configuration>typeAliases:给我们的实体启一个别名
environments:数据库的配置信息
mappers:对应的mapper文件
下面是我们的测试文件:
package com.julyday.test_mybatis;
import java.io.IOException;
import java.io.Reader;
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.After;
import org.junit.Before;
import org.junit.Test;
import com.julyday.test_mybatis.entity.User;
public class TestMybatis {
private SqlSession sqlSession;
@Before
public void init() {
Reader reader;
try {
reader = Resources.getResourceAsReader("Configuration.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(reader);
sqlSession = sqlSessionFactory.openSession();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testInsert() {
User u = new User("julyday", 18);
sqlSession.insert("User.insert", u);
sqlSession.commit();
}
@Test
public void testFind() {
User u = sqlSession.selectOne("User.find", 1);
System.out.println(u);
}
@Test
public void testGetList() {
User user = new User();
//user.setAge(18);
//user.setName("julyday");
user.setName("'' or 1=1 ");
//List<User> list = sqlSession.selectList("User.getList", user);
List<User> list = sqlSession.selectList("User.sqlInject", user);
System.out.println(list.size());
for(User u : list){
System.out.println(u);
}
}
@Test
public void testSelectOrder() {
List<User> list = sqlSession.selectList("User.selectOrder", "age desc");
System.out.println(list.size());
for(User u : list){
System.out.println(u);
}
}
@Test
public void testUpdate() {
User u = sqlSession.selectOne("User.find", 1);
u.setAge(12);
sqlSession.update("User.update", u);
sqlSession.commit();
}
@Test
public void testDelete() {
sqlSession.delete("User.delete",1);
}
@After
public void destory() {
sqlSession.close();
}
}
修改<mapper namespace="com.julyday.test_mybatis.dao.UserDao">,这个命名空间必须唯一,这是反射的基础。这里就简单的看下源码就知道了,同时也会加深你对mybatis的理解。可以从ud = sqlSession.getMapper(UserDao.class);这个开始,在DefaultSqlSession类里面,当然你必须对代理和反射有一定的了解,这里简单的说下可以看MapperProxy.cachedMapperMethod()方法。
我们的测试类:
这里我放在D:\generator,写一个generator.xml
generator.xml -overwrite 这里targetProject目录是必须要存在的,可以写成你eclipse项目的路径。
这里我们就简单的说下最后一个table,很明显是数据库的表到类的映射,第一个是表名,第二个是类名,后面的根据英文大家都能猜到是干啥的,不明白的大家可以自己尝试下。多个表的话就写对个table。
实体类不看了,有需要的朋友下代码看。
mapper文件:
多对一:
最后国际惯例,贴上全部代码的git地址:代码下载地址
mybatis的有点:1.学习简单;2.mybatis需要手写sql(半自动化),所以调优会很简单。3.作为一个orm框架,使用方便是肯定的了。
下面我们来进行简单的学习使用mybatis。
一:初识mybatis
首先我们创建一个maven工程test_mybatis。pom.xml
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.1</version> </dependency> <!-- mysql连接 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.34</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
package com.julyday.test_mybatis.entity; public class User { private int id; private String name; private int age; public User() { } public User(String name, int age) { this.name = name; this.age = age; } //getter setter @Override public String toString() { return "User [id=" + id + ", name=" + name + ", age=" + age + "]"; } }
mybatis的mapper文件
<?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="User">
<resultMap type="com.julyday.test_mybatis.entity.User" id="UserResult">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="age" jdbcType="INTEGER" property="age" />
</resultMap>
<sql id="col">
id,name,age
</sql>
<insert id="insert" useGeneratedKeys="true" >
insert into user(name,age) values (#{name,jdbcType=VARCHAR},#{age,jdbcType=INTEGER})
</insert>
<select id="find" resultMap="UserResult">
SELECT <include refid="col"/> FROM user WHERE id = #{id,jdbcType=INTEGER}
</select>
<select id="selectOrder" resultMap="UserResult">
SELECT <include refid="col"/> FROM user order by ${_parameter}
</select>
<select id="getList" parameterType="com.julyday.test_mybatis.entity.User" resultMap="UserResult">
SELECT <include refid="col"/> FROM user
<where>
<if test="name != null and !"".equals(name.trim())">
name = #{name,jdbcType=VARCHAR}
</if>
<if test="age > 0">
and age = #{age,jdbcType=INTEGER}
</if>
</where>
</select>
<select id="sqlInject" parameterType="User" resultMap="UserResult">
SELECT <include refid="col"/> FROM user
<where>
<if test="name != null and !"".equals(name.trim())">
name = ${name}
</if>
<if test="age > 0">
and age = #{age,jdbcType=INTEGER}
</if>
</where>
</select>
<update id="update">
update user
<set>
<if test="name != null and !"".equals(name.trim())">
name = #{name,jdbcType=VARCHAR},
</if>
<if test="age > 0">
age = #{age,jdbcType=INTEGER}
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<delete id="delete">
delete from user where id = #{id,jdbcType=INTEGER}
</delete>
</mapper>
resultMap:返回结果,type对应我们的实体,id别名。
id:表示主键
column:数据库对应字段
jdbcType:表示对应的jdbc类型,写jdbc的同学可能比较熟悉(java.sql.Types),对象的数据库类型有个对应关系,这里不多说了。
property:实体中的属性字段
sql:不是我们通常意义上的sql,他是为了简便字段使用的,当字段个数较多是很有用,同时也不会有n+1的情况出现。
insert,select,update,delete:对应的数据库操作。select中<include refid="col"/>,就是用到我们之前的sql了。
where:对应了数据库中的关键字,在这里,如果里面没有查询条件就不含where关键字,同样如果第一个含有and或者or他会去除,我们这如果name没值,age前的and会去除。
set:同where。
${}和#{}的区别:select * from user where name = ${name},当参数为字符串类型时,${name}是“julyday”,结果是select * from user where name = julyday,而#{name}的结果是select
* from user where name = 'julyday',这个就像我们在jdbc中直接字符串+ 和 setString()的对比一样,前者会出现sql注入的风险,name的传值是“'' or 1=1”,这样前一个就查了全表,后一个查询结果是0条。当然在order by的后面我们是需要用#{},不然排序是不起作用的。
这里为方便我们排查错误我们可以查看日志,但是mybatis没有像hibernate一样提供自己的日志服务,我们需要第三方的log4j来打印日志。
log4j.rootLogger=debug,stdout,logfile
### 把日志信息输出到控制台 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
### 把日志信息输出到文件:jbit.log ###
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=D:/test.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=[test_mybatis][%p] %d{yyyy-MM-dd HH:mm:ss} %F %m%n
###显示SQL语句部分
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUGlog4j的配置这里就不再赘述了。
当然mapper这个文件可以在源码的找到,不会写的朋友可以自己下载源码看下,~\src\test\java\org\apache\ibatis\submitted\complex_property下,包括下面的Configuration.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>
<!--
<settings>
<setting name="useGeneratedKeys" value="false"/>
<setting name="useColumnLabel" value="true"/>
</settings>
-->
<typeAliases>
<typeAlias alias="User" type="com.julyday.test_mybatis.entity.User"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="" value=""/>
</transactionManager>
<dataSource type="UNPOOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mybatis/User.xml"/>
</mappers>
</configuration>typeAliases:给我们的实体启一个别名
environments:数据库的配置信息
mappers:对应的mapper文件
下面是我们的测试文件:
package com.julyday.test_mybatis;
import java.io.IOException;
import java.io.Reader;
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.After;
import org.junit.Before;
import org.junit.Test;
import com.julyday.test_mybatis.entity.User;
public class TestMybatis {
private SqlSession sqlSession;
@Before
public void init() {
Reader reader;
try {
reader = Resources.getResourceAsReader("Configuration.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(reader);
sqlSession = sqlSessionFactory.openSession();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testInsert() {
User u = new User("julyday", 18);
sqlSession.insert("User.insert", u);
sqlSession.commit();
}
@Test
public void testFind() {
User u = sqlSession.selectOne("User.find", 1);
System.out.println(u);
}
@Test
public void testGetList() {
User user = new User();
//user.setAge(18);
//user.setName("julyday");
user.setName("'' or 1=1 ");
//List<User> list = sqlSession.selectList("User.getList", user);
List<User> list = sqlSession.selectList("User.sqlInject", user);
System.out.println(list.size());
for(User u : list){
System.out.println(u);
}
}
@Test
public void testSelectOrder() {
List<User> list = sqlSession.selectList("User.selectOrder", "age desc");
System.out.println(list.size());
for(User u : list){
System.out.println(u);
}
}
@Test
public void testUpdate() {
User u = sqlSession.selectOne("User.find", 1);
u.setAge(12);
sqlSession.update("User.update", u);
sqlSession.commit();
}
@Test
public void testDelete() {
sqlSession.delete("User.delete",1);
}
@After
public void destory() {
sqlSession.close();
}
}
二:面向接口编程
package com.julyday.test_mybatis.dao; import java.util.List; import com.julyday.test_mybatis.entity.User; public interface UserDao { public void insert(User user); public User find(int id); public List<User> selectOrder(String order); public List<User> getList(User user); public List<User> sqlInject(User user); public void update(User user); public void delete(int id); }copy一下User.xml成UserDao.xml
修改<mapper namespace="com.julyday.test_mybatis.dao.UserDao">,这个命名空间必须唯一,这是反射的基础。这里就简单的看下源码就知道了,同时也会加深你对mybatis的理解。可以从ud = sqlSession.getMapper(UserDao.class);这个开始,在DefaultSqlSession类里面,当然你必须对代理和反射有一定的了解,这里简单的说下可以看MapperProxy.cachedMapperMethod()方法。
private MapperMethod cachedMapperMethod(Method method) { MapperMethod mapperMethod = methodCache.get(method); if (mapperMethod == null) { mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()); methodCache.put(method, mapperMethod); } return mapperMethod; }反射的invoke方法最后一句return mapperMethod.execute(sqlSession, args);就是正文了,MapperMethod这个类就是他的庐山真面目了,后面根据我们的sql类型找到对应的分支看下。这个就不继续下去了。
我们的测试类:
package com.julyday.test_mybatis; import java.io.IOException; import java.io.Reader; 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.After; import org.junit.Before; import org.junit.Test; import com.julyday.test_mybatis.dao.UserDao; import com.julyday.test_mybatis.entity.User; public class TestDao { private SqlSession sqlSession; private UserDao ud ; @Before public void init() { Reader reader; try { reader = Resources.getResourceAsReader("Configuration.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(reader); sqlSession = sqlSessionFactory.openSession(); ud = sqlSession.getMapper(UserDao.class); } catch (IOException e) { e.printStackTrace(); } } @Test public void testInsert() { User u = new User("zhangsan", 28); ud.insert(u); sqlSession.commit(); } @Test public void testFind() { User u = ud.find(1); System.out.println(u); } @Test public void testGetList() { User user = new User(); //user.setAge(18); //user.setName("julyday"); user.setName("'' or 1=1 "); //List<User> list =ud.getList(user); List<User> list = ud.sqlInject(user); System.out.println(list.size()); for(User u : list){ System.out.println(u); } } @Test public void testSelectOrder() { List<User> list = ud.selectOrder("age desc"); System.out.println(list.size()); for(User u : list){ System.out.println(u); } } @Test public void testUpdate() { User u = ud.find(1); u.setAge(19); ud.update(u); sqlSession.commit(); } @Test public void testDelete() { ud.delete(3); sqlSession.commit(); } @After public void destory() { sqlSession.close(); } }
三:mybatis自动化工具类generator
首先是jar包的下载:mybatis-generator-core-1.3.2.jar。jar下载这里我放在D:\generator,写一个generator.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!-- 数据库驱动包位置 --> <classPathEntry location="D:\generator\mysql-connector-java-5.1.34.jar" /> <!-- <classPathEntry location="C:\oracle\product\10.2.0\db_1\jdbc\lib\ojdbc14.jar" />--> <context id="DB2Tables" targetRuntime="MyBatis3"> <!-- 是否去除自动生成的注释 true:是 : false:否 --> <commentGenerator> <property name="suppressAllComments" value="true" /> </commentGenerator> <!-- 数据库链接URL、用户名、密码 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root" password="root"> <!--<jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@localhost:1521:orcl" userId="msa" password="msa">--> </jdbcConnection> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- 生成模型的包名和位置 --> <javaModelGenerator targetPackage="com.julyday.test_mybatis.entity" targetProject="D:\generator\src"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- 生成的映射文件包名和位置 --> <sqlMapGenerator targetPackage="mybatis" targetProject="D:\generator\src"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!-- 生成DAO的包名和位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.julyday.test_mybatis.dao" targetProject="D:\generator\src"> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <!-- 要生成那些表(更改tableName和domainObjectName就可以) --> <table tableName="user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" /> </context> </generatorConfiguration>然后就是执行了,java -jar mybatis-generator-core-1.3.2.jar -configfile
generator.xml -overwrite 这里targetProject目录是必须要存在的,可以写成你eclipse项目的路径。
这里我们就简单的说下最后一个table,很明显是数据库的表到类的映射,第一个是表名,第二个是类名,后面的根据英文大家都能猜到是干啥的,不明白的大家可以自己尝试下。多个表的话就写对个table。
四:表关联关系
一对多:实体类不看了,有需要的朋友下代码看。
mapper文件:
<?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="Student"> <resultMap type="com.julyday.test_mybatis.entity.Student" id="StudentResult"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="age" jdbcType="INTEGER" property="age" /> <result column="gid" jdbcType="INTEGER" property="gid" /> </resultMap> <select id="find" resultMap="StudentResult"> SELECT id,name,age,gid FROM student WHERE id = #{id,jdbcType=INTEGER} </select> </mapper>
<?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="Grade"> <resultMap type="com.julyday.test_mybatis.entity.Grade" id="GradeResult"> <id column="g_id" jdbcType="INTEGER" property="id" /> <result column="gname" jdbcType="VARCHAR" property="gname" /> <result column="gdesc" jdbcType="VARCHAR" property="gdesc" /> <collection property="students" resultMap="Student.StudentResult" /> <!-- <collection property="students" ofType="com.julyday.test_mybatis.entity.Student" column="gid"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="age" jdbcType="INTEGER" property="age" /> <result column="gid" jdbcType="INTEGER" property="gid" /> </collection>--> </resultMap> <select id="find" resultMap="GradeResult"> SELECT id as g_id,gname,gdesc FROM grade WHERE id = #{id,jdbcType=INTEGER} </select> <select id="findAll" parameterType="com.julyday.test_mybatis.entity.Grade" resultMap="GradeResult"> SELECT g.id as g_id,g.gname,g.gdesc,s.id,s.name,s.age,s.gid FROM Grade g left join student s on g.id = s.gid where g.id=#{id,jdbcType=INTEGER} </select> </mapper>一对多,一的一方用collection,两种collection任选一个。
@Test public void testFindall() { Grade grade = new Grade(); grade.setId(1); List<Grade> list = sqlSession.selectList("Grade.findAll",grade); for(Grade g : list){ System.out.println(g.toString()); List<Student> ls = g.getStudents(); for(Student s : ls){ System.out.println(s.toString()); } } }测试没问题。
多对一:
<?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="Order"> <resultMap type="com.julyday.test_mybatis.entity.Order" id="OrderResult"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> </resultMap> <select id="find" resultMap="OrderResult"> SELECT id,name FROM orders WHERE id = #{id,jdbcType=INTEGER} </select> </mapper>
<?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="Product"> <resultMap type="com.julyday.test_mybatis.entity.Product" id="ProductResult"> <id column="p_id" jdbcType="INTEGER" property="id"/> <result column="p_name" jdbcType="VARCHAR" property="name"/> <result column="price" jdbcType="INTEGER" property="price"/> <result column="oid" jdbcType="INTEGER" property="oid"/> <association property="order" javaType="com.julyday.test_mybatis.entity.Order"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> </association> <!-- <association property="order" resultMap="Order.OrderResult"/>--> </resultMap> <select id="find" resultMap="ProductResult"> SELECT id as p_id,name as p_name,price,oid FROM product WHERE id = #{id,jdbcType=INTEGER} </select> <select id="findAll" resultMap="ProductResult"> SELECT p.id as p_id,p.name as p_name,p.price,p.oid,o.id,o.name FROM product p right join orders o on p.oid = o.id WHERE p.id = #{id,jdbcType=INTEGER} </select> </mapper>多对一,用association,同样的两个association选一个。
@Test public void testFindall() { Product product = new Product(); product.setId(3); List<Product> list = sqlSession.selectList("Product.findAll",product); for(Product p : list){ System.out.println(p.toString()); Order o = p.getOrder(); System.out.println(o.toString()); } }测试OK.
最后国际惯例,贴上全部代码的git地址:代码下载地址
相关文章推荐
- Mybatis简单入门
- SpringMVC入门二: 1规范结构, 2简单整合MyBatis
- 史上最简单的MyBatis动态SQL入门示例代码
- bc94 老司机学习MyBatis教程之MyBatis基础篇简单入门HelloWorld
- MyBatis 学习总结(一)——MyBatis 简单介绍及快速入门
- springboot+mybatis的简单的入门例子
- Mybatis入门和简单Demo
- 一、MyBatis简单入门
- 这是mybatis最简单的入门
- spring整合mybatis(入门级简单教程1)--在spring中配置c3p0,并成功测试
- Mybatis简单的入门之增删改查
- mybatis入门之简单操作
- spring boot+mybatis+mysql 简单入门
- spring整合mybatis(入门级简单教程2)
- JAVA之Mybatis基础入门--框架搭建与简单查询
- JAVA入门[6]-Mybatis简单示例
- MyBatis简单入门
- spring整合mybatis(入门级简单教程3)--获取sqlSession对象
- Mybatis 3.2.7 简单入门Demo
- mybatis简单入门和介绍 mybatis教程