mybatis 操作数据库(05)
类型转换、动态排序,查询接口与mapper对应关系说明及其注意事项
一、MyBatis 自带写常见类型转换器。例如:java 类中 String 对应 mySQL中的varchar
二、自定义类型转换器
如java类中的true对应数据库字段 1,java中 false对应数据库中0。(数据的数值类型需与java类中boolean定义一个一致性约束对应关系)
实例:定义java类为Person ,sex数据类型为boolean,数据库定义类型为 int。这种情况需要自定义类型转换器
三、注意事项:
1、接口方法名和mapper.xml文件中标签的id相同
2、接口该方法的输入参数和mapper.xml文件中标签的parameterType相同
3、接口该方法的返回值和mapper.xml文件中标签的resultType相同
除了以上约定,要实现接口中方法和mapper.xml 中的SQL标签一一对应,还需要以下两点:
1、namespace的值,就是接口的全类名(接口 <---> mapper.xml 一一对应)
人为习惯:
1、SQL映射文件(mapper.xml)和接口放在同一个package下
四、${} 与 #{}【区别】:
第一点:
#{任意值}
${value} ,其中的标识只能是value
第二点:
#{} 作为参数自动会给string类型添加上''(自动类型转换)
${} 原样输出,适合于动态排序字段
作为查询以下两种情况等价:
select id,name,age from t_person_01 where name=#{value}
select id,name,age from t_person_01 where name='${value}'
动态排序:
select id,name,age,sex from t_person_01 ORDER BY ${value} ASC
第三点:
#{} :防止SQL注入
${} : 不防止
【相同点】:
parameterType 为对象类型
#{属性名}
${属性名}
五、实例举例:
1、配置文件 mybatis-03.xml
文件内容为:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "//mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 转换器 --> <typeHandlers> <!-- 把java类的boolean类型转换数据 int,数据库int转换为java类的boolean类型 --> <typeHandler handler="com.mybatis03.util.BooleanAndIntConverter" javaType="Boolean" jdbcType="INTEGER"/> </typeHandlers> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis01"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <!-- jack.zhao 加载映射文件 --> <mapper resource="com/mybatis03/mapper/personMapper.xml"/> </mappers> </configuration>
2、类型转换器
package com.mybatis03.util; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * @author :jack.zhao * @Describe: 类型转换器(BaseTypeHandler<Boolean> java 类型) * @date :2021-10-16 22:55 */ public class BooleanAndIntConverter extends BaseTypeHandler<Boolean> { /** * java(boolean) ----> int (java 类属性映射到数据库) * @param ps preparedStatement 参数对象 * @param i preparedStatement 对象操作位置 * @param aBoolean java值 * @param jdbcType jdbc 操作数据库类型值 * @throws SQLException */ @Override public void setNonNullParameter(PreparedStatement ps, int i, Boolean aBoolean, JdbcType jdbcType) throws SQLException { if(aBoolean){ ps.setInt(i,1); } else { ps.setInt(i,0); } } /** * db(int) --------->java(boolean) (数据库映射java类属性) * @param resultSet * @param columnName * @return * @throws SQLException */ @Override public Boolean getNullableResult(ResultSet resultSet, String columnName) throws SQLException { int sexNum = resultSet.getInt(columnName); return sexNum ==1 ? true:false; } @Override public Boolean getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException { int sexNum = resultSet.getInt(columnIndex);// 位置 return sexNum ==1 ? true:false; } @Override public Boolean getNullableResult(CallableStatement callableStatement, int i) throws SQLException { return null; } }
3、实体类
package com.mybatis03.bean; /** * @author :jack.zhao * @Describe: 实体类 * @date :2021-10-16 22:55 */ public class Person { private int id; private String name; private int age; private Boolean sex; public Person() { } public Person(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } public Person(int id, String name, int age, Boolean sex) { this.id = id; this.name = name; this.age = age; this.sex = sex; } public Boolean getSex() { return sex; } public void setSex(Boolean sex) { this.sex = sex; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", sex=" + sex + '}'; } }
4、操作数据库接口类
package com.mybatis03.mapper; import com.mybatis03.bean.Person; import java.util.List; /** * @author :jack.zhao * @Describe: 操作mybatis接口 * @date :2021-10-16 22:55 */ public interface PersonMapper { void delStudentById(int id); void updateStudentById(Person person); Person queryPersonByName(String strName); List<Person> queryPersonOrderByColumn(String strColumn); List<Person> queryListPersonBypersonsexWithConverter(int id); void addPersonWithConverter(Person person); List<Person> queryPersonByAgeAndName(Person person); }
5、测试类
package com.mybatis03.test; import com.mybatis03.bean.Person; import com.mybatis03.mapper.PersonMapper; 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.jupiter.api.Test; import java.io.Reader; import java.util.List; /** * @author :jack.zhao * @Describe: 测试类 * @date :2021-10-16 22:55 */ public class test03 { // 查询集合信息(带转换器) @Test public void selectList() throws Exception{ Reader reader = Resources.getResourceAsReader("mybatis-03.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession session = sessionFactory.openSession(); // 动态代理 PersonMapper personMapper = session.getMapper(PersonMapper.class); List<com.mybatis03.bean.Person> personList = personMapper.queryListPersonBypersonsexWithConverter(1001); System.out.println("查询所有人员信息为:"+personList); session.close(); } // 增加人员信息(带转换器) @Test public void addPerson() throws Exception{ Reader reader = Resources.getResourceAsReader("mybatis-03.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession session = sessionFactory.openSession(); Person person = new Person(1008,"wangwu",29,true); // 动态代理 PersonMapper personMapper = session.getMapper(PersonMapper.class); personMapper.addPersonWithConverter(person); session.commit(); // 因为配置的是JDBC方式需要手动执行commit操作 System.out.println("添加人员信息成功!"); session.close(); } // 根据ID删除指定信息 @Test public void delPesonByID() throws Exception{ Reader reader = Resources.getResourceAsReader("mybatis-03.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession session = sessionFactory.openSession(); // 动态代理 PersonMapper personMapper = session.getMapper(PersonMapper.class); personMapper.delStudentById(1008); session.commit(); // 因为配置的是JDBC方式需要手动执行commit操作 System.out.println("删除人员信息成功!"); session.close(); } // 修改人员信息 @Test public void updateStudentById() throws Exception{ Person person = new Person(1008,"chenjiu",36,false); Reader reader = Resources.getResourceAsReader("mybatis-03.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession session = sessionFactory.openSession(); // 动态代理 PersonMapper personMapper = session.getMapper(PersonMapper.class); personMapper.updateStudentById(person); session.commit(); // 因为配置的是JDBC方式需要手动执行commit操作 System.out.println("修改人员信息成功!"); session.close(); } // 根据名称查询人员信息 @Test public void selectListByName() throws Exception{ Reader reader = Resources.getResourceAsReader("mybatis-03.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession session = sessionFactory.openSession(); // 动态代理 PersonMapper personMapper = session.getMapper(PersonMapper.class); Person person = personMapper.queryPersonByName("chenjiu"); System.out.println("查询所有人员信息为:"+person); session.close(); } // 查询所有人员信息,然后根据传入的字段进行排序(动态排序) @Test public void queryPersonOrderByColumn() throws Exception{ Reader reader = Resources.getResourceAsReader("mybatis-03.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession session = sessionFactory.openSession(); // 动态代理 PersonMapper personMapper = session.getMapper(PersonMapper.class); List<Person> personList = personMapper.queryPersonOrderByColumn("id"); System.out.println("查询所有人员信息为:"+personList); session.close(); } @Test public void queryPersonByAgeAndName() throws Exception{ Reader reader = Resources.getResourceAsReader("mybatis-03.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession session = sessionFactory.openSession(); Person person = new Person(); person.setAge(28); person.setName("%ch%"); // 动态代理 PersonMapper personMapper = session.getMapper(PersonMapper.class); List<Person> personList = personMapper.queryPersonByAgeAndName(person); System.out.println("查询所有人员信息为:"+personList); session.close(); } }
6、mapper文件内容
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "//mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.mybatis03.mapper.PersonMapper"> <delete id="delStudentById" parameterType="int"> DELETE from t_person_01 where id =#{id} </delete> <update id="updateStudentById" parameterType="com.mybatis03.bean.Person"> UPDATE t_person_01 SET NAME =#{name},age = #{age},sex=#{sex,javaType=boolean,jdbcType=INTEGER} where id =#{id} </update> <select id="queryPersonByName" parameterType="String" resultMap="personResult"> select id,name,age,sex from t_person_01 where name ='${value}' </select> <!-- 查询使用类型转换器 1、如果类中属性和表中字段能够合理匹配(string-varchar),则可以使用resultType;否则(boolean-int)使用resultMap 2、如果类中属性名和表中字段名能够合理匹配(personNo-personsNo),则可以使用resultType;否则(id-personNo)使用resultMap where id=#{id} --> <select id="queryListPersonBypersonsexWithConverter" parameterType="int" resultMap="personResult"> select id,name,age,sex from t_person_01 </select> <insert id="addPersonWithConverter" parameterType="com.mybatis03.bean.Person"> INSERT INTO t_person_01(id,name,age,sex) VALUES (#{id},#{name},#{age},#{sex,javaType=boolean,jdbcType=INTEGER}) </insert> <resultMap type="com.mybatis03.bean.Person" id="personResult"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <result property="sex" column="sex" javaType="boolean" jdbcType="INTEGER"/> </resultMap> <!-- 动态排序 --> <select id="queryPersonOrderByColumn" parameterType="String" resultMap="personResult"> select id,name,age,sex from t_person_01 ORDER BY ${value} ASC </select> <select id="queryPersonByAgeAndName" parameterType="com.mybatis03.bean.Person" resultMap="personResult"> <!-- select id,name,age,sex from t_person_01 where age = #{age} or name like #{name} --> <!-- 上下的sql语句等价 --> select id,name,age,sex from t_person_01 where age = #{age} or name like '%${name}%' </select> </mapper>
数据库测试数据:
创建数据库sql语句: