数据库操作
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

775 lines
17 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
  1. package dbquery
  2. import (
  3. "database/sql"
  4. "errors"
  5. "log"
  6. "strconv"
  7. "strings"
  8. "git.tetele.net/tgo/helper"
  9. )
  10. var stmt *sql.Stmt
  11. var err error
  12. type Query struct {
  13. dbname string
  14. table string
  15. alias string
  16. title string
  17. where []string
  18. where_or []string
  19. join [][]string //[["tablea as a","a.id=b.id","left"]]
  20. save_data []map[string]interface{} //批量操作的数据[["title":"a","num":1,],["title":"a","num":1,]]
  21. upd_field []string // 批量更新时需要更新的字段,为空时按除id外的字段进行更新
  22. data []string
  23. value []interface{}
  24. orderby string
  25. groupby string
  26. having string
  27. page int
  28. page_size int
  29. stmt *sql.Stmt
  30. conn *sql.DB
  31. debug bool
  32. dbtype string
  33. }
  34. func NewQuery(t ...string) *Query {
  35. var conn_type *sql.DB = DB
  36. var db_type string = "mysql"
  37. if len(t) > 0 {
  38. switch t[0] {
  39. case "mysql":
  40. conn_type = DB
  41. db_type = "mysql"
  42. case "mssql": //sql server
  43. conn_type = MSDB_CONN
  44. db_type = "mssql"
  45. }
  46. }
  47. return &Query{
  48. conn: conn_type,
  49. dbtype: db_type,
  50. }
  51. }
  52. func (this *Query) Conn(conn *sql.DB) *Query {
  53. this.conn = conn
  54. return this
  55. }
  56. func (this *Query) Db(dbname string) *Query {
  57. this.dbname = dbname
  58. return this
  59. }
  60. func (this *Query) Table(tablename string) *Query {
  61. this.table = tablename
  62. return this
  63. }
  64. func (this *Query) Alias(tablename string) *Query {
  65. this.alias = tablename
  66. return this
  67. }
  68. func (this *Query) Title(title string) *Query {
  69. this.title = title
  70. return this
  71. }
  72. func (this *Query) Page(page int) *Query {
  73. this.page = page
  74. return this
  75. }
  76. func (this *Query) PageSize(page_num int) *Query {
  77. this.page_size = page_num
  78. return this
  79. }
  80. func (this *Query) Having(having string) *Query {
  81. this.having = having
  82. return this
  83. }
  84. func (this *Query) Orderby(orderby string) *Query {
  85. this.orderby = orderby
  86. return this
  87. }
  88. func (this *Query) Groupby(groupby string) *Query {
  89. this.groupby = groupby
  90. return this
  91. }
  92. func (this *Query) Where(where string) *Query {
  93. this.where = append(this.where, where)
  94. return this
  95. }
  96. func (this *Query) Wheres(wheres []string) *Query {
  97. if len(wheres) > 0 {
  98. this.where = append(this.where, wheres...)
  99. }
  100. return this
  101. }
  102. func (this *Query) WhereOr(where string) *Query {
  103. this.where_or = append(this.where_or, where)
  104. return this
  105. }
  106. func (this *Query) SaveData(value map[string]interface{}) *Query {
  107. this.save_data = append(this.save_data, value)
  108. return this
  109. }
  110. func (this *Query) SaveDatas(value []map[string]interface{}) *Query {
  111. this.save_data = append(this.save_data, value...)
  112. return this
  113. }
  114. func (this *Query) UpdField(value string) *Query {
  115. this.upd_field = append(this.upd_field, value)
  116. return this
  117. }
  118. func (this *Query) UpdFields(value []string) *Query {
  119. this.upd_field = append(this.upd_field, value...)
  120. return this
  121. }
  122. func (this *Query) Value(value interface{}) *Query {
  123. this.value = append(this.value, value)
  124. return this
  125. }
  126. func (this *Query) Values(values []interface{}) *Query {
  127. this.value = append(this.value, values...)
  128. return this
  129. }
  130. func (this *Query) Join(join []string) *Query {
  131. this.join = append(this.join, join)
  132. return this
  133. }
  134. func (this *Query) Data(data string) *Query {
  135. this.data = append(this.data, data)
  136. return this
  137. }
  138. func (this *Query) Datas(datas []string) *Query {
  139. this.data = append(this.data, datas...)
  140. return this
  141. }
  142. func (this *Query) Debug(debug bool) *Query {
  143. this.debug = debug
  144. return this
  145. }
  146. /*
  147. * 清理上次查询
  148. */
  149. func (this *Query) Clean() *Query {
  150. this.title = ""
  151. this.where = this.where[0:0]
  152. this.where_or = this.where_or[0:0]
  153. this.join = this.join[0:0]
  154. this.data = this.data[0:0]
  155. this.value = this.value[0:0]
  156. this.orderby = ""
  157. this.groupby = ""
  158. this.page = 0
  159. this.page_size = 0
  160. this.save_data = this.save_data[0:0]
  161. this.upd_field = this.upd_field[0:0]
  162. this.having = ""
  163. return this
  164. }
  165. //构造子查询
  166. func (this *Query) BuildSelectSql() (map[string]interface{}, error) {
  167. if this.dbname == "" && this.table == "" {
  168. return nil, errors.New("参数错误,没有数据表")
  169. }
  170. var table = ""
  171. if strings.Contains(this.table, "select ") {
  172. table = this.table
  173. } else {
  174. table = getTableName(this.dbname, this.table, this.dbtype)
  175. }
  176. // var err error
  177. var sql, title string
  178. if this.title != "" {
  179. title = this.title
  180. } else {
  181. title = "*"
  182. }
  183. sql = helper.StringJoin("/*slave*/ select ", title)
  184. if this.alias != "" {
  185. table = helper.StringJoin(table, " as ", this.alias)
  186. }
  187. sql = helper.StringJoin(sql, " from ", table)
  188. if len(this.join) > 0 {
  189. for _, joinitem := range this.join {
  190. if len(joinitem) < 2 {
  191. continue
  192. }
  193. if len(joinitem) == 3 {
  194. sql = helper.StringJoin(sql, " ", joinitem[2], " join ", getTableName(this.dbname, joinitem[0], this.dbtype), " on ", joinitem[1])
  195. } else { //默认左连接
  196. sql = helper.StringJoin(sql, " left join ", getTableName(this.dbname, joinitem[0], this.dbtype), " on ", joinitem[1])
  197. }
  198. }
  199. }
  200. if len(this.where) > 0 || len(this.where_or) > 0 {
  201. sql = helper.StringJoin(sql, " where ")
  202. }
  203. if len(this.where) > 0 {
  204. sql = helper.StringJoin(sql, " (", strings.Join(this.where, " and "), " ) ")
  205. }
  206. if len(this.where_or) > 0 {
  207. if len(this.where) > 0 {
  208. sql = helper.StringJoin(sql, " or ", strings.Join(this.where_or, " or "))
  209. } else {
  210. sql = helper.StringJoin(sql, strings.Join(this.where_or, " or "))
  211. }
  212. }
  213. if this.groupby != "" {
  214. sql = helper.StringJoin(sql, " group by ", this.groupby)
  215. }
  216. if this.having != "" {
  217. sql = helper.StringJoin(sql, " having ", this.having)
  218. }
  219. if this.orderby != "" {
  220. sql = helper.StringJoin(sql, " order by ", this.orderby)
  221. }
  222. if this.page > 0 || this.page_size > 0 {
  223. if this.page < 1 {
  224. this.page = 1
  225. }
  226. if this.page_size < 1 {
  227. this.page_size = 10
  228. }
  229. from := strconv.Itoa((this.page - 1) * this.page_size)
  230. offset := strconv.Itoa(this.page_size)
  231. if from != "" && offset != "" {
  232. sql = helper.StringJoin(sql, " limit ", from, " , ", offset)
  233. }
  234. }
  235. if this.debug {
  236. log.Println("query sql:", sql, this.value)
  237. }
  238. condition_len := 0 //所有条件数
  239. for _, ch2 := range sql {
  240. if string(ch2) == "?" {
  241. condition_len++
  242. }
  243. }
  244. if condition_len != len(this.value) {
  245. return nil, errors.New("参数错误,条件值错误")
  246. }
  247. return map[string]interface{}{
  248. "sql": sql,
  249. "value": this.value,
  250. }, nil
  251. }
  252. // 拼查询sql
  253. func (this *Query) QueryStmt() error {
  254. res := map[string]interface{}{}
  255. res, err = this.BuildSelectSql()
  256. if err != nil {
  257. return err
  258. }
  259. sql := helper.ToStr(res["sql"])
  260. if this.conn == nil {
  261. this.conn = DB
  262. }
  263. stmt, err = this.conn.Prepare(sql)
  264. if err != nil {
  265. return err
  266. }
  267. this.stmt = stmt
  268. return nil
  269. }
  270. // 拼更新sql
  271. func (this *Query) UpdateStmt() error {
  272. if this.dbname == "" && this.table == "" {
  273. return errors.New("参数错误,没有数据表")
  274. }
  275. if len(this.where) < 1 {
  276. return errors.New("参数错误,缺少条件")
  277. }
  278. dbName := getTableName(this.dbname, this.table, this.dbtype)
  279. var sql string
  280. sql = helper.StringJoin("update ", dbName, " set ", strings.Join(this.data, " , "))
  281. sql = helper.StringJoin(sql, " where ", strings.Join(this.where, " and "))
  282. if this.debug {
  283. log.Println("update sql:", sql, this.value)
  284. }
  285. condition_len := 0 //所有条件数
  286. for _, ch2 := range sql {
  287. if string(ch2) == "?" {
  288. condition_len++
  289. }
  290. }
  291. if condition_len != len(this.value) {
  292. return errors.New("参数错误,条件值错误")
  293. }
  294. if this.conn == nil {
  295. this.conn = DB
  296. }
  297. stmt, err = this.conn.Prepare(sql)
  298. if err != nil {
  299. return err
  300. }
  301. this.stmt = stmt
  302. return nil
  303. }
  304. // 拼批量存在更新不存在插入sql
  305. func (this *Query) UpdateAllStmt() error {
  306. if this.dbname == "" && this.table == "" {
  307. return errors.New("参数错误,没有数据表")
  308. }
  309. dbName := getTableName(this.dbname, this.table)
  310. var sql string
  311. var dataSql []string //一组用到的占位字符
  312. var valSql []string //占位字符组
  313. var updSql []string //更新字段的sql
  314. var updFieldLen = len(this.upd_field) //需要更新的字段数量,为0时更新除id外添加值
  315. dataLen := len(this.save_data)
  316. if dataLen > 0 {
  317. //批量操作
  318. this.data = this.data[0:0]
  319. this.value = this.value[0:0]
  320. var dataSqlText string //占位字符组
  321. for i := 0; i < dataLen; i++ {
  322. if i == 0 {
  323. //第一组时分配变量空间
  324. fieldLen := len(this.save_data[i])
  325. this.data = make([]string, 0, fieldLen)
  326. dataSql = make([]string, 0, fieldLen)
  327. this.value = make([]interface{}, 0, fieldLen*dataLen)
  328. valSql = make([]string, 0, dataLen)
  329. switch updFieldLen {
  330. case 0:
  331. //预览创建数据的长度
  332. updSql = make([]string, 0, fieldLen)
  333. default:
  334. //按照需要更新字段数长度
  335. updSql = make([]string, 0, updFieldLen)
  336. for _, k := range this.upd_field {
  337. updSql = append(updSql, k+"=values("+k+")") //存储需要更新的字段
  338. }
  339. }
  340. for k := range this.save_data[i] {
  341. this.data = append(this.data, k) //存储添加的字段
  342. dataSql = append(dataSql, "?") //存储需要的占位符
  343. if updFieldLen == 0 && k != "id" {
  344. updSql = append(updSql, k+"=values("+k+")") //存储需要更新的字段
  345. }
  346. }
  347. dataSqlText = strings.Join(dataSql, ",") //组成每组占位字符格式
  348. }
  349. for j := 0; j < len(this.data); j++ {
  350. this.value = append(this.value, this.save_data[i][this.data[j]]) //存储值
  351. }
  352. valSql = append(valSql, "("+dataSqlText+")") //组成占位字符组
  353. }
  354. } else {
  355. //添加一条(原理同上)
  356. fieldLen := len(this.data)
  357. dataSql = make([]string, 0, fieldLen)
  358. valSql = make([]string, 0, 1)
  359. switch updFieldLen {
  360. case 0:
  361. updSql = make([]string, 0, fieldLen)
  362. default:
  363. updSql = make([]string, 0, updFieldLen)
  364. for _, k := range this.upd_field {
  365. updSql = append(updSql, k+"=values("+k+")")
  366. }
  367. }
  368. for i := 0; i < fieldLen; i++ {
  369. dataSql = append(dataSql, "?")
  370. if updFieldLen == 0 && this.data[i] != "id" {
  371. updSql = append(updSql, this.data[i]+"=values("+this.data[i]+")")
  372. }
  373. }
  374. if updFieldLen > 0 {
  375. for _, k := range this.upd_field {
  376. updSql = append(updSql, k+"=values("+k+")")
  377. }
  378. }
  379. valSql = append(valSql, "("+strings.Join(dataSql, " , ")+")")
  380. }
  381. if len(this.data) == 0 {
  382. return errors.New("参数错误,没有字段值")
  383. }
  384. if len(this.value) == 0 {
  385. return errors.New("参数错误,条件值错误")
  386. }
  387. setText := " values "
  388. if len(valSql) > 1 {
  389. setText = " value "
  390. }
  391. sql = helper.StringJoin("insert into ", dbName, " (", strings.Join(this.data, " , "), ")", setText, strings.Join(valSql, ","), " ON DUPLICATE KEY UPDATE ", strings.Join(updSql, " , "))
  392. if this.debug {
  393. log.Println("insert on duplicate key update sql:", sql, this.value)
  394. }
  395. conditionLen := 0 //所有条件数
  396. for _, ch2 := range sql {
  397. if string(ch2) == "?" {
  398. conditionLen++
  399. }
  400. }
  401. if conditionLen != len(this.value) {
  402. return errors.New("参数错误,条件值数量不匹配")
  403. }
  404. if this.conn == nil {
  405. this.conn = DB
  406. }
  407. stmt, err = this.conn.Prepare(sql)
  408. if err != nil {
  409. return err
  410. }
  411. this.stmt = stmt
  412. return nil
  413. }
  414. // 拼批量插入sql
  415. func (this *Query) CreateAllStmt() error {
  416. if this.dbname == "" && this.table == "" {
  417. return errors.New("参数错误,没有数据表")
  418. }
  419. dbName := getTableName(this.dbname, this.table)
  420. var sql string
  421. var dataSql []string //一组用到的占位字符
  422. var valSql []string //占位字符组
  423. dataLen := len(this.save_data)
  424. if dataLen > 0 {
  425. //清空字段和值
  426. this.data = this.data[0:0]
  427. this.value = this.value[0:0]
  428. var dataSqlText string //占位字符组
  429. for i := 0; i < dataLen; i++ {
  430. if i == 0 {
  431. //第一组时分配变量空间
  432. fieldLen := len(this.save_data[i])
  433. this.data = make([]string, 0, fieldLen)
  434. dataSql = make([]string, 0, fieldLen)
  435. this.value = make([]interface{}, 0, fieldLen*dataLen)
  436. valSql = make([]string, 0, dataLen)
  437. for k := range this.save_data[i] {
  438. this.data = append(this.data, k) //存储字段
  439. dataSql = append(dataSql, "?") //存储需要的占位符
  440. }
  441. dataSqlText = strings.Join(dataSql, ",") //组成每组占位字符格式
  442. }
  443. for j := 0; j < len(this.data); j++ {
  444. this.value = append(this.value, this.save_data[i][this.data[j]]) //存储值
  445. }
  446. valSql = append(valSql, "("+dataSqlText+")") //组成占位字符组
  447. }
  448. } else {
  449. //添加一条(原理同上)
  450. fieldLen := len(this.data)
  451. dataSql = make([]string, 0, fieldLen)
  452. for i := 0; i < fieldLen; i++ {
  453. dataSql = append(dataSql, "?")
  454. }
  455. valSql = make([]string, 0, 1)
  456. valSql = append(valSql, "("+strings.Join(dataSql, " , ")+")")
  457. }
  458. if len(this.data) == 0 {
  459. return errors.New("参数错误,字段名错误")
  460. }
  461. if len(this.value) == 0 {
  462. return errors.New("参数错误,条件值错误")
  463. }
  464. //通过sql关键字优化批量操作和单个操作效率
  465. setText := " values "
  466. if len(valSql) > 1 {
  467. setText = " value "
  468. }
  469. sql = helper.StringJoin("insert into ", dbName, " (", strings.Join(this.data, " , "), ")", setText, strings.Join(valSql, ","))
  470. if this.debug {
  471. log.Println("insert sql:", sql, this.value)
  472. }
  473. conditionLen := 0 //所有条件数
  474. for _, ch2 := range sql {
  475. if string(ch2) == "?" {
  476. conditionLen++
  477. }
  478. }
  479. if conditionLen != len(this.value) {
  480. return errors.New("参数错误,条件值数量不匹配")
  481. }
  482. if this.conn == nil {
  483. this.conn = DB
  484. }
  485. stmt, err = this.conn.Prepare(sql)
  486. if err != nil {
  487. return err
  488. }
  489. this.stmt = stmt
  490. return nil
  491. }
  492. // 拼插入sql
  493. func (this *Query) CreateStmt() error {
  494. if this.dbname == "" && this.table == "" {
  495. return errors.New("参数错误,没有数据表")
  496. }
  497. dbName := getTableName(this.dbname, this.table, this.dbtype)
  498. var sql string
  499. sql = helper.StringJoin("insert into ", dbName, " set ", strings.Join(this.data, " , "))
  500. if this.debug {
  501. log.Println("insert sql:", sql, this.value)
  502. }
  503. condition_len := 0 //所有条件数
  504. for _, ch2 := range sql {
  505. if string(ch2) == "?" {
  506. condition_len++
  507. }
  508. }
  509. if condition_len != len(this.value) {
  510. return errors.New("参数错误,条件值错误")
  511. }
  512. if this.conn == nil {
  513. this.conn = DB
  514. }
  515. stmt, err = this.conn.Prepare(sql)
  516. if err != nil {
  517. return err
  518. }
  519. this.stmt = stmt
  520. return nil
  521. }
  522. // 拼删除sql
  523. func (this *Query) DeleteStmt() error {
  524. if this.dbname == "" && this.table == "" {
  525. return errors.New("参数错误,没有数据表")
  526. }
  527. if len(this.where) < 1 {
  528. return errors.New("参数错误,缺少条件")
  529. }
  530. dbName := getTableName(this.dbname, this.table, this.dbtype)
  531. var sql string
  532. sql = helper.StringJoin("delete from ", dbName, " where ", strings.Join(this.where, " and "))
  533. if this.page_size > 0 {
  534. sql = helper.StringJoin(sql, " limit ", strconv.Itoa(this.page_size))
  535. }
  536. if this.debug {
  537. log.Println("delete sql:", sql, this.value)
  538. }
  539. condition_len := 0 //所有条件数
  540. for _, ch2 := range sql {
  541. if string(ch2) == "?" {
  542. condition_len++
  543. }
  544. }
  545. if condition_len != len(this.value) {
  546. return errors.New("参数错误,条件值错误")
  547. }
  548. if this.conn == nil {
  549. this.conn = DB
  550. }
  551. stmt, err = this.conn.Prepare(sql)
  552. if err != nil {
  553. return err
  554. }
  555. this.stmt = stmt
  556. return nil
  557. }
  558. /**
  559. * 执行查询列表
  560. * return list error
  561. */
  562. func (this *Query) Select() ([]map[string]string, error) {
  563. _, rows, err := FetchRows(this.dbname, this.table, this.alias, this.title, this.join,
  564. this.where, this.where_or, this.value, this.orderby, this.groupby, this.having, this.page, this.page_size, this.debug)
  565. return rows, err
  566. }
  567. /**
  568. * 执行查询多条数据
  569. * return row error
  570. * 2022/01/05
  571. */
  572. func (this *Query) List() ([]map[string]string, error) {
  573. err := this.QueryStmt()
  574. if err != nil {
  575. return []map[string]string{}, err
  576. }
  577. if this.stmt == nil {
  578. return []map[string]string{}, errors.New("缺少必要参数")
  579. }
  580. return StmtForQueryList(this.stmt, this.value)
  581. }
  582. /**
  583. * 执行查询一条数据
  584. * return row error
  585. */
  586. func (this *Query) Find() (map[string]string, error) {
  587. _, row, err := GetRow(this.dbname, this.table, this.alias, this.title, this.join,
  588. this.where, this.where_or, this.value, this.orderby, this.groupby, this.having, this.debug)
  589. return row, err
  590. }
  591. /**
  592. * 执行查询一条数据
  593. * return row error
  594. * 2022/01/05
  595. */
  596. func (this *Query) Get() (map[string]string, error) {
  597. this.page = 1
  598. this.page_size = 1
  599. err := this.QueryStmt()
  600. if err != nil {
  601. return map[string]string{}, err
  602. }
  603. if this.stmt == nil {
  604. return nil, errors.New("缺少必要参数")
  605. }
  606. return StmtForQueryRow(this.stmt, this.value)
  607. }
  608. /**
  609. * 执行更新
  610. * return is_updated error
  611. */
  612. func (this *Query) Update() (int64, error) {
  613. err := this.UpdateStmt()
  614. if err != nil {
  615. return 0, err
  616. }
  617. return StmtForUpdateExec(this.stmt, this.value)
  618. }
  619. //批量更新
  620. func (this *Query) UpdateAll() (int64, error) {
  621. err := this.UpdateAllStmt()
  622. if err != nil {
  623. return 0, err
  624. }
  625. return StmtForUpdateExec(this.stmt, this.value)
  626. }
  627. /**
  628. * 执行删除
  629. * return is_delete error
  630. */
  631. func (this *Query) Delete() (int64, error) {
  632. err := this.DeleteStmt()
  633. if err != nil {
  634. return 0, err
  635. }
  636. return StmtForUpdateExec(this.stmt, this.value)
  637. }
  638. /**
  639. * 执行写入
  640. * return is_insert error
  641. */
  642. func (this *Query) Create() (int64, error) {
  643. err := this.CreateStmt()
  644. if err != nil {
  645. return 0, err
  646. }
  647. return StmtForInsertExec(this.stmt, this.value)
  648. }
  649. func (this *Query) CreateAll() (int64, error) {
  650. err := this.CreateAllStmt()
  651. if err != nil {
  652. return 0, err
  653. }
  654. return StmtForInsertExec(this.stmt, this.value)
  655. }