MyBatis


1. jdbc 编程

1.1 优点

  • 编程简单
  • 效率高(无论是任何的数据访问框架都不可能比jdbc的效率高)

1.2 缺点

  • 数据库的连接频繁的关闭,造成资源的浪费

    解决方案:数据库的连接池(dbcp c3p0..)

  • sql 语句存在硬编码,如果要修改需求,那就要修改 sql 语句,而 sql 语句又是在 java 代码中,我们改变了 Java 代码就要重新编译java 代码,不易于维护

    解决方案:(设想—>不要把 sql 语句写在 java 代码中)


2. mybatis 的架构

SqlMapConfig(配置信息的封装对象)--->SqlSessionFactory--->SqlSession--->Excecutor--->mapstatement

image-20220402185952649


3. mybatis到底是什么?

  • 数据持久层(dao)的解决方案
  • 解决了jdbc硬编码与连接对象频繁创建的问题

4. mybatis入门程序(了解)

4.1 修改maven编译jdk的版本

conf/settings.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<profiles>
<profile>
<id>development-jdk-1.8</id>
<activation>
<jdk>1.8</jdk>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>

4.2 mybatis依赖的pom

1
2
3
4
5
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>

4.3 配置日志文件(先不管)

1
2
3
4
5
6
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.rootLogger=debug, stdout

4.4 创建mybatis的配置文件

SqlMapConfig.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/up2"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="sqlmap/UserMapper.xml"></mapper>
</mappers>
</configuration>

4.5 创建映射(mapper)文件

1
2
3
4
5
6
7
8
9
<?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="test">
<select id="findUserById" parameterType="int" resultType="int">
select age from user where id=#{id}
</select>
</mapper>

4.6 运行程序

  • 创建配置文件SqlMapConfig,用来初始化SqlSessionFactory对象
  • 创建编写sql语句的xml文件(映射文件)
  • 创建SqlSessionFactory对象
  • 创建SqlSession对象
  • 使用SqlSession对象执行MapStatement(对映射文件的封装)
1
2
3
4
5
6
7
8
9
10
11
InputStream conf = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(conf);
//使用会话工厂创建会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//使用会话对象执行sql语句(MapStatement)
Object obj = sqlSession.selectOne("test.findAgeById", 1);
System.out.println(obj);
//提交事务
sqlSession.commit();
sqlSession.close();

5. 常用参数

  • namespace 命名空间(表示一组MapStatement)
  • id:一个statement的唯一标识
  • parameterType:输入参数的类型(java中的数据类型或者mybatis中的数据类型),一般不用指定,mybatis会根据传递的参数自动推荐类型;
  • resultType:输出参数的类型(java中的数据类型或者mybatis中的数据类型),只是指定类型,和查询出来的数量无关 注意:(resultType只能给select类型的statement来进行使用)

6. 解决mybatis中查询中文出现的问题(8.x以下的版本)

1
2
3
4
5
6
7
8
9
10
11
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/up2?characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>

7. 查询多条记录

1
2
3
/**使用selectOne(id,param);查询的结果如果是多条则会出现一些错误,使用selectList(id)即可查询多条记录
*/
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2

8. 模糊查询

1
2
3
4
5
<!--想象的模糊查询-->
<select id="findUserByNameOfLike" parameterType="string" resultType="com.uplooking.mybatis.pojo.User">
select * from user where name like #{name}
</select>
<!--想象的模糊查询是存在问题的,因为参数一般是用户输入的,用户会输入通配符 % _吗?
1
2
3
4
<!--我们改进之后变成以下这样了-->
<select id="findUserByNameOfLike" parameterType="string" resultType="com.uplooking.mybatis.pojo.User">
select * from user where name like '%#{name}%'
</select>

终极解决方案

只有一个输入参数时要使用 value

1
2
3
<select id="findUserByNameOfLike" parameterType="string" resultType="com.uplooking.mybatis.pojo.User">
select * from user where name like "%${value}%"
</select>
1
2
3
<select id="findUserByNameOfLike" parameterType="string" resultType="com.uplooking.mybatis.pojo.User">
select * from user where name like "%"#{name}"%"
</select>

9. ${} 与 #{}

  • #{}:以占位符的形式进行填充(可以避免 sql 注入,推荐使用)

  • ${}:以普通字符串的形式进行填充


10. 添加用户

1
2
3
<insert id="addUser" parameterType="com.uplooking.mybatis.pojo.User">
INSERT into user VALUES (null,#{name},#{age})
</insert>
1
2
3
4
5
6
7
8
9
public void testAddUser() {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setName("小红");
user.setAge(29);
sqlSession.insert("test.addUser", user);
sqlSession.commit();
sqlSession.close();
}

11. mybatis 与 hibernate 的区别

11.1 mybatis

  • 入门简单,程序容易上手开发,节省开发成本
  • mybatis 需要程序员自己编写sql语句 是一个不完全的ORM框架 ,对sql修改和优化非常容易实现
  • mybatis 适合开发需求变更频繁的系统,比如:互联网项目

11.2 hibernate

  • 入门门槛高 ,如果用 hibernate 写出高性能的程序不容易实现。hibernate不用写sql语句
  • hibernate适合需求固定,对象数据模型稳定,中小型项目,比如:企业OA系统。

总之,企业在技术选型时根据项目实际情况,以降低成本和提高系统 可维护性为出发点进行技术选型。


12. mybatis开发dao

12.1 传统的方式开发dao(了解)

1
2
3
4
5
/*定义接口*/
public interface UserDao {
void addUser(User user);
void deleteUser(Integer id);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*定义实现类*/
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;

public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}

@Override
public void addUser(User user) {
SqlSession session = sqlSessionFactory.openSession();
session.insert("test.addUser", user);
session.commit();
session.close();
}

@Override
public void deleteUser(Integer id) {
}
}
1
2
3
4
5
6
7
8
9
public void testAddUser() {
//sqlSession = sqlSessionFactory.openSession();
//sqlSession.insert("test.addUser", user);
User user = new User();
user.setName("小红");
user.setAge(29);
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
userDao.addUser(user);
}

12.2 使用 mapper 代理的方式开发dao(重要)

1
2
3
程序员只需要写 dao 接口,dao 接口实现对象由 mybatis 自动生成代理对象

相比传统的方式开发更加简单,且传统的 dao 开发中存在硬编码(statement_id)

使用 mapper 代理的方式开发 dao 层要遵循一些规范:

  1. mapper.xml文件名和接口的名称保持一致
  2. mapper.xml中namespace指定为mapper接口的全限定名
  3. mapper.xml中statement的id就是mapper.java中方法名
  4. mapper.xml中statement的parameterType和mapper.java中方法输入参数类型一致
  5. mapper.xml中statement的resultType和mapper.java中方法返回值类型一致.

12.2.1 创建 mapper 接口

1
2
3
4
5
6
package com.uplooking.mybatis.mapper;
import com.uplooking.mybatis.pojo.User;
public interface UserMapper {
void addUser(User user);
void deleteUser(Integer id);
}

12.2.2 创建 mapper.xml

1
2
3
4
5
6
7
8
9
10
11
<?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="com.uplooking.mybatis.mapper.UserMapper">
<insert id="addUser" parameterType="com.uplooking.mybatis.pojo.User">
insert into user values(null,#{name},#{age});
</insert>

<delete id="deleteUser"></delete>
</mapper>

12.2.3 配置 SqlMapConfig

1
2
3
4
5
6
<mappers>
<!--以下方式标识mapper的路径,只适用于mapper.xml和mapper接口在同一个目录下面的情况(这种方式已经不推荐大家使用了,一般我们不会放在同一个包下,mapper.xml我们都会单独放在resources中)-->
<package name="com.uplooking.mybatis.mapper"></package>

<!--如果接口和xml文件不再同一个目录下,则要使用 <mapper resource="mappers/UserMapper.xml" 来进行指定mapper.xml的路径,但是大家也发现一个问题,如果xml文件过多,这种方式配置起来不是很方便,但是这种方式不能使用通配符来进行指定,我们会在后面整合Spring的时候,在Spring整合mybatis的jar包中SqlSessionFactoryBean来使用通配符指定-->
</mappers>

12.2.4 maven 不认识 mapper.xml 解决方案

pom.xml

1
2
3
4
5
6
7
8
9
10
11
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>

12.2.5 测试运行

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void addUser() throws Exception {
InputStream conf = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(conf);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setName("小红红红");
user.setAge(12);
mapper.addUser(user);
sqlSession.close();
}

13. 数据库和实体类映射的业内的共识规范

  • 表名小写, User.java—>user EduUser.java—>edu_user
  • 属性名称, name—->name userName—>user_name

注意: 数据库中的明和字段名称一般不使用大写


14. mybatis中的别名

14.1 系统定义的别名

1
2
3
4
5
_byte--->byte
_long--->long
_short--->short
_int--->int
........

14.2 自定义别名

SqlMapConfig.xml

单独指定某个类的别名

1
2
3
<typeAliases>
<typeAlias type="com.uplooking.mybatis.pojo.User" alias="user"></typeAlias>
</typeAliases>

注意: 标签必须放在之前

给指定包全部生成别名,默认是简单类名或者简单类名的小写(小驼峰)

1
<package name="com.xzy.mybatis.entity"/>

14.3 使用别名

1
2
3
<select id="findUserById" resultType="user" parameterType="int">
select * from user where id=#{value}
</select>

15. mybatis中的返回值

15.1 简单类型的返回值

1
2
3
<select id="findUserById" resultType="string" parameterType="int">
select name from user where id=#{value}
</select>

15.2 复杂类型的返回值

1
2
3
<select id="findUserById" resultType="com.uplooking.mybatis.pojo.User" parameterType="int">
select * from user where id=#{value}
</select>

15.3 resultMap映射

1
2
3
4
5
6
7
8
9
<resultMap id="user1ResultMapping" type="com.uplooking.mybatis.pojo.User1">
<id property="uid" column="id"></id>
<result property="uname" column="name"></result>
<result property="uage" column="age"></result>
</resultMap>

<select id="findUserById" resultType="user1ResultMapping" parameterType="int">
select * from user where id=#{value}
</select>
  • resultType :指定输出结果的类型(pojo、简单类型、hashmap..),将sql查询结果映射为java对象
  • 使用resultType注意:sql查询的列名要和resultType指定pojo的属性名相同,指定相同属性方可映射成功,如果sql查询的列名要和resultType指定pojo的属性名全部不相同,list中无法创建pojo对象的。
  • resultMap:将sql查询结果映射为java对象。
  • 如果sql查询列名和最终要映射的pojo的属性名不一致,使用resultMap将列名和pojo的属性名做一个对应关系 (列名和属性名映射配置)

16. 动态sql(重点)

mybatis重点是对sql的灵活解析和处理

16.1 where…if 语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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="com.xzy.mapper.UserMapper">

<select id="listByUser" parameterType="com.xzy.entity.User" resultType="com.xzy.entity.User">
select *
from user
<where>
<if test="nickname!=null">
nickname = #{nickname}
</if>
<if test="password!=null">
and password=#{password}
</if>
</where>
</select>
</mapper>

注意: where紧跟着的and或者or会被省略


16.2 foreach 语句(了解)

foreach 元素的属性主要有 item,index,collection,open,separator,close

  • collection接收一个集合为参数时 collection的值为list

    1
    2
    3
    4
    5
    select * from user
    <where>
    <foreach collection="list" item="id" open="id in ("separator="," close=")">
    #{id}
    </foreach>
  • item表示集合中每一个元素进行迭代时的别名,

  • index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,

  • open表示该语句以什么开始,

  • separator表示在每次进行迭代之间以什么符号作为分隔符,

  • close表示以什么结束

1
2
3
4
5
6
7
8
9
<select id="findUsers" resultType="com.uplooking.mybatis.pojo.User"
parameterType="com.uplooking.mybatis.pojo.UserCustom">
select * from user
<where>
<foreach collection="list" item="id" open="id in ("separator="," close=")">
#{id}
</foreach>
</where>
</select>
1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void testFindUsers() throws IOException {
InputStream conf = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(conf);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
UserCustom userCustom = new UserCustom();
userCustom.setIds(Arrays.asList(1,2,3));
List<User> users = mapper.findUsers(userCustom);
System.out.println(users);
}

16.3 if + set + where语句 (主要用来更新)

1
2
3
4
5
6
7
8
9
10
11
<update id="updateUsername" parameterType="com.uplooking.mybatis.pojo.User">
update user
<set>
<if test="name!=null">
name=#{name}
</if>
</set>
<where>
id=#{id}
</where>
</update>
1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void testupdateUser() throws IOException {
InputStream conf = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(conf);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(1);
user.setName("xiaohuahua1");
mapper.updateUsername(user);
}

16.4 choose+when+otherwise

1
2
3
4
5
6
7
8
9
10
11
12
13
<where>
<choose>
<when test="条件">
sql语句
</when>
<when test="条件">
sql语句
</when>
<otherwise>
sql语句
</otherwise>
</choose>
</where>

17. mybatis中接收多个参数(重要)

可以接收一个参数 也可以接收多个参数

17.1 接收普通的单一参数

1
2
3
public interface UserMapper {
User findById(Integer id);
}
1
2
3
4
5
<select id="findById" parameterType="int" resultType="com.xzy.entity.User">
select *
from user
where id = #{value }
</select>

17.2 接收对象类型的参数

1
2
3
public interface UserMapper {
User findByUser(User user);
}
1
2
3
4
5
<select id="findByUser" parameterType="com.xzy.entity.User" resultType="com.xzy.entity.User">
select *
from user
where nickname = #{nickname}
</select>

17.3 接收多个参数

1
List<User> findByNicknameOrPassword(String nickname, String password);
1
2
3
4
5
6
<select id="findByNicknameOrPassword" resultType="com.xzy.entity.User">
select *
from user
where nickname = #{param1}
or password = #{param2}
</select>

但是我们上面使用param1和param2…来接收形参数据,名称不太友好(不能见名知意) ,所有Mybatis中给我们提供了一个注解 @Param("xxx"),我们可以使用这个注解表示形参名称,来给mybatis使用;

1
2
3
public interface UserMapper {
List<User> findByNicknameOrPassword(@Param("nickname") String nickname, @Param("password") String password);
}
1
2
3
4
5
6
<select id="findByNicknameOrPassword" resultType="com.xzy.entity.User">
select *
from user
where nickname = #{nickname}
or password = #{password}
</select>

18. mybatis中的结果映射

18.1 一对一的映射

一对一的关系在实际开发中很少见,因为一对一的关系我们都会直接搞成一个附加的字段	
18.1.1 创建pojo类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.xzy.entity;

public class User {
private Integer id;
private String nickname;
private String password;
private Address address;

public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}

@Override
public String toString() {
return "User{" +
"id=" + id +
", nickname='" + nickname + '\'' +
", password='" + password + '\'' +
", address=" + address +
'}';
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getNickname() {
return nickname;
}

public void setNickname(String nickname) {
this.nickname = nickname;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.xzy.entity;

public class Address {
private Integer id;
private String prov;
private String city;

@Override
public String toString() {
return "Address{" +
"id=" + id +
", prov='" + prov + '\'' +
", city='" + city + '\'' +
'}';
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getProv() {
return prov;
}

public void setProv(String prov) {
this.prov = prov;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}
}
18.1.2 创建mapper接口
1
2
3
public interface UserMapper {
User findUserById(Integer id);
}
18.1.3 创建mapper映射
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?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="com.xzy.mapper.UserMapper">

<select id="findByNicknameOrPassword" resultType="com.xzy.entity.User">
select *
from user
where nickname = #{nickname}
or password = #{password}
</select>

<resultMap id="userAddressMap" type="com.xzy.entity.User">
<id property="id" column="id"></id>
<result property="nickname" column="nickname"></result>
<result property="password" column="password"></result>
<!--一对一的关系-->
<association property="address" javaType="com.xzy.entity.Address">
<id property="id" column="id"></id>
<result property="prov" column="prov"></result>
<result property="city" column="city"></result>
</association>

</resultMap>
<select id="findById" resultMap="userAddressMap">
select *
from user,
address
where user.id = address.id
and user.id = #{id}
</select>
</mapper>
18.1.4 执行查询
1
2
3
4
5
6
7
@Test
public void testFindUserById() throws IOException {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(1);
System.out.println(user);
}

18.2 一对多的映射

18.2.1 创建pojo类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.uplooking.mybatis.pojo;
import java.util.List;
public class User {
private Integer id;
private String name;
private Integer age;
private List<Orders> orderss;

@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", orderss=" + orderss +
", address=" + address +
'}';
}

public List<Orders> getOrderss() {
return orderss;
}

public void setOrderss(List<Orders> orderss) {
this.orderss = orderss;
}

/*一对一的映射*/
private Address address;

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 Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.uplooking.mybatis.pojo;

import java.util.Date;

public class Orders {
private Integer id;
private Integer num;
private Date createTime;

@Override
public String toString() {
return "Orders{" +
"id=" + id +
", num=" + num +
", createTime=" + createTime +
'}';
}
}

18.2.2 创建mapper接口
1
2
3
public interface UserMapper {
User findUserById(Integer id);
}
18.2.3 创建mapper映射文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<resultMap id="userAndAddressMapping" type="com.uplooking.mybatis.pojo.User">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<!--一对多的关系-->
<collection property="orderss" ofType="com.uplooking.mybatis.pojo.Orders">
<result property="num" column="num"></result>
<result property="createTime" column="createTime"></result>
</collection>
</resultMap>

<select id="findUserById" resultMap="userAndAddressMapping" parameterType="int">
select u.id,u.name,u.age,o.num,o.createtime
from user u,orders o where o.uid=u.id and u.id=#{value};
</select>
18.2.4 运行
1
2
3
4
5
6
7
@Test
public void testFindUserById() throws IOException {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(1);
System.out.println(user);
}

18.3 复杂的映射

pojo同上一样,在此只写sql和映射

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<resultMap id="userAndAddressMapping" type="com.uplooking.mybatis.pojo.User">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>

<!--一对一的关联-->
<association property="address" javaType="com.uplooking.mybatis.pojo.Address">
<result property="province" column="province"></result>
<result property="city" column="city"></result>
<result property="street" column="street"></result>
</association>


<!--一对多的关系-->
<collection property="orderss" ofType="com.uplooking.mybatis.pojo.Orders">
<result property="num" column="num"></result>
<result property="createTime" column="createTime"></result>
</collection>

</resultMap>

<select id="findUserById" resultMap="userAndAddressMapping" parameterType="int">
select u.id,u.name,u.age,o.num,o.createtime,a.province,a.city,a.street
from user u,orders o ,address a where o.uid=u.id and u.aid=a.id and u.id=#{value};
</select>

19. mybatis的逆向工程

  • mybatis官方给我们提供的一个工具
  • 用来根据表结构生成 pojo 类

19.1 依赖pom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="UTF-8"?>
<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.uplooking</groupId>
<artifactId>2018-08-21-mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>

</dependencies>
</project>

19.2 配置 generatorconfig.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?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>
<context id="generateTables" targetRuntime="MyBatis3">



<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>

<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true"/>
<property name="suppressDate" value="true"/>
</commentGenerator>

<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/up2"
userId="root"
password="root"
>
</jdbcConnection>

<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg"
userId="yycg" password="yycg"> </jdbcConnection> -->

<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL
和 NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>

<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.uplooking.pojo"
targetProject=".\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true"/>
</javaModelGenerator>

<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.uplooking.mapper"
targetProject=".\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>

<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.uplooking.mapper" targetProject=".\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>

<!-- 指定数据库表 -->
<table schema="general" tableName="user" domainObjectName="User"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="true"
selectByExampleQueryId="false">
<property name="useActualColumnNames" value="false"/>
</table>

<table schema="general" tableName="address" domainObjectName="Address"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="true"
selectByExampleQueryId="false">
<property name="useActualColumnNames" value="false"/>
</table>

</context>
</generatorConfiguration>

19.3 生成pojo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
public class Generator {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;//加载上面的配置文件
File configFile = new File("./src/main/resources/generatorconfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}

文章作者: Yang Shiyu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Yang Shiyu !
  目录