天天看点

mybatis 详解(二)------入门实例(基于XML)

通过上一小节,我们对 mybatis有了一个大致的了解,下面我们通过一个入门实例来对mybatis有更近一步的了解。

  我们用 mybatis 来对 user 表进行增删改查操作。

   ps:本篇博客源代码链接:http://pan.baidu.com/s/1eSEfc8i 密码:j480

1、创建MySQL数据库:mybatisDemo和表:user

  这里我们就不写脚本创建了,创建完成后,再向其中插入几条数据即可。

  user 表字段如下:

  

mybatis 详解(二)------入门实例(基于XML)
mybatis 详解(二)------入门实例(基于XML)

2、建立一个Java工程,并导入相应的jar包,具体目录如下

  注意:log4j和Junit不是必须的,但是我们为了查看日志以及便于测试,加入了这两个jar包

mybatis 详解(二)------入门实例(基于XML)

3、在 MyBatisTest 工程中添加数据库配置文件 mybatis-configuration.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

<?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标签,当mybatis和spring整合之后,这个标签是不用配置的 -->

<!-- 可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境  

一、development:开发模式

二、work:工作模式-->

<environments

default

=

"development"

>

<!--id属性必须和上面的

default

一样  -->

<environment id=

"development"

>

<!--事务管理器

一、JDBC:这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围

二、MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期

比如 spring 或 JEE 应用服务器的上下文,默认情况下,它会关闭连接。然而一些容器并不希望这样,

因此如果你需要从连接中停止它,就可以将 closeConnection 属性设置为

false

,比如:

<transactionManager type=

"MANAGED"

>

<property name=

"closeConnection"

value=

"false"

/>

</transactionManager>

-->

<transactionManager type=

"JDBC"

/>

<!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源  -->

<dataSource type=

"POOLED"

>

<property name=

"driver"

value=

"com.mysql.jdbc.Driver"

/>

<property name=

"url"

value=

"jdbc:mysql://localhost:3306/mybatisdemo"

/>

<property name=

"username"

value=

"root"

/>

<property name=

"password"

value=

"root"

/>

</dataSource>

</environment>

</environments>

</configuration>

4、定义表所对应的实体类

mybatis 详解(二)------入门实例(基于XML)

34

35

36

37

38

39

40

41

42

43

44

45

46

package

com.ys.po;

import

java.util.Date;

public

class

User {

private

int

id;

private

String username;

private

String sex;

private

Date birthday;

private

String address;

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 getSex() {

return

sex;

}

public

void

setSex(String sex) {

this

.sex = sex;

}

public

Date getBirthday() {

return

birthday;

}

public

void

setBirthday(Date birthday) {

this

.birthday = birthday;

}

public

String getAddress() {

return

address;

}

public

void

setAddress(String address) {

this

.address = address;

}

@Override

public

String toString() {

return

"User [id="

+ id +

", username="

+ username +

", sex="

+ sex

+

", birthday="

+ birthday +

", address="

+ address +

"]"

;

}

}

5、定义操作 user 表的sql映射文件userMapper.xml  

mybatis 详解(二)------入门实例(基于XML)

47

48

49

50

51

52

<?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.ys.po.userMapper"

>

<!-- 根据 id 查询 user 表中的数据

id:唯一标识符,此文件中的id值不能重复

resultType:返回值类型,一条数据库记录也就对应实体类的一个对象

parameterType:参数类型,也就是查询条件的类型

-->

<select id=

"selectUserById"

resultType=

"com.ys.po.User"

parameterType=

"int"

>

<!-- 这里和普通的sql 查询语句差不多,对于只有一个参数,后面的 #{id}表示占位符,里面不一定要写id,写啥都可以,但是不要空着,如果有多个参数则必须写pojo类里面的属性 -->

select * from user where id = #{id}

</select>

<!-- 查询 user 表的所有数据

注意:因为是查询所有数据,所以返回的应该是一个集合,这个集合里面每个元素都是User类型

-->

<select id=

"selectUserAll"

resultType=

"com.ys.po.User"

>

select * from user

</select>

<!-- 模糊查询:根据 user 表的username字段

下面两种写法都可以,但是要注意

1

、${value}里面必须要写value,不然会报错

2

、${}表示拼接 sql 字符串,将接收到的参数不加任何修饰拼接在sql语句中

3

、使用${}会造成 sql 注入

-->

<select id=

"selectLikeUserName"

resultType=

"com.ys.po.User"

parameterType=

"String"

>

select * from user where username like

'%${value}%'

<!-- select * from user where username like #{username} -->

</select>

<!-- 向 user 表插入一条数据 -->

<insert id=

"insertUser"

parameterType=

"com.ys.po.User"

>

insert into user(id,username,sex,birthday,address)

value(#{id},#{username},#{sex},#{birthday},#{address})

</insert>

<!-- 根据 id 更新 user 表的数据 -->

<update id=

"updateUserById"

parameterType=

"com.ys.po.User"

>

update user set username=#{username} where id=#{id}

</update>

<!-- 根据 id 删除 user 表的数据 -->

<delete id=

"deleteUserById"

parameterType=

"int"

>

delete from user where id=#{id}

</delete>

</mapper>

6、向 mybatis-configuration.xml 配置文件中注册 userMapper.xml 文件

mybatis 详解(二)------入门实例(基于XML)

<mappers>

<!-- 注册userMapper.xml文件,

userMapper.xml位于com.ys.mapper这个包下,所以resource写成com/ys/mapper/userMapper.xml-->

<mapper resource=

"com/ys/mapper/userMapper.xml"

/>

</mappers>

 7、创建测试类

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

package

com.ys.test;

import

java.io.InputStream;

import

java.util.List;

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

com.ys.po.User;

public

class

CRUDTest {

//定义 SqlSession

SqlSession session =

null

;

@Before

public

void

init(){

//定义mybatis全局配置文件

String resource =

"mybatis-configuration.xml"

;

//加载 mybatis 全局配置文件

InputStream inputStream = CRUDTest.

class

.getClassLoader()

.getResourceAsStream(resource);

//构建sqlSession的工厂

SqlSessionFactory sessionFactory =

new

SqlSessionFactoryBuilder().build(inputStream);

//根据 sqlSessionFactory 产生 session

session = sessionFactory.openSession();

}

//根据id查询user表数据

@Test

public

void

testSelectUserById(){

/*这个字符串由 userMapper.xml 文件中 两个部分构成

<mapper namespace="com.ys.po.userMapper"> 的 namespace 的值

<select id="selectUserById" > id 值*/

String statement =

"com.ys.po.userMapper.selectUserById"

;

User user = session.selectOne(statement,

1

);

System.out.println(user);

session.close();

}

//查询所有user表所有数据

@Test

public

void

testSelectUserAll(){

String statement =

"com.ys.po.userMapper.selectUserAll"

;

List<User> listUser = session.selectList(statement);

for

(User user : listUser){

System.out.println(user);

}

session.close();

}

//模糊查询:根据 user 表的username字段

@Test

public

void

testSelectLikeUserName(){

String statement =

"com.ys.po.userMapper.selectLikeUserName"

;

List<User> listUser = session.selectList(statement,

"%t%"

);

for

(User user : listUser){

System.out.println(user);

}

session.close();

}

//向 user 表中插入一条数据

@Test

public

void

testInsertUser(){

String statement =

"com.ys.po.userMapper.insertUser"

;

User user =

new

User();

user.setUsername(

"Bob"

);

user.setSex(

"女"

);

session.insert(statement, user);

//提交插入的数据

session.commit();

session.close();

}

//根据 id 更新 user 表的数据

@Test

public

void

testUpdateUserById(){

String statement =

"com.ys.po.userMapper.updateUserById"

;

//如果设置的 id不存在,那么数据库没有数据更改

User user =

new

User();

user.setId(

4

);

user.setUsername(

"jim"

);

session.update(statement, user);

session.commit();

session.close();

}

//根据 id 删除 user 表的数据

@Test

public

void

testDeleteUserById(){

String statement =

"com.ys.po.userMapper.deleteUserById"

;

session.delete(statement,

4

);

session.commit();

session.close();

}

}

补充:如何得到插入数据之后的主键值?

第一种:数据库设置主键自增机制

    userMapper.xml 文件中定义:

<!-- 向 user 表插入一条数据 -->

<insert id=

"insertUser"

parameterType=

"com.ys.po.User"

>

<!-- 将插入的数据主键返回到 user 对象中

keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性

select LAST_INSERT_ID():查询上一次执行insert 操作返回的主键id值,只适用于自增主键

resultType:指定 select LAST_INSERT_ID() 的结果类型

order:AFTER,相对于 select LAST_INSERT_ID()操作的顺序

-->

<selectKey keyProperty=

"id"

resultType=

"int"

order=

"AFTER"

>

select LAST_INSERT_ID()

</selectKey>

insert into user(username,sex,birthday,address)

value(#{username},#{sex},#{birthday},#{address})

</insert>

    测试:

//向 user 表中插入一条数据并获取主键值

@Test

public

void

testInsertUser(){

String statement =

"com.ys.po.userMapper.insertUser"

;

User user =

new

User();

user.setUsername(

"Bob"

);

user.setSex(

"女"

);

session.insert(statement, user);

//提交插入的数据

session.commit();

//打印主键值

System.out.println(user.getId());

session.close();

}

第二种:非自增主键机制

<!-- 向 user 表插入一条数据 -->

<insert id=

"insertUser"

parameterType=

"com.ys.po.User"

>

<!-- 将插入的数据主键返回到 user 对象中

流程是:首先通过 select UUID()得到主键值,然后设置到 user 对象的id中,在进行 insert 操作

keyProperty:将查询到的主键设置到parameterType 指定到对象的那个属性

select UUID():得到主键的id值,注意这里是字符串

resultType:指定 select UUID() 的结果类型

order:BEFORE,相对于 select UUID()操作的顺序

-->

<selectKey keyProperty=

"id"

resultType=

"String"

order=

"BEFORE"

>

select UUID()

</selectKey>

insert into user(id,username,sex,birthday,address)

value(#{id},#{username},#{sex},#{birthday},#{address})

</insert>

    

总结:

  ①、parameterType:指定输入参数的类型

  ②、resultType:指定输出结果的类型,在select中如果查询结果是集合,那么也表示集合中每个元素的类型

  ③、#{}:表示占位符,用来接收输入参数,类型可以是简单类型,pojo,HashMap等等

    如果接收简单类型,#{}可以写成 value 或者其他名称

    如果接收 pojo 对象值,通过 OGNL 读取对象中的属性值,即属性.属性.属性...的方式获取属性值

  ④、${}:表示一个拼接符,会引起 sql 注入,不建议使用  

    用来接收输入参数,类型可以是简单类型,pojo,HashMap等等

    如果接收简单类型,${}里面只能是 value