limit不能使用变量
问题123set @r = (select floor(rand() * (@c - 1)));select * from proxy limit @r,1;MySQL的limit参数不能使用变量
解决办法将SQL语句改为prepare字符串,其中变量为参数,传入参数后执行prepare
12345set @c = (select count(*)from proxy);set @r = (select floor(rand() * (@c - 1)));prepare ps from 'select * from proxy limit ?,1';execute ps using @r;deallocate prepare ps;
qlalchemy.exc.InvalidRequestError: Object '<xxxxx at 0xxxxxx>' is already attached to session 'x' (this is 'x')
异常1sqlalchemy.exc.InvalidRequestError: Object '<xxxxx at 0xxxxxx>' is already attached to session 'x' (this is 'x')
重现通过session1查询一条结果A后,没有关闭session1,将A放入session2执行
原因A最多只能有一个附属session
结果A附属于session1,不能放入session2执行
解决办法关闭session1后,使A脱离session1,再放入session2执行
set-datatype-as-int-enum
问题SQLAlchemy的类型可以设为Enum,默认使用key
e.g.1234class MyEnum(Enum): one = 1 two = 2 three = 3
设置Column("column_name", Enum(MyEnum))插入的是"one"、"two"等key字符串
官方提供了参数values_callable,但value必须是字符串
内部使用value的len属性构造object,而数值没有该属性
假设value为字符串’1’,’2’,’3’
e.g.1Column("column_name", Enum(MyEnum, values_callable=lambda x: [e.value for e in x]))
解决办法继承TypeDecorator创建自定义Enum列类型
1234567891011121314from sqlalchemy import Integer, TypeDecoratorclass IntEnum(TypeDecorato ...
collection
功能表示该属性为“多”的一方
如教室与学生关系中的学生
使用定义时,该属性应为集合
1List<Student> students;
已知t_class(id,name),t_student(id,name,cid),外键为t_student.cid=t_class.id
设置实体clazz: Class(Integer id, String name, List<Student> students),student: Student(Integer id, String name)
用法与association基本一致
其他属性及用法参考association
collection的javaType应该为ArrayList等列表类型(可省略),ofType是列表内的类型
属性
功能
举例
说明
ofType
列表内的类型
Student
123456789101112<select parameterType="int" id="selectByClassId" resultMap=" ...
association
功能表示该属性为“一”的一方
如教室与学生关系中的教室
使用已知t_class(id,name),t_student(id,name,cid),外键为t_student.cid=t_class.id
设置实体clazz: Class(Integer id, String name),student: Student(Integer id, String name, Clazz clazz)
12345678<resultMap id="resultClass" type="Clazz"> <id column="id" jdbcType="INTEGER" property="id"/> <result column="name" jdbcType="VARCHAR" property="name"/></resultMap><resultMap id=" ...
级联
说明级联指实体嵌套,如Project实体有一个属性为User实体类型,组成嵌套关系
类型MyBatis支持一对一、一对多、多对一映射,不支持多对多映射
如果需要多对多映射,需设置中间表,组成“多对一、一对多”映射
方式已知User(id,name,project),Project(id,name,uid),外键为Project.uid=User.id
设置实体User(Integer id, String name),Project(Integer id, String name, User user)
连接多表在SQL语句内直接连接多表,查询project,并填充project.user属性
project与user是多对一关系,使用association填充内嵌实体的属性
123456789101112131415161718<select parameterType="int" id="selectWithUser" resultMap="resultWithUser"> select p ...
mapper映射-枚举类型转换器
MyBatis自带两种(EnumOrdinalTypeHandler和EnumTypeHandler)枚举转换器,但只支持最基本的枚举类型
与ordinal属性相互转换EnumOrdinalTypeHandler可将枚举的ordinal属性和int相互转换
1enum GenderEnum{MALE,FEMALE}
会将GenderEnum.MALE转为0,GenderEnum.FEMALE转为1(可相互转换)
与名称相互转换EnumTypeHandler可将枚举的名称和string相互转换
1enum GenderEnum{MALE,FEMALE}
会将GenderEnum.MALE转为"MALE",GenderEnum.FEMALE转为"FEMALE"(可互相转换)
自定义转换对于复杂的Enum则需要自定义转换器
复杂枚举123456789101112131415161718192021222324252627//复杂枚举enum GenderEnum{ MALE(1,"m ...
Mapper映射-自定义类型转换器
某些类型没有自动转换,则需要自定义TypeHandler
以自定义User类为例,基本思路相同
已知属性user类型为User(id, name),对应的jdbc类型为integer,存储User的id
该转换器功能为:将user(3)转为3存储数据库,或将数据库3转为user(3)
1234567891011121314151617181920212223//这里可以添加注解@MappedJdbcTypes或@MappedTypespublic class ExampleTypeHandler extends BaseTypeHandler<User> { @Override public void setNonNullParameter(PreparedStatement ps, int i, User parameter, JdbcType jdbcType) throws SQLException { ps.setInt(i, parameter.id); } @Override public ...
Mapper配置文件-类型转换器(TypeHandler)
功能将数据库类型(jdbcType)和Java类型(javaType)互相转换
自动转换基础类型MyBatis会自动识别并完成转换
常见的boolean、byte、int、Date、Timestamp及部分数组等都支持自动转换
详见 https://mybatis.org/mybatis-3/zh/configuration.html#typeHandlers
使用转换器的底层是BaseTypeHandler<T>(继承自TypeHanlder<T>接口),默认T为参数类型
指定转换器可通过指定Java类型或jdbc类型设置
设置java类型设置javaType为指定对应的实体属性类型,不设置时自动判断
e.g.1<result column="request_url" property="requestUrl" javaType="java.lang.String"/>
数据库列request_url(类型为jdbcType.VARCHAR),对应的实体属性为requestUrl(类型为 ...
Mapper配置文件-insert|update|delete
insert常用属性
常用属性
默认值
说明
其他
useGeneratedKeys
false
是否使用JDBC的getGeneratedKeys获取生成的主键
适用于自增字段
keyProperty
getGeneratedKeys或由selectKey属性确定
parameterType中的唯一识别属性,一般为主属性,将会回填至bean
多个属性时,使用逗号分隔
keyColumn
唯一识别字段名,一般为主键
多个字段时,使用逗号分隔,部分数据库当主键不是第一列时必须设置
设置 useGeneratedKeys=true keyProperty="parameterType的主键属性" keyColumn="主键列名",即可在插入记录后,将主键写入bean
示例123<insert id="insertUser" parameterType="user" useGeneratedKeys=true keyProperty="id" keyColumn= ...