mybatis的增删改查的简单实例与参数分析

mybatis是持久层框架,使用mybatis可以把sql与Java代码相分离,把代码的编写在配置文件中,此处实现一个简单的实例,即用户的增删改查

1.首先需要导入jar包,mybatis的jar包导入一个核心jar包即可,因为要操作数据库,我使用的是MySQL,所以还需要导入MySQL的驱动包,jar包的截图如下所示:

2.编写实体类文件以及对应的映射文件,文件代码如下所示 :

 1 package com.gp.dao;
 2 
 3 public class User {
 4     private Integer id;
 5     private String name;
 6     private String password;
 7 
 8     @Override
 9     public String toString() {
10         return "User [id=" + id + ", name=" + name + ", password=" + password
11                 + "]";
12     }
13 
14     public Integer getId() {
15         return id;
16     }
17 
18     public void setId(Integer id) {
19         this.id = id;
20     }
21 
22     public String getName() {
23         return name;
24     }
25 
26     public void setName(String name) {
27         this.name = name;
28     }
29 
30     public String getPassword() {
31         return password;
32     }
33 
34     public void setPassword(String password) {
35         this.password = password;
36     }
37 }

与其对应的配置的配置文件如下:

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper
 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.gp.dao.UserMapper">
 6     <select id="selectUser" resultType="com.gp.dao.User">
 7         select * from user where id =#{id}
 8     </select>
 9     <insert id="insertUser">
