当前位置: 澳门新濠3559 > 编程 > 正文

3.定义映射文件(mapper.xml),使用占位符

时间:2019-10-07 13:18来源:编程
一、自定义Dao接口达成类 搭建情状 Dao接口: public interface IStudentDao { //插入 void insertStudent(Student student); void insertStudentCacheId(Student student); //删改 void deleteStudentById; void updateStudent(Student

一、自定义Dao接口达成类

搭建情状

Dao接口:

public interface IStudentDao { //插入 void insertStudent(Student student); void insertStudentCacheId(Student student); //删改 void deleteStudentById; void updateStudent(Student student); //查询所有 List<Student> selectAllStudents(); Map<String, Object> selectAllStudentsMap(); //查询指定学生 Student selectStudentById; Student selectStudentByMap(Map<String, Object> map); //根据姓名查询 List<Student> selectStudentsByName(String name);}

Dao实现类:

public class StudentDaoImpl implements IStudentDao { private SqlSession sqlSession; @Override public void insertStudent(Student student) { try { sqlSession = MyBatisUtils.getSqlSession(); sqlSession.insert("insertStudent",student); sqlSession.commit(); } finally{ if(sqlSession!=null){ sqlSession.close(); } } }}

测试:

public class MyTest { private IStudentDao dao; @Before public void before(){ dao = new StudentDaoImpl(); }}

1.仅仅插入数据

照耀文件:

<insert parameterType="com.hcx.beans.Student"> insert into student(name,age,score) values(#{name},#{age},#{score})</insert>
  • id:该sql语句的独一标记,java代码中要运用该标记。
  • "#{}":对点名参数类型属性值的援用。其底层是透过反射机制,调用student类相关属相的get方法来获得值得。因为尾部使用的是反射,所以那边运用的是类的属性名,而非表的字段名。

dao实现类:

@Overridepublic void insertStudent(Student student) { try { sqlSession = MyBatisUtils.getSqlSession(); sqlSession.insert("insertStudent",student); sqlSession.commit(); } finally{ if(sqlSession!=null){ sqlSession.close(); } } }

静心:试行完对DB的修改操作,一定要做Sqlsession的交付。否则,修改将无法共同到DB中。因为使用无参的openSession()方法已经将业务自动提交成效给关闭了。

测试类:

@Testpublic void test01(){ Student student = new Student("张三",23,99.8); dao.insertStudent;}

2.插入后用新id起头化被插入对象

mysql中在插入语句后实施如下语句,则会输出新插入记录的id

insert into student(name,age,score) values('王五',25,95.5);select @@identity;

辉映文件中的<insert/>标签中,有贰个子标签<selectKey/>用于获取新插入记录的主键值。

1.以下二种写法均能够成功“使用新插入记录的主键值起始化被插入的对象”的功效:

方式一:

<insert parameterType="com.hcx.beans.Student"> insert into student(name,age,score) values(#{name},#{age},#{score}) <selectKey resultType="int" keyProperty="id" order="AFTER"> select @@identity </selectKey></insert>

方式二:

<insert parameterType="com.hcx.beans.Student"> insert into student(name,age,score) values(#{name},#{age},#{score}) <selectKey resultType="int" keyProperty="id" order="AFTER"> select last_insert_id(); </selectKey></insert>
  • resultType:提出获取的主键的品种
  • keyProperty:提议主键在java类中对应的属性名。此处会将拿到的主键值直接封装到被插入的student对象中,即dao中insert()方法的第4个参数对象中。
  • order:建议id的变通相对于insert语句的举办是在前照旧在后。MySql数据库表中的id,均是先进行insert语句,而后生成id,所以需求设置为after;oracle数据库表中的id,则是在insert推行以前先生成,所以须求设置为before。当前的MyBatis版本,不钦点order属性,则会基于所用DBMS,自动选择其值。

2.Dao实现类

@Overridepublic void insertStudentCacheId(Student student) { try { sqlSession = MyBatisUtils.getSqlSession(); sqlSession.insert("insesrtStudentCatchId",student); sqlSession.commit(); }finally{ if(sqlSession != null) { sqlSession.close(); } }}

3.测试类:

//插入后用新id初始化被插入对象@Testpublic void test02(){ Student student = new Student("张三",23,99.8); System.out.println("插入前student=" student); dao.insertStudentCatchId; System.out.println("插入后student=" student);}

3.去除数据

1.映射文书:

<delete > delete from student where id=#{id}</delete>

瞩目:这里的动态参数id所赋值为#{id}。这个#{}表示那就是个占位符,代表delete()方法的第一个参数。#{}中能够放大肆值,无须要与delete方法的第一个参数值相同。

2.dao实现类

@Overridepublic void deleteStudentById { try { sqlSession = MyBatisUtils.getSqlSession(); sqlSession.insert("deleteStudentById",id); sqlSession.commit(); }finally{ if(sqlSession != null) { sqlSession.close(); } } }

3.测试类

@Testpublic void test03(){ dao.deleteStudentById; }

4.改换数据

1.映射文本:

<update > update student set name=#{name},age=#{age},score=#{score} where id=#{id}</update>

注意,这里的#{}中,必须求填写update()方法所传第1个参数student对象的个性名称,不能够轻便填入。

2.dao实现类

@Overridepublic void updateStudent(Student student) { try { sqlSession = MyBatisUtils.getSqlSession(); sqlSession.update("updateStudnet",student); sqlSession.commit(); }finally{ if(sqlSession != null) { sqlSession.close(); } } }

3.测试类

@Testpublic void test04(){ Student student = new Student("得的",26,96.6); student.setId; dao.updateStudent; }

5.询问全数目的-重返list

1.映射文本

<select resultType="com.hcx.beans.Student"> select * from student</select>

留神,resultType属性并非指查询结果最后的连串,而是每查出DB中的一条记下,将该记录封装成为的指标的连串。

2.dao实现类

姣好dao达成类的selectAllStudent()方法。使用Sqlsession的selectList()方法成功查询操作。该方法会将查询出的每条记下封装为内定项目对象后,再将最后的结果集封装为list重临。

措施原型为:List selectList(String statement)statement:映射文件中布置的SQL语句的id。

@Overridepublic List<Student> selectAllStudents() { List<Student> students = null; try { sqlSession = MyBatisUtils.getSqlSession(); students = sqlSession.selectList("selectAllStudents"); //sqlSession.commit(); }finally{ if(sqlSession != null) { sqlSession.close(); } } return students;}

瞩目:在写查询时,由于不是对DB中的数据开展退换,所以无需进行Sqlsession的交由。但结尾Sqlsession对象依然须求关闭的。

3.测试类

@Testpublic void test05(){ List<Student> students = dao.selectAllStudents(); for (Student student : students) { System.out.println; } }

6.询问全数目的-再次回到Map

1.映射文件

<select resultType="com.hcx.beans.Student"> select * from student</select>

2.dao实现类

完了dao达成类的selectStudentMap()方法。使用Sqlsession的selectMap()方法成功查询操作。该查询方法会将查询出的每条记下先封装为内定对象,然后再将该对象作为value,将该指标的钦点属性所对应的字段名作为key封装为一个map对象。

措施原型:Map<Object,Object> selectMap(String statement,String mapKey)

  • statement:映射文件中布局的sql语句的id
  • mapkey:查询出的map所要选拔的key。那个key为数据表的字段名。查询出的结果是二个map,每行记录将会相应贰个Map.entry对象,该对象的key为钦定字段的值,value为记录数据所封装的对象

代码:

@Overridepublic Map<String, Object> selectAllStudentsMap() { Map<String, Student> studentsMap = null; try { sqlSession = MyBatisUtils.getSqlSession(); studentsMap = sqlSession.selectMap("selectAllStudents", "name"); //name:指定所形成map的key } finally{ if(sqlSession!=null){ sqlSession.close(); } } return null;}

3.测试类

@Testpublic void test06(){ Map<String, Student> map = dao.selectAllStudentsMap(); Student student = map.get; System.out.println;}

介意:若钦赐的充作key的属性值在DB中并不独一,则前面的笔录值会覆盖掉前边的值。即钦赐key的value值,一定是DB中该同名属性的最后一条记录值。

7.询问单个对象

1.映射文件

<select resultType="com.hcx.beans.Student"> select * from student where id=#{id}</select>

2.dao实现类

采取Sqlsession的selectOne()方法。其会将查询的结果记录封装为贰个钦赐项指标目的。

措施原型:Object selectOne(String statement,Object parameter)

  • statement:映射文件中布局的SQL语句的id
  • parameter:查询条件中动态参数的值

代码:

@Overridepublic Student selectStudentById { Student student = null; try { sqlSession = MyBatisUtils.getSqlSession(); student = sqlSession.selectOne("selectStudentById",id); sqlSession.commit(); }finally{ if(sqlSession != null) { sqlSession.close(); } } return student;}

3.测试类

@Testpublic void test07(){ Student student = dao.selectStudentById; System.out.println;}

8.歪曲查询

1.映射文件

写法一:

<select resultType="com.hcx.beans.Student"> select * from student where name like concat('%',#{name},'%')</select>

在拓宽模糊查询时,需求开展字符串的拼凑。sql中的字符串的拼接使用的是函数concat(arg1,arg2,...)。注意不能够动用java中的字符串连接符 。

写法二:

<select resultType="com.hcx.beans.Student"> select * from student where name like '%' #{name} '%'</select>

以上三种形式是一模一样的。都以以动态参数的情势出现在sql语句中的。

写法三:还可应用如下情势,需求潜心,只好利用${}中只好采取value,不能够应用别的:

<select resultType="com.hcx.beans.Student"> select * from student where name like '%${value}%'</select>

这种方法是纯粹的字符串拼接,直接将参数拼接到了sql语句中,所以可能会发出sql注入

2.dao实现类

@Overridepublic List<Student> selectStudentsByName(String name) { List<Student> students = null; try { sqlSession = MyBatisUtils.getSqlSession(); students = sqlSession.selectOne("selectStudentByName",name); sqlSession.commit(); }finally{ if(sqlSession != null) { sqlSession.close(); } } return students;}

3.测试类

@Testpublic void test08(){ List<Student> students = dao.selectStudentsByName; for (Student student : students) { System.out.println; }}

$与#的区别:

#为占位符,$为字符串拼接符字符串拼接是将参数值以硬编码的方式直接拼接到了sql语句中。字符串拼接就会引发两个问题:sql注入问题与没有使用预编译所导致的执行效率低下问题

使用场景:

相似景况下,动态参数的值是由客商输入的,则无法使用拼接符$,因为有比很大希望会现出sql注入;若动态参数的值是由系统总计生成的,则可以使用拼接符$。但那样就算不设有sql注入的高危机,但仍存在试行功用难点。

9.基于map实行询问

mapper中sql语句的动态参数也得以是map的key

1.测试类

map中贮存八个“键-值”对,即有七个key

@Testpublic void test09(){ Student student = new Student(); student.setId; Map<String, Object> map = new HashMap<String,Object>(); map.put("studentId", 2); map.put("student", student); student = dao.selectStudentByMap; System.out.println; }

2.映射文件

<select resultType="com.hcx.beans.Student"> select * from student where id=#{studentId}</select><select resultType="com.hcx.beans.Student"> select * from student where id=#{student.id}</select>

3.dao实现类

@Overridepublic Student selectStudentByMap(Map<String, Object> map) { Student student = null; try { sqlSession = MyBatisUtils.getSqlSession(); student = sqlSession.selectOne("selectStudentByMap",map); sqlSession.commit(); }finally{ if(sqlSession != null) { sqlSession.close(); } } return student;}

一、基本顺序

须求:达成将student新闻写入到DB中

1.概念实体类:

public class Student {

    private Integer id;
    private String name;
    private int age;
    private double score;
    //无参、带参构造器
    //getter、setter
    //toString()
}

2.定义Dao接口:

public interface IStudentDao {
    void insertStu(Student student);
}

3.概念映射文件(mapper.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">  

<mapper namespace="test" parameterType="com.hcx.beans.Student">
    <insert id="insertStudent" parameterType="com.hcx.beans.Student">
        insert into student(name,age,score) 
        values(#{name},#{age},#{score})
    </insert>
</mapper>

注意:#{}中写入的是student类的属性名。

对于parameterType属性,框架会自行依据客商推行的Sqlsession方法中的参数自动物检疫查评定到,所以通常我们毫不内定parameterType属性。

4.定义主配置文件(mybatis.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>
    <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/test"/>  
                <property name="username" value="root"/>  
                <property name="password" value="root"/>  
            </dataSource>
        </environment>
    </environments>

    <!-- 注册映射文件 -->
    <mappers>  
        <mapper resource="com/hcx/dao/mapper.xml"/>   
    </mappers>
</configuration>

5.定义dao实现类

public class StudentDaoImpl implements IStudentDao {

    private SqlSession sqlSession;

    @Override
    public void insertStu(Student student) {

        try {
            //读取主配置文件
            InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
            //创建SqlSessionFactory对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //创建sqlsession对象
            sqlSession = sqlSessionFactory.openSession();
            //操作
            sqlSession.insert("insertStudent",student);
            //Sqlsession提交
            sqlSession.commit();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if(sqlSession!=null){
                sqlSession.close();
            }
        }           
    }
}

6.测试

public class MyTest {

    private IStudentDao dao;

    @Before
    public void before(){
        dao = new StudentDaoImpl();
    }
    @Test
    public void testInsert(){

        Student student = new Student("张三",23,99.8);
        dao.insertStu(student);     
    }   
}

7.加多日记调控文件

日记品级设置:

  • debug:呈现出所推行的sql语句、参数值、对DB的震慑条数等音讯。
  • trace:彰显出查询出的每条记下的种种字段名及值

能够钦点要出口日志的职业空间的名字,此时,只会输出该namespace下实施的SQL的日记内容

##define a logger
log4j.rootLogger=trace,console

##define a logger
##log4j.logger.namespace_value=trace,console
log4j.logger.test=trace,console

2.5.2.1 定义resultMap

    <!--定义resultMap
        将SELECT id id_,username username_ FROM USER和User类中的属性作一个映射关系。
          type:resultMap最终映射的java对象类型,可以使用别名
          id:对resultMap的唯一标识
      -->
    <resultMap type="user" id="userResultMap">
        <!--id表示查询结果集中唯一标识
            column:查询出来的列名
            property:type指定的pojo类型中的属性名
                    最终resultMap对column和property作一个映射关系(对应关系)
          -->
        <id column="id_" property="id"/>
        <!--result:对普通名映射定义
            column:查询出来的列名
            property:type指定的pojo类型中的属性名
                    最终resultMap对column和property作一个映射关系(对应关系)
          -->
        <result column="username_" property="username"/>
    </resultMap>

---------------------- ----------- resultMap输出结果---------------------------------------------

  resultType可以钦命pojo将查询结果映射为pojo,但供给pojo的属性名和sql查询的列名一致方可映射成功。

         假如sql查询字段名和pojo的天性名分歧,可以由此resultMap将字段名和质量名作贰个相应关系 ,resultMap实质上还须要将查询结果映射到pojo对象中。

         resultMap能够完成将查询结果映射为复杂性类型的pojo,比如在查询结果映射对象中满含pojo和list实现一对一询问和一对多询问。

二、属性名与查询字段名不一致样

resultType能够将查询结果从来照射为实体Bean对象的条件是,sql查询的字段名与实业Bean的性格名同样。因为在将查询结果转变为钦定项目对象时,系统活动将查询结果字段名称作为靶子的属性名,通过反射机制达成目的的开创。

当sql查询结果的字段名和实业Bean的习性名分化时,将不恐怕创设出必要类型的指标。此时有两种减轻方案:查询字段使用外号或利用结果映射resultMap

1.修改student表

图片 1student表.PNG

2.dao接口

public interface IStudentDao { Student selectStudentById;}

3.测试类

public class MyTest { @Test public void test1(){ IStudentDao dao = new StudentDaoImpl(); Student student = dao.selectStudentById; System.out.println; }}

4.dao实现类

public class StudentDaoImpl implements IStudentDao { @Override public Student selectStudentById { SqlSession sqlSession = null; Student student = null; try { sqlSession = MyBatisUtils.getSqlSession(); student = sqlSession.selectOne("selectById2",id); } finally{ if(sqlSession!=null){ sqlSession.close(); } } }}

焚林而猎办法一:查询字段使用别称

虽说属性名称与表中的字段名称不相同样,但可以为查询结果的字段名称予以小名,让外号与实业Bean的属性同样。那样框架也能够依靠查询结果运用反射机制将目标创立。

在炫丽文件mapper中增多如下映射。注意,由于表的score字段名与student类的质量名一样,所以那边无需采取小名。

<select resultType="Student"> select tid id,tname name,tage,age,score from student where tid=#{tid}</select>

消除措施二:使用结果映射resultMap

能够利用结果映射resultMap来创建映射关系,达成由字段到属性的映照,到达将查询结果封装为对象的指标。resultMap是对resultType的加强。

<resultMap type="Student" > <id column="tid" property="id"/> <result column="tname" property="name"/> <result column="tage" property="age"/></resultMap><select resultMap="studentMapper"> select tid, tname, tage, score from student where tid=#{tid}</select>

<resultMap/>标签中定义了由type内定的类的质量名到表中字段名称的照耀关系。依据那些映射关系,框架利用反射机制创立相应对象。

  • type:钦定要映射的实体类
  • id:钦定该resultMap映射关系的称呼
  • <id>标签:id的字段名column与实体类的品质property间的映射关系
  • <result>标签:id以外另外字段名column与实体类的属性property间的照射关系

一经字段名与实体类的特性名一样的场地,能够不写入<resultMap/>中。

二、使用工具类

每二回执行Sqlsession的法子,均需求首先得到到该指标。而Sqlsession对象的拿走又绝相比较麻烦,所以,能够赢得Sqlsession对象定义为二个工具类方法。

Sqlsession对象是经过SqlsessionFactory对象创设的。由于SqlsessionFactory类为重量级对象,且为线程安全的,所以能够将SqlsessionFactory对象定义为单例的。

1.创建筑工程具类

public class MyBatisUtil {
    private static SqlSessionFactory factory;

    public static SqlSession getSqlSession(){
        try {
            if(factory==null){
                //读取主配置文件
                InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
                //创建Sqlsession工厂
                factory = new SqlSessionFactoryBuilder().build(inputStream);

            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return factory.openSession();
    }
}

2.改动dao接口的落到实处类

从未有过卓殊须要处理,但Sqlsession绝对要关张。

public class StudentDaoImpl implements IStudentDao {

    private SqlSession sqlSession;

    @Override
    public void insertStu(Student student) {

        try {
            sqlSession = MyBatisUtil.getSqlSession();
            sqlSession.insert("insertStu,student");
            //Sqlsession提交
            sqlSession.commit();
        }finally {
            if(sqlSession!=null){
                sqlSession.close();
            }
        }

    }

}

1.5 传递hashmap

sql映射文件定义如下:

    <!--传递hashmap综合查询用户信息  -->
    <select id="findUserByHashmap" parameterType="hashmap" resultType="user">
        select * from user where id=#{id} and username like '%${username}%'
    </select>

sql中红的标号的是hashmap的key。

mapper.java:

//传递hashmap综合查询用户信息
 public List<User> findUserByHashmap(HashMap<String, Object> map) throws Exception;

测试:

    @Test
    public void findUserByHashmapTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        //构造查询条件HashMap对象
        HashMap<String, Object> map=new HashMap<>();
        map.put("id", 10);
        map.put("username", "张三");
        //传递HashMap对象查询用户列表
        List<User> list=userMapper.findUserByHashmap(map);
        System.out.println(list);
        sqlSession.close();
    }

传送的map中的key和sql中解析的key不同时,不会报错,只是透过key获取的值为空。

3.    输出pojo列表(list集合)

Mapper.xml

<!-- 根据名称模糊查询用户信息 -->

    <select id="findUserByUsername" parameterType="string" resultType="user">

       select * from user where username like '%${value}%'

    </select>

 

Mapper接口:

public List<User> findUserByUsername(String username) throws Exception;

 

 

测试:

Public void testFindUserByUsername()throws Exception{

       //获取session

       SqlSession session = sqlSessionFactory.openSession();

       //获限mapper接口实例

       UserMapper userMapper = session.getMapper(UserMapper.class);

       //如果使用占位符号则必须人为在传参数中加%

       //List<User> list = userMapper.selectUserByName("%管理员%");

       //如果使用${}原始符号则不用人为在参数中加%

       List<User> list = userMapper.findUserByUsername("管理员");

       //关闭session

       session.close();

    }

动用session的selectList方法获得pojo列表。

CU智跑D操作,即指对数据库中实体对象的增create、改Update、查Read、删Delete操作

四、四个映射文件

在品种中,日常一个dao接口会相应四个辉映文件。

1.新扩展两个辉映文件

<!-- 注册映射文件 -->
<mappers>  
    <mapper resource="com/hcx/dao/mapper.xml"/>   
    <mapper resource="com/hcx/dao/mapper2.xml"/> 
</mappers>

2.修改肆意三个光彩夺目文件

能够修改放肆多个辉映文件<mapper/>标签的namespace属性,将三个不要映射文件中的sql映射,放入为分歧的命名空间。

取名空间的意义:用于区分分歧命名空间中的同名的sql映射id。

3.修改dao实现类

在dao完结类中应用时,必要提交具体使用的是哪个命名空间下的sql映射语句。

public class StudentDaoImpl2 implements IStudentDao {

    private SqlSession sqlSession;

    @Override
    public void insertStu(Student student) {

        try {
            sqlSession = MyBatisUtil.getSqlSession();
            sqlSession.insert("test.insertStu,student");
            //Sqlsession提交
            sqlSession.commit();
        }finally {
            if(sqlSession!=null){
                sqlSession.close();
            }
        }           
    }       
}

2.1 输出轻易类型

看上边包车型地铁例证,输出整型,mapper.xml文件:

    <!--获取用户列表总数  -->
    <select id="findUserCount" parameterType="user" resultType="int">
        select count(*) from user
    </select>

mapper接口:

public interface UserMapper {
    //获取用户列表总数
    public int findUserCount(User user) throws Exception;
}

测试:

  @Test
    public void findUserCountTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //创建UserMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        User user=new User();
        user.setUsername("yan");
        //调用userMapper的方法
        int count=userMapper.findUserCount(user);
        System.out.println(count);
        sqlSession.close();
    }

总结:

查询出来的结果集唯有一行且一列,能够选拔简单类型进行输出映射。

3. 传递pojo包装对象(传递QueryVo,取值的时候取其性质User对象的性质,也就是取传的对象的性质的习性,只然则对象的习性是指标)

   开拓中经过pojo传 递查询条件,查询条件是综合的查询条件,不仅仅蕴涵客商查询条件还满含别的的询问条件(比方将顾客购买商品信息也当做查询条件),那时能够选拔包装对象传递输入参数。

 

三、附属性文件中读取DB连接四要素

1.定义属性文件

在src下定义属性文件jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///test
jdbc.user=root
jdbc.password=root

2.修改主配置文件

对此主配置文件,第一,必要登记属性文件。第二,须要从属性文件中经过key,将其value读抽取来。

<?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="${jdbc.dirver}"/>  
                <property name="url" value="${jdbc.url}"/>  
                <property name="username" value="${jdbc.user}"/>  
                <property name="password" value="${jdbc.password}"/>  
            </dataSource>
        </environment>
    </environments>

    <!-- 注册映射文件 -->
    <mappers>  
        <mapper resource="com/hcx/dao/mapper.xml"/>   
    </mappers>
</configuration>

1.4.3 mapper.xml

 在UserMapper.xml中定义客商音信汇总查询(查询条件复杂,通过高等查询举行理并答复杂关系查询)

    <!--用户信息综合查询 
    UserQueryVo中定义了userCustom属性
    #{userCustom.sex}:取出pojo包装对象中性别值
    ${userCustom.username}:取出pojo包装对象中用户名称
     -->
    <select id="findUserList" parameterType="joanna.yan.mybatis.entity.UserQueryVo" resultType="joanna.yan.mybatis.entity.UserCustom">
        SELECT * FROM USER WHERE user.sex=#{userCustom.sex} AND user.username LIKE '%${userCustom.username}%'
    </select>

2. 传递POJO对象

Mybatis使用ognl表明式深入分析对象字段的值,如下例子:

   <!-- 更新用户,根据Id更新 ,需要传入Id(int型)与更新信息
    parameterType类型为User类型,指定需要修改的用户id和修改后的属性值,#{username}表示从传入的对象中取对应的username属性
    #{id}表示从user对象中获取id
    -->
    <update id="updateUserByTd" parameterType="cn.itcast.mybatis.po.User">
    update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
    where id=#{id}
    </update>

 

 

特别测量试验:

Sql中字段名输入错误后测量试验,username输入dusername测量试验结果报错:

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'dusername' in 'class cn.itcast.mybatis.po.User'
### Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'dusername' in 'class cn.itcast.mybatis.po.User'

  

第一个MyBatis程序

2.6 小结

利用resultType举办输出映射,独有查询出来的列名和pojo中的属性名一样,该列才可以映射成功。

设若查询出来的列名和pojo的特性名分歧,通过定义一个resultMap对列名和pojo属性名之间作三个映射关系。

倘若此文对你有扶持,微信打赏小编弹指间呢~ 

图片 2

resultType总结:

  输出pojo对象和出口pojo列表在sql中定义的resultType是一律的。

  再次来到单个pojo对象要力保sql查询出来的结果集为单条,内部使用session.selectOne方法调用,mapper接口使用pojo对象作为艺术再次来到值。

  重回pojo列表表示查询出来的结果集恐怕为多条,内部使用session.selectList方法,mapper接口使用List<pojo>对象作为艺术重返值。

 

2.5.2 将上边包车型地铁sql使用User完结映射

SELECT id id_,username username_ FROM USER WHERE id=#{value}

改sql对查询结果的列名举办了重新命名:

图片 3

User类中属性名和上边查询列名不等同。

 

转载请注解出处: 

1     传递轻松类型

1.int型

图片 4

2.String型

<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
        SELECT * FROM USER WHERE username like '%${value}%'
    </select>

 

 

2.5.1 resultMap使用方法

假使查询出来的列名和pojo的质量名不相同,通过定义贰个resultMap对列名和pojo属性名之间作三个炫人眼目关系。

(1)定义resultMap

(2)使用resultMap作为statement的输出映射类型。

1  Mapper.xml定义

图片 5

 

1.3 传递pojo对象

mybatis使用ognl表明式分析对象字段的值,如下例子:

     <!--传递pojo对象综合查询用户信息  -->
     <select id="findUserByUser" parameterType="user" resultType="user">
         select * from user where id=#{id} and username like '%${username}%'
     </select>

sql中深蓝标明的是user对象中的字段名称。

测试:

    @Test
    public void findUserByUserTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        User user=new User();
        user.setId(10);
        user.setUsername("张三");
        List<User> list=userMapper.findUserByUser(user);
        System.out.println(list);
        sqlSession.close();
    }

4.   输出hashmap(平常不用,在急需查询钦点列并转为接送的时候能够运用)

  输出pojo对象可以改用hashmap输出类型,将出口的字段名称作为map的key,value为字段值。

  那样贰个话语轻易意义于具有列被活动映射到 HashMap 的键上,这由 resultType 属性钦赐。那在众多情景下是平价的,但是 HashMap 不能够很好描述贰个世界模型。那样你的应用程序将会采纳 JavaBeans 或 POJOs(Plain Old Java Objects,普通 Java 对象)来作为世界模型。

    <!-- S 查询部门树 -->
    <select id="getDepartmentTreeForExam" resultType="map">
        SELECT
        departmentId,upDepartmentId,departmentName FROM department
    </select>
    <!-- E 查询部门树 -->

 

 

mapper接口:

    /**
     * 查询部门id,上级id,部门名称生成内部部门树
     * 
     * @return 一个map包含部门的部门id,上级id,部门名称
     * @throws SQLException
     */
    public List<Map<String,Object>> getDepartmentTreeForExam() throws SQLException;

 

 

测试:

package cn.xm.exam.test.daoTest;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import cn.xm.exam.mapper.employee.in.custom.DepartmentCustomMapper;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/applicationContext-*.xml")
public class DepartmentCustomMapperTest {
    @Autowired
    private DepartmentCustomMapper departmentCustomMapper;

    @Test
    public void testGeneDepartmentTree() throws SQLException {
        List<Map<String, Object>> departmentTree = departmentCustomMapper.getDepartmentTreeForExam();
        System.out.println(departmentTree);
    }

}

 

结果:

[{departmentId=10, departmentName=厂级-1}, {departmentId=10001, departmentName=部门1_10, upDepartmentId=10}, {departmentId=10001001, departmentName=班组1_10001, upDepartmentId=10001}, {departmentId=10002, departmentName=部门2_10, upDepartmentId=10}, {departmentId=10002001, departmentName=班组2_10002, upDepartmentId=10002}, {departmentId=10003, departmentName=部门3_10, upDepartmentId=10}, {departmentId=11, departmentName=厂级-2}, {departmentId=11001, departmentName=部门1_11, upDepartmentId=11}, {departmentId=12, departmentName=厂级-3}]

 

 

 

1.4 传递pojo包装对象

开荒中经过pojo传递查询条件,查询条件是归纳的查询条件,不仅仅囊括客商查询条件,还包涵别的的查询条件(举个例子将客户购买的商品音信也充作查询条件),这时能够使用包装对象传递输入参数。

------------------------------------resultType输出类型----------------------------------------

1.2 传递轻易类型

参照他事他说加以考察上面包车型地铁事例。

4.  传递hashmap

Sql映射文件定义如下:

<!-- 传递hashmap综合查询用户信息 -->
    <select id="findUserByHashmap" parameterType="hashmap" resultType="user">
       select * from user where id=#{id} and username like '%${username}%'
    </select>

 

下边紫灰标记的是hashmap的key。

 

测试:

Public void testFindUserByHashmap()throws Exception{
        //获取session
        SqlSession session = sqlSessionFactory.openSession();
        //获限mapper接口实例
        UserMapper userMapper = session.getMapper(UserMapper.class);
        //构造查询条件Hashmap对象
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("id", 1);
        map.put("username", "管理员");

        //传递Hashmap对象查询用户列表
        List<User>list = userMapper.findUserByHashmap(map);
        //关闭session
        session.close();
    }

 

 

老大测量试验:

传递的map中的key和sql中分析的key不雷同。

测量检验结果尚未报错,只是通过key获取值为空。

 

5.传递List

sql定义:(输入类型为List,collection定义为list)

    <select id="getQuestionsForExamPaper" parameterType="java.util.List"
        resultMap="questionAndOptionForPaper">
        SELECT * FROM questions q,options o WHERE
        q.questionId=o.questionId and
        q.questionId in
        <foreach collection="list" item="id" separator="," open="("
            close=")">
            #{id}
        </foreach>
    </select>

 

Java 测试:

    // 测试根据ID集合查询试题
    @Test
    public void test2() throws SQLException {
        Map<String, Object> condition = new HashMap<String, Object>();
        condition.put("type", "单选题");
        condition.put("level", 1);
        condition.put("num", 3);
        List<String> IDs = questionsCustomMapper.getQuestionsIdsForExamPaper(condition);
        List<Questions> questions = questionsCustomMapper.getQuestionsForExamPaper(IDs);
        System.out.println(questions.size());
    }

 

 foreach 的最首要用在创设in条件中,它能够在SQL语句中实行迭代一个汇集。foreach成分的性质首要有 item,index,collection,open,separator,close。item表示集结中每三个成分进行迭代时的外号,index钦赐三个名字,用于表示在迭代进度中,每一趟迭代到的职位,open代表该语句以什么样开头,separator代表在历次实行迭代时期以如何符号作为分隔 符,close表示以什么甘休,在采纳foreach的时候最主要的也是最轻巧失误的正是collection属性,该属性是必需内定的,可是在差异处境下,该属性的值是分裂样的,重要有弹指间3种景况: 

  1. 一旦传入的是单参数且参数类型是三个List的时候,collection属性值为list .
  2. 假若传入的是单参数且参数类型是二个array数组的时候,collection的属性值为array .
  3. 要是传入的参数是多少个的时候,我们就需求把它们封装成二个Map了,当然单参数也足以封装成map,实际上只要您在传诵参数的时候,在MyBatis里面也 是会把它封装成三个Map的,map的key就是参数名,所以那一年collection属性值便是传播的List或array对象在大团结包装的map 里面的key.

 

 

2.5.2.4 测试

    @Test
    public void findUserByIdResultMapTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        User user=userMapper.findUserByIdResultMap(1);
        System.out.println(user);
        sqlSession.close();
    }

--------------------------------parameterType输入类型--------------------

 

由此parameterType钦定输入参数的种类,类型能够是大概类型、hashmap、pojo的包装等级次序

2.4 输出hashmap

出口pojo对象能够改用hashmap输出类型,将出口的字段名称作为map的key,value为字段值。

3.1  定义包装对象

概念包装对象将查询条件(pojo)以类组合的措施包装起来。

图片 6

 

2.5 resultMap

resultType能够钦定将查询结果映射为pojo,但需求pojo的属性名和sql查询的列名一致才可光彩夺目成功。

假使sql查询字段名和pojo的质量名区别,能够通过resultMap将字段名和性质名作贰个应和关系,resultMap实质上还亟需将查询结果映射到pojo对象中。

resultMap能够兑现将查询结果映射为复杂性类型的pojo,比方在查询结果映射对象中总结pojo和list达成完毕一对一询问和一对多询问。

 

1.4.4 mapper.java

//用户信息综合查询
public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;

 2.   输出pojo对象

Mapper.xml

   <!-- 根据id查询用户信息 -->

    <select id="findUserById" parameterType="int" resultType="user">

       select * from user where id = #{id}

    </select>

 

 

Mapper接口:

public User findUserById(int id) throws Exception;

 

 

测试:

 

Public void testFindUserById() throws Exception {

       //获取session

       SqlSession session = sqlSessionFactory.openSession();

       //获限mapper接口实例

       UserMapper userMapper = session.getMapper(UserMapper.class);

       //通过mapper接口调用statement

       User user = userMapper.findUserById(1);

       System.out.println(user);

       //关闭session

       session.close();

    }

使用session调用selectOne查询单条记录。

 

2.5.2.2 使用resultMap作为statement的输出映射类型

    <!--使用resultMap进行输出映射
        resultMap:指定定义的resultMap的id,如果这个resultMap在其它的mapper文件,前边需要加namespace
      -->
    <select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
        SELECT id id_,username username_ FROM USER WHERE id=#{value}
    </select>

0.#{}与${}区别

#{}达成的是向prepareStatement中的预管理语句中装置参数值,sql语句中#{}表示多少个占位符即?。

<!-- 根据id查询用户信息 -->
    <select id="findUserById" parameterType="int" resultType="user">
        select * from user where id = #{id}
    </select>

  

选择占位符#{}能够使得防护sql注入,在采用时无需关心参数值的门类,mybatis会自动进行java类型和jdbc类型的更改。#{}能够接过简单类型值或pojo属性值,如若parameterType传输单个简单类型值,#{}括号中得以是value或别的名称。

 

${}和#{}分歧,通过${}能够将parameterType 传入的原委拼接在sql中且不举办jdbc类型转变, ${}能够接收轻易类型值或pojo属性值,倘若parameterType传输单个简单类型值,${}括号中只可以是value。使用${}不能防备sql注入,可是有的时候用${}会极度便利,如下的例子:

<!-- 根据名称模糊查询用户信息 -->
    <select id="selectUserByName" parameterType="string" resultType="user">
       select * from user where username like '%${value}%'
    </select>

  

假诺本例子使用#{}则传出的字符串中必得有%号,而%是人为拼接在参数中,鲜明有个别麻烦,假使应用${}在sql中拼接为%的法门则在调用mapper接口传递参数就有益广大。

 

再举个例子order by排序,假如将列名通过参数字传送入sql,依照传的列名实行排序,应该写为:

ORDER BY ${columnName}

要是采取#{}将不大概落实此作用。

 

前边有讲到Spring SpringMVC MyBatis深切学习及搭建(三)——MyBatis全局配置文件解析

3.2   mapper.xml映射文件

图片 7

 

表明:mybatis底层通过ognl从pojo中获取属性值:#{user.username},user便是流传的包裹对象的天性。queryVo是别名,即下面定义的包装对象类型。

 

2.5.2.3 mapper.java

    //根据id查询用户信息,使用resultMap输出
    public User findUserByIdResultMap(int id) throws Exception;

3.  Mapper接口定义

public List<User> findUserListResultMap() throws Exception;

 

 

 

 

 

1.4.2 定义包装档案的次序pojo

针对下面必要,建议选用自定义的包裹等级次序的pojo,在卷入档期的顺序的pojo元帅复杂的查询条件包装进去。

/**
 * 包装类型
 * @author Joanna.Yan
 *
 */
public class UserQueryVo {
    //在这里包装所需要的查询条件

    //用户查询条件
    private UserCustom userCustom;

    public UserCustom getUserCustom() {
        return userCustom;
    }

    public void setUserCustom(UserCustom userCustom) {
        this.userCustom = userCustom;
    }

    //可以包装其它的查询条件,订单、商品
    //......
}

2.  定义resultMap

<!-- 定义resultMap
    将SELECT id id_,username username_ FROM USER 和User类中的属性作一个映射关系

    type:resultMap最终映射的java对象类型,可以使用别名
    id:对resultMap的唯一标识
     -->
     <resultMap type="user" id="userResultMap">
         <!-- id表示查询结果集中唯一标识 
         column:查询出来的列名
         property:type指定的pojo类型中的属性名
         最终resultMap对column和property作一个映射关系 (对应关系)
         -->
         <id column="id_" property="id"/>
         <!-- 
         result:对普通名映射定义
         column:查询出来的列名
         property:type指定的pojo类型中的属性名
         最终resultMap对column和property作一个映射关系 (对应关系)
          -->
         <result column="username_" property="username"/>

     </resultMap>

<id />:此属性表示查询结果集的有一无二标志,极其主要。假使是多少个字段为复合独一约束则定义八个<id />。

Property:表示person类的习性。

Column:表示sql查询出来的字段名。

Column和property放在一同表示将sql查询出来的字段映射到钦赐的pojo类属性上。

 

<result />:普通结果,即pojo的性质。

 

1.1 #{}与${}

#{}实现的是向prepareStatement中的预管理语句设置参数值,sql语句中#{}表示三个占位符即?

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

动用占位符#{}能够有效防御sql注入,在利用时不须求关系参数值的项目,mybatis会自动实行java类型和jdbc类型的转移。#{}能够接过轻便类型值或pojo属性值,假若parameterType传输单个项目值,#{}括号能够是value或其余名称。

${}和#{}分歧,通过${}能够将parameterType传入的内容拼接在sql中且不开展jdbc类型调换,${}还可以简单类型值或pojo属性值,要是parameterType传输单个轻便类型值,${}括号中只好是value。使用${}不能防守sql注入,不过有的时候用${}会十三分便利,如下例子:

    <select id="findUserByName" parameterType="java.lang.String" resultType="joanna.yan.mybatis.entity.User">
        select * from user where username LIKE '%${value}%'
    </select>

如若本例子使用#{}则传出的字符串中必得求有%,而%是人造拼接在参数中,鲜明不怎么困苦,要是应用${}在sql中拼接为%的艺术则在调用mapper接口传递参数就方便广大。

//如果使用占位符号则必须人为在传参数中加%
List<User> list = userMapper.selectUserByName("%管理员%");

//如果使用${}原始符号则不用人为在参数中加%
List<User>list = userMapper.selectUserByName("管理员");

再举个例子order by排序,借使将列名通过参数字传送入sql,依照传的列名进行排序,应该写为:O大切诺基DER BY ${columnName}

假定运用#{}将相当的小概兑现此功效。

1. 出口简单类型

Mapper.xml文件

<!-- 获取用户列表总数 -->

    <select id="findUserCount" parameterType="user" resultType="int">

       select count(1) from user

    </select>

 

 

 

Mapper接口

public int findUserCount(User user) throws Exception;

 

 

测试:

Public void testFindUserCount() throws Exception{

       //获取session

       SqlSession session = sqlSessionFactory.openSession();

       //获取mapper接口实例

       UserMapper userMapper = session.getMapper(UserMapper.class);



       User user = new User();

       user.setUsername("管理员");


       int count = userMapper.findUserCount(user);



       //关闭session

       session.close();

    }

 

总结:

出口轻松类型必需询问出来的结果集有一条记下,最后将率先个字段的值转变为出口类型。

利用session的selectOne可查询单条记录。

 

2. 输出映射

1. 输入映射

通过parameterType钦命输入参数的项目,类型能够是简简单单类型、hashmap、pojo的包裹等级次序。

1.4.1 需求

完结客户音讯的归纳查询,供给传入查询条件很复杂(恐怕蕴含客商音讯、另外音信,举例商品、订单等)

2.3 resultType总结

选拔resultType实行输出映射,独有查询出来的列名和pojo中的属性名一样,该列才得以映射成功。

假定查询出来的列名和pojo中的属性名全体不雷同,则不会创制pojo对象。

比如查询出来的列名和pojo中的属性有多个长久以来,就能够成立pojo对象。

1.4.5 测量试验代码

    @Test
    public void findUserListTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        //创建包装对象,设置查询条件
        UserQueryVo userQueryVo=new UserQueryVo();
        UserCustom userCustom=new UserCustom();
        userCustom.setSex("1");
        userCustom.setUsername("张三丰");
        userQueryVo.setUserCustom(userCustom);
        List<UserCustom> list=userMapper.findUserList(userQueryVo);
        System.out.println(list);
    }

2.2 输出pojo对象和pojo列表

任凭是出口的pojo单个目的依然八个列表(list中回顾pojo),在mapper.xml中resultType内定的项目是大同小异的。

图片 8

在mapper.java内定的形式再次回到值类型不均等:

(1)输出单个pojo对象,方法重回值是单个对象类型。

图片 9

(2)输出pojo对象list,方法重临值是List<POJO>

图片 10

变化的动态代理对象中是依照mapper方法的归来值类型分明是调用session.selectOne(重回单个对象调用)依旧session.selectList(重返集合对象调用)。

编辑:编程 本文来源:3.定义映射文件(mapper.xml),使用占位符

关键词: 澳门新濠3559