10         insert into user(id,name,password) values(#{id},#{name},#{password})
11     </insert>
12     <!-- parameterType参数可以省略,也可以写上 -限制全类名 -->
13     <update id="updateUser" parameterType="com.gp.dao.User">
14         update user set name=#{name} ,password=#{password} where id=#{id}
15     </update>
16     <delete id="delete">
17         delete from user where id=#{id}
18     </delete>
19 </mapper>

3.编写测试文件,文件代码如下所示:

 1 package com.gp.test;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 
 6 import org.apache.ibatis.io.Resources;
 7 import org.apache.ibatis.session.SqlSession;
 8 import org.apache.ibatis.session.SqlSessionFactory;
 9 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
10 
11 import com.gp.dao.User;
12 
13 public class TestUser {
14 
15     //编写获取SqlSessionFactory的静态方法
16     public static SqlSessionFactory getSqlSessionFactory() {
17         String resource = "mybatis-config.xml";
18         InputStream inputStream;
19         try {
20             inputStream = Resources.getResourceAsStream(resource);
21             SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
22                     .build(inputStream);
23             return sqlSessionFactory;
24         } catch (IOException e) {
25             e.printStackTrace();
26         }
27         return null;
28     }
29 
30     //实现查询方法
31     public void selectUser() {
32         SqlSession session = getSqlSessionFactory().openSession();
33         try {
34             User user = session.selectOne("com.gp.dao.UserMapper.selectUser", 1);
35             System.out.println(user);
36         } finally {
37             session.close();
38         }
39     }
40     
41     //实现插入方法
42     public void insertUser(){
43         //获取的sqlSession不会 自动提交
44         SqlSession session=getSqlSessionFactory().openSession();
45         try{
46             User user=new User();
47             user.setId(6);
48             user.setName("小明");
49             user.setPassword("123456");
50             Object obj=session.insert("com.gp.dao.UserMapper.insertUser", user);
51             //执行完插入后一定要手动提交
52             session.commit();
53             System.out.println(obj);
54         }finally{
55             session.close();
56         }
57     }
58     
59     //实现修改方法
60     public void updateUser(){
61         SqlSession session=getSqlSessionFactory().openSession();
62         try{
63             User user=new User();
64             user.setId(6);
65             user.setName("小明");
66             user.setPassword("666666");
67             Object obj=session.insert("com.gp.dao.UserMapper.updateUser", user);
68             //执行完修改后一定要手动提交
69             session.commit();
70             System.out.println(obj);
71         }finally{
72             session.close();
73         }
74     }
75     //实现删除方法
76     public void deleteUser(){
77         SqlSession session=getSqlSessionFactory().openSession();
78         try{
79             Object obj=session.insert("com.gp.dao.UserMapper.delete", 6);
80             //执行完修改后一定要手动提交
81             session.commit();
82             System.out.println(obj);
83         }finally{
84             session.close();
85         }
86     }
87 
88     public static void main(String[] args) {
89          TestUser tu=new TestUser();
90 //         tu.selectUser();
91 //         tu.insertUser();
92 //         tu.updateUser();
93          tu.deleteUser();
94     }
95 }

至此,简单的mybatis的增删改查就完成了,以下说明几点;

1.配置文件mybatis-config.xml主要负责数据源的配置,以及映射实体类的映射文件

2.映射文件UserMapper.xml主要负责SQL语句的编写,并返回结果,实现数据最基本的增删改查

3.编写测试文件时,需要先加载配置文件,把配置文件以数据流的形式进行读取,根据读取的数据流创建SQLSessionFactory工厂,由SqlSessionFactory获取Sqlsession

   获取SQLSession就可以执行对应的SQL语句,执行SQL语句

 直接使用SqlSession的select,insert,update,delete方法进行对应的增删改查操作,有两个参数:

       第一个参数是sql语句定位到映射文件UserMapper.xml文件的参数,是mapper映射文件中    namespace+id名,namespace具体定位到执行那个映射文件,id名具体定位执行那个SQL语句;

       第二个参数是SQL语句的参数取值,例如插入语句传入的就是对象User,查询传入的就是id号。

上面是通过XML映射文件进行对数据的操作,还有一种方式,可以通过接口的方式进行操作数据的增删改查,下面举个简单的实例,如下所示:

实体类User不变,新增加一个接口文件UserMapper1.java,改变一下配置文件中的namespace,namespace是此接口的全类名,而增删改查标签中的id对应UserMapper1接口中对应的方法名,代码如下所示:

接口UserMapper1.java

1 package com.gp.dao;
2 
3 public interface UserMapper1 {
4    public void insertUser(User user);
5    public User selectUser(Integer id);
6    public void updateUser(User user);
7    public void deleteUser(Integer id);
8 }

对应的映射文件如下:

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper
 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.gp.dao.UserMapper1"><!-- 此处路径是接口UserMapper1的路径全类名 -->
 6     <select id="selectUser" resultType="com.gp.dao.User"><!-- 此处的id表示接口中的方法名 -->
 7         select * from user where id =#{id}
 8     </select>
 9     <insert id="insertUser">
10         insert into user(id,name,password) values(#{id},#{name},#{password})
11     </insert>
12     <!-- parameterType参数可以省略,也可以写上 -限制全类名 -->
13     <update id="updateUser" parameterType="com.gp.dao.User">
14         update user set name=#{name} ,password=#{password} where id=#{id}
15     </update>
16     <delete id="deleteUser">
17         delete from user where id=#{id}
18     </delete>
19 </mapper>

下面的测试类仅测试下查询方法,代码如下所示:

 1 package com.gp.test;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 
 6 import org.apache.ibatis.io.Resources;
 7 import org.apache.ibatis.session.SqlSession;
 8 import org.apache.ibatis.session.SqlSessionFactory;
 9 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
10 
11 import com.gp.dao.User;
12 import com.gp.dao.UserMapper1;
13 
14 public class TestUser1 {
15     
16     //编写获取SqlSessionFactory的静态方法
17     public static SqlSessionFactory getSqlSessionFactory() {
18         String resource = "mybatis-config.xml";
19         InputStream inputStream;
20         try {
21             inputStream = Resources.getResourceAsStream(resource);
22             SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
23                     .build(inputStream);
24             return sqlSessionFactory;
25         } catch (IOException e) {
26             e.printStackTrace();
27         }
28         return null;
29     }
30     
31     //实现查询方法
32     public void selectUser() {
33         
34         SqlSession session = getSqlSessionFactory().openSession();
35         
36         try {
37             UserMapper1 mapper = session.getMapper(UserMapper1.class);
38             User user = mapper.selectUser(1);
39              
40             System.out.println(user);
41         } finally {
42             session.close();
43         }
44     }
45    public static void main(String[] args) {
46      TestUser1 tu1=new TestUser1();
47      tu1.selectUser();
48    }
49 }

测试的结果截图如下所示;

 

具体可以查看mybatis的参考手册

关于参数的处理:

单个参数:mybatis不会做特殊处理,#{参数名},直接取出就可以了,即使#{}中的参数名称和实体类User中的id名称不一致,依然会查询出结果,例如上面实例中配置文件的select标签中的参数改为#{idname}

多个参数:按照正常逻辑,select标签中的查询条件有2个,一个id,一个name,接口中新增一个方法,如下所示:

  public User selectIdAndName(Integer id,String name);

映射文件中增加select标签如下所示:

1     <select id="selectIdAndName" resultType="com.gp.dao.User">
2        select * from user where id =#{id} and name=#{name}
3     </select>

执行后会异常报错;Parameter 'id' not found. Available parameters are [1, 0, param1, param2]

原因:

mybatis遇到多个参数会做特殊处理,多个参数会被封装成一个map,key:param1....paramN

value表示传入的参数值,#{}就是从map中获取指定的key的值

正确的写法是:

    <select id="selectIdAndName" resultType="com.gp.dao.User">
       select * from user where id =#{param1} and name=#{param2}
    </select>

测试文件中获取对象的代码修改为:

            UserMapper1 mapper = session.getMapper(UserMapper1.class);
            User user = mapper.selectIdAndName(1,"张三");             

命名参数:明确指定封装参数值map的key,@param("id"),不建议使用param1...paramN,

多个参数被封装为一个map,

key:使用@param注释指定的值     value:参数值,     #{指定的key}取出对应的参数值

实例修改如下所示,把接口中的方法修改为如下所示:

   public User selectIdAndName(@Param("id")Integer id,@Param("name")String name);

把映射文件中的配置SQL修改为如下所示 :

    <select id="selectIdAndName" resultType="com.gp.dao.User">
       select * from user where id =#{id} and name=#{name}
    </select>

运行结果正常显示:

如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入实体类User的对象即可,即pojo,#{属性名},取出传入的pojo的属性值

如果多个参数不是我们业务逻辑的数据模型,没有对应的map,为了方便,我们可以传入map对象,#{key},取出map中对应的值

在UserMapper1接口中增加如下方法:

public User getUserMap(Map<String,Object> map);

修改的测试类TestUser1.java如下所示:

            UserMapper1 mapper = session.getMapper(UserMapper1.class);
            Map<String ,Object> map=new HashMap<String,Object>();
             map.put("id", 1);
             map.put("name", "张三");
            User user=mapper.getUserMap(map);
            System.out.println(user);

可以得出测试结果:

2018-03-17 11:47:27,958 [main] DEBUG [com.gp.dao.UserMapper1.getUserMap] - ==>  Preparing: select * from user where id =? and name=? 
      2018-03-17 11:47:27,984 [main] DEBUG [com.gp.dao.UserMapper1.getUserMap] - ==> Parameters: 1(Integer), 张三(String)
      2018-03-17 11:47:28,000 [main] DEBUG [com.gp.dao.UserMapper1.getUserMap] - <==      Total: 1
      User [id=1, name=张三, password=123456]

若多个参数不经常使用,可以传入map中,但要是经常使用,推荐编写一个TO(Transfer  object)数据传输对象

Page{

 int  index;

int  size;

}

获取参数的时候,有两种方式,一种是${},一种是#{}

两者都可以获取map中的值或者pojo对象中属性的值。

两者的区别是什么呢?

#{}是以预编译的形式将参数设置到SQL语句中的,Preparedstatment

${}取出的值直接拼装到SQL语句中,会有安全问题,

大多情况下,取参数的值都是使用#{},

原生jdbc不支持占位符的地方可以使用${}进行取值,比如分表,排序,表名等

select * from ${year}_salary where xxx;

select * from user order by ${name} ${order}

select * from ${tableName} where xxx;

=======================================================================

特别注意:,如果是Collocation(List,set)或者数组,也会特殊处理,把传入的list或者数组封装在map中,key:Collection(collection),list还可以使用key(list),数组(array)

例如:public User getUserId(List<Integer> ids);     取值,取出第一个id的值,#{list[0]},不能是#{param1[0]}也不能是#{ids[0]}

 

posted on 2018-03-17 13:35  没有太晚的开始  阅读(334)  评论(0编辑  收藏  举报

导